svn rev #22138: branches/fast/src/ include/ kdc/ lib/krb5/asn.1/ lib/krb5/krb/

hartmans@MIT.EDU hartmans at MIT.EDU
Thu Mar 26 01:37:19 EDT 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=22138
Commit By: hartmans
Log Message:
Remove FAST finish checksum

Per discussion on ietf-krb-wg, the checksum is unnecessary if a nonce
is included in the response .  For this to be secure, the cookie needs
to be inner padata when FAST is used.

* kdc/fast.c: when constructing fast responses  include the nonce
* lib/krb5/krb/fast.c: generate a random nonce for each time a fast request is constructed
* add nonce field to fast_response
* remove checksum field from fast_finished
* Look for cookie as inner padata when FAST is used


Changed Files:
U   branches/fast/src/include/k5-int.h
U   branches/fast/src/kdc/do_as_req.c
U   branches/fast/src/kdc/fast_util.c
U   branches/fast/src/kdc/kdc_util.h
U   branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c
U   branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c
U   branches/fast/src/lib/krb5/asn.1/krb5_decode.c
U   branches/fast/src/lib/krb5/krb/fast.c
U   branches/fast/src/lib/krb5/krb/fast.h
U   branches/fast/src/lib/krb5/krb/kfree.c
Modified: branches/fast/src/include/k5-int.h
===================================================================
--- branches/fast/src/include/k5-int.h	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/include/k5-int.h	2009-03-26 05:37:18 UTC (rev 22138)
@@ -989,19 +989,19 @@
 #define UNSUPPORTED_CRITICAL_FAST_OPTIONS 0x00ff
 #define KRB5_FAST_OPTION_HIDE_CLIENT_NAMES 0x01
 
-    typedef struct _krb5_fast_finished {
-	krb5_timestamp timestamp;
-	krb5_int32 usec;
-	krb5_principal client;
-	krb5_checksum checksum;
-	krb5_checksum ticket_checksum;
-    } krb5_fast_finished;
+typedef struct _krb5_fast_finished {
+    krb5_timestamp timestamp;
+    krb5_int32 usec;
+    krb5_principal client;
+    krb5_checksum ticket_checksum;
+} krb5_fast_finished;
 
-	typedef struct _krb5_fast_response {
-	    krb5_magic magic;
+typedef struct _krb5_fast_response {
+    krb5_magic magic;
     krb5_pa_data **padata;
     krb5_keyblock *rep_key;
     krb5_fast_finished *finished;
+    krb5_int32 nonce;
 } krb5_fast_response;
 
 

Modified: branches/fast/src/kdc/do_as_req.c
===================================================================
--- branches/fast/src/kdc/do_as_req.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/kdc/do_as_req.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -766,7 +766,7 @@
 	}
     }
     retval = kdc_fast_handle_error(kdc_context, rstate,
-				   pa, &errpkt);
+				   request, pa, &errpkt);
     if (retval == 0)
     retval = krb5_mk_error(kdc_context, &errpkt, scratch);
     free(errpkt.text.data);

Modified: branches/fast/src/kdc/fast_util.c
===================================================================
--- branches/fast/src/kdc/fast_util.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/kdc/fast_util.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -113,10 +113,7 @@
     krb5_clear_error_message(kdc_context);
     fast_padata = find_pa_data(request->padata,
 			       KRB5_PADATA_FX_FAST);
-    cookie_padata = find_pa_data(request->padata, KRB5_PADATA_FX_COOKIE);
-        if (fast_padata == NULL)
-	return 0; /*no fast*/
-    
+    if (fast_padata !=  NULL){
     scratch.length = fast_padata->length;
     scratch.data = (char *) fast_padata->contents;
     retval = decode_krb5_pa_fx_fast_request(&scratch, &fast_armored_req);
@@ -171,7 +168,20 @@
 	if ((fast_req->fast_options & UNSUPPORTED_CRITICAL_FAST_OPTIONS) !=0)
 	    retval = KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION;
     }
-    if (retval == 0 && cookie_padata != NULL) {
+	    if (retval == 0)
+	        cookie_padata = find_pa_data(fast_req->req_body->padata, KRB5_PADATA_FX_COOKIE);
+	    if (retval == 0) {
+	      state->fast_options = fast_req->fast_options;
+	      if (request->kdc_state == state)
+		request->kdc_state = NULL;
+	      krb5_free_kdc_req( kdc_context, request);
+	      *requestptr = fast_req->req_body;
+	      fast_req->req_body = NULL;
+	
+	    }
+    }
+    else cookie_padata = find_pa_data(request->padata, KRB5_PADATA_FX_COOKIE);
+        if (retval == 0 && cookie_padata != NULL) {
 	krb5_pa_data *new_padata = malloc(sizeof (krb5_pa_data));
 	if (new_padata != NULL) {
 	    retval = ENOMEM;
@@ -188,16 +198,7 @@
 	    }
 	}
     }
-    if (retval == 0) {
-	state->fast_options = fast_req->fast_options;
-	if (request->kdc_state == state)
-	    request->kdc_state = NULL;
-	krb5_free_kdc_req( kdc_context, request);
-	*requestptr = fast_req->req_body;
-	fast_req->req_body = NULL;
-	
-    }
-    if (fast_req)
+	if (fast_req)
 	krb5_free_fast_req( kdc_context, fast_req);
     if (fast_armored_req)
 	krb5_free_fast_armored_req(kdc_context, fast_armored_req);
@@ -232,7 +233,9 @@
 }
 
 krb5_error_code kdc_fast_response_handle_padata
-(struct kdc_request_state *state, krb5_kdc_rep *rep, const krb5_data *pkt)
+(struct kdc_request_state *state,
+ krb5_kdc_req *request,
+ krb5_kdc_rep *rep)
 {
     krb5_error_code retval = 0;
     krb5_fast_finished finish;
@@ -246,7 +249,8 @@
 	return 0;
     memset(&finish, 0, sizeof(finish));
     fast_response.padata = rep->padata;
-    fast_response.rep_key = state->reply_key; 
+    fast_response.rep_key = state->reply_key;
+    fast_response.nonce = request->nonce;
     fast_response.finished = &finish;
     finish.client = rep->client;
     pa_array = calloc(3, sizeof(*pa_array));
@@ -263,12 +267,7 @@
 	retval = krb5_c_make_checksum(kdc_context, cksumtype,
 				      state->armor_key, KRB5_KEYUSAGE_FAST_FINISHED,
 				      encoded_ticket, &finish.ticket_checksum);
-/* xxx checksum should be something else; sticking ticket_checksum there is a placeholder*/
     if (retval == 0)
-	retval = krb5_c_make_checksum(kdc_context, cksumtype,
-				      state->armor_key, KRB5_KEYUSAGE_FAST_FINISHED,
-				      encoded_ticket, &finish.checksum);
-    if (retval == 0)
 	retval = encode_krb5_fast_response(&fast_response,  &encoded_fast_response);
     if (retval == 0) {
 	pa[0].pa_type = KRB5_PADATA_FX_FAST;
@@ -286,10 +285,8 @@
 	krb5_free_data(kdc_context, encoded_fast_response);
     if (encoded_ticket)
 	krb5_free_data(kdc_context, encoded_ticket);
-    if (finish.checksum.contents)
-	krb5_free_checksum_contents(kdc_context, &finish.checksum);
     if (finish.ticket_checksum.contents)
-	krb5_free_checksum_contents(kdc_context, &finish.checksum);
+	krb5_free_checksum_contents(kdc_context, &finish.ticket_checksum);
     return retval;
 }
 
@@ -301,6 +298,7 @@
  */
 krb5_error_code kdc_fast_handle_error
 (krb5_context context, struct kdc_request_state *state,
+ krb5_kdc_req *request,
  krb5_pa_data  **in_padata, krb5_error *err)
 {
     krb5_error_code retval = 0;
@@ -335,6 +333,7 @@
 	pa[0].contents = (unsigned char *) encoded_fx_error->data;
 	inner_pa[size++] = &pa[0];
 	resp.padata = inner_pa;
+	resp.nonce = request->nonce;
 	resp.rep_key = NULL;
 	resp.finished = NULL;
     }

Modified: branches/fast/src/kdc/kdc_util.h
===================================================================
--- branches/fast/src/kdc/kdc_util.h	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/kdc/kdc_util.h	2009-03-26 05:37:18 UTC (rev 22138)
@@ -323,9 +323,12 @@
  struct kdc_request_state *state);
 
 krb5_error_code kdc_fast_response_handle_padata
-(struct kdc_request_state *state, krb5_kdc_rep *rep, const krb5_data *pkt);
+(struct kdc_request_state *state,
+ krb5_kdc_req *request,
+ krb5_kdc_rep *rep);
 krb5_error_code kdc_fast_handle_error
 (krb5_context context, struct kdc_request_state *state,
+ krb5_kdc_req *request,
  krb5_pa_data  **in_padata, krb5_error *err);
 
  

Modified: branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c
===================================================================
--- branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -1653,7 +1653,6 @@
 {
     setup();
     val->client = NULL;
-    val->checksum.contents = NULL;
     val->ticket_checksum.contents = NULL;
     {begin_structure();
     get_field(val->timestamp, 0, asn1_decode_kerberos_time);
@@ -1661,14 +1660,12 @@
     alloc_field(val->client);
     get_field(val->client, 2, asn1_decode_realm);
     get_field(val->client, 3, asn1_decode_principal_name);
-    get_field(val->checksum, 4, asn1_decode_checksum);
-    get_field(val->ticket_checksum, 5, asn1_decode_checksum);
+    get_field(val->ticket_checksum, 4, asn1_decode_checksum);
     end_structure();
     }
     return 0;
  error_out:
     krb5_free_principal(NULL, val->client);
-    krb5_free_checksum_contents(NULL, &val->checksum);
     krb5_free_checksum_contents( NULL, &val->ticket_checksum);
     return retval;
 }

Modified: branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c
===================================================================
--- branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -1224,8 +1224,7 @@
     FIELDOF_NORM( krb5_fast_finished, int32, usec, 1),
     FIELDOF_NORM( krb5_fast_finished, realm_of_principal, client, 2),
     FIELDOF_NORM(krb5_fast_finished, principal, client, 3),
-    FIELDOF_NORM( krb5_fast_finished, checksum, checksum, 4),
-    FIELDOF_NORM( krb5_fast_finished, checksum, ticket_checksum, 5),
+    FIELDOF_NORM( krb5_fast_finished, checksum, ticket_checksum, 4),
 };
 
 DEFSEQTYPE( fast_finished, krb5_fast_finished, fast_finished_fields, 0);
@@ -1236,6 +1235,7 @@
     FIELDOF_NORM(krb5_fast_response, ptr_seqof_pa_data, padata, 0),
     FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, rep_key, 1, 1),
     FIELDOF_OPT( krb5_fast_response, ptr_fast_finished, finished, 2, 2),
+    FIELDOF_NORM(krb5_fast_response, int32, nonce, 3),
 };
 
 static unsigned int fast_response_optional (const void *p)

Modified: branches/fast/src/lib/krb5/asn.1/krb5_decode.c
===================================================================
--- branches/fast/src/lib/krb5/asn.1/krb5_decode.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/asn.1/krb5_decode.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -1142,7 +1142,8 @@
     get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data);
     opt_field(rep->rep_key, 1, asn1_decode_encryption_key_ptr);
     opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr);
-    end_structure(); }
+    get_field(rep->nonce, 3, asn1_decode_int32);
+        end_structure(); }
     rep->magic = KV5M_FAST_RESPONSE;
     cleanup(free);
 }

Modified: branches/fast/src/lib/krb5/krb/fast.c
===================================================================
--- branches/fast/src/lib/krb5/krb/fast.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/krb/fast.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -159,7 +159,7 @@
 
 krb5_error_code 
 krb5int_fast_prep_req (krb5_context context, struct krb5int_fast_request_state *state,
-		       const krb5_kdc_req *request,
+		        krb5_kdc_req *request,
 		       const krb5_data *to_be_checksummed, kdc_req_encoder_proc encoder,
 		       krb5_data **encoded_request)
 {
@@ -172,6 +172,8 @@
     krb5_data *encoded_armored_req = NULL;
     krb5_data *local_encoded_result = NULL;
     krb5_cksumtype cksumtype;
+    krb5_data random_data;
+    char random_buf[4];
 
     assert(state != NULL);
     assert(state->fast_outer_request.padata == NULL);
@@ -179,6 +181,14 @@
     if (state->armor_key == NULL) {
 	return encoder(request, encoded_request);
     }
+/* Fill in a fresh random nonce for each inner request*/
+    	random_data.length = 4;
+	random_data.data = (char *)random_buf;
+	retval = krb5_c_random_make_octets(context, &random_data);
+	if (retval == 0) {
+	    	    request->nonce = 0x7fffffff & load_32_n(random_buf);
+		    state->nonce = request->nonce;
+	}
     fast_req.req_body =  request;
     if (fast_req.req_body->padata == NULL) {
 	fast_req.req_body->padata = calloc(1, sizeof(krb5_pa_data *));
@@ -287,6 +297,12 @@
 	krb5_free_pa_data(context, result);
 	result = NULL;
 	if (retval == 0) {
+	    if (fast_response->nonce != state->nonce) {
+		krb5_set_error_message(context, KRB5_KDCREP_MODIFIED, "Nonce in reply did not match expected value");
+		retval = KRB5_KDCREP_MODIFIED;
+	    }
+	}
+	if (retval == 0) {	
 	    fx_error_pa = krb5int_find_pa_data(context, fast_response->padata, KRB5_PADATA_FX_ERROR);
 	    if (fx_error_pa == NULL) {
 		krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, "Expecting FX_ERROR pa-data inside FAST container");

Modified: branches/fast/src/lib/krb5/krb/fast.h
===================================================================
--- branches/fast/src/lib/krb5/krb/fast.h	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/krb/fast.h	2009-03-26 05:37:18 UTC (rev 22138)
@@ -39,6 +39,7 @@
     krb5_ui_4 fast_state_flags;
     krb5_ui_4 fast_options;
     krb5_data cookie_contents;
+    krb5_int32 nonce;
 };
 
 krb5_error_code
@@ -49,7 +50,7 @@
 
 krb5_error_code 
 krb5int_fast_prep_req (krb5_context context, struct krb5int_fast_request_state *state,
-		       const krb5_kdc_req *request,
+		       krb5_kdc_req *request,
 		       const krb5_data *to_be_checksummed, kdc_req_encoder_proc encoder,
 		       krb5_data **encoded_request);
 krb5_error_code

Modified: branches/fast/src/lib/krb5/krb/kfree.c
===================================================================
--- branches/fast/src/lib/krb5/krb/kfree.c	2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/krb/kfree.c	2009-03-26 05:37:18 UTC (rev 22138)
@@ -828,7 +828,6 @@
   if (!val)
     return;
   krb5_free_principal(context, val->client);
-  krb5_free_checksum_contents(context, &val->checksum);
   krb5_free_checksum_contents(context, &val->ticket_checksum);
   free(val);
 }




More information about the cvs-krb5 mailing list