svn rev #22245: branches/krb5-1-7/src/ include/ kdc/ lib/crypto/ lib/crypto/arcfour/ ...

tlyu@MIT.EDU tlyu at MIT.EDU
Wed Apr 15 16:07:21 EDT 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=22245
Commit By: tlyu
Log Message:
ticket: 6436

pull up r22167, r22170 from trunk

 ------------------------------------------------------------------------
 r22170 | hartmans | 2009-04-03 23:03:04 -0400 (Fri, 03 Apr 2009) | 3 lines
 Changed paths:
    M /trunk/src/kdc/fast_util.c
    M /trunk/src/lib/krb5/krb/get_in_tkt.c

 ticket: 6436

 fix logic errors
 ------------------------------------------------------------------------
 r22167 | hartmans | 2009-04-03 00:03:45 -0400 (Fri, 03 Apr 2009) | 3 lines
 Changed paths:
    M /trunk/src/include/k5-int.h
    M /trunk/src/kdc/do_as_req.c
    M /trunk/src/kdc/do_tgs_req.c
    M /trunk/src/kdc/fast_util.c
    M /trunk/src/kdc/kdc_preauth.c
    M /trunk/src/kdc/kdc_util.c
    M /trunk/src/kdc/kdc_util.h
    M /trunk/src/lib/crypto/arcfour/arcfour.c
    M /trunk/src/lib/crypto/arcfour/arcfour.h
    M /trunk/src/lib/crypto/etypes.c
    M /trunk/src/lib/krb5/asn.1/asn1_k_encode.c
    M /trunk/src/lib/krb5/asn.1/krb5_decode.c
    M /trunk/src/lib/krb5/krb/Makefile.in
    M /trunk/src/lib/krb5/krb/fast.c
    M /trunk/src/lib/krb5/krb/fast.h
    M /trunk/src/lib/krb5/krb/get_in_tkt.c
    M /trunk/src/lib/krb5/krb/kfree.c
    M /trunk/src/lib/krb5/krb/preauth2.c
    A /trunk/src/lib/krb5/krb/t_ad_fx_armor.c
    M /trunk/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c

 ticket: 6436

 Merge fast branch at 22166 onto trunk


Changed Files:
U   branches/krb5-1-7/src/include/k5-int.h
U   branches/krb5-1-7/src/kdc/do_as_req.c
U   branches/krb5-1-7/src/kdc/do_tgs_req.c
U   branches/krb5-1-7/src/kdc/fast_util.c
U   branches/krb5-1-7/src/kdc/kdc_preauth.c
U   branches/krb5-1-7/src/kdc/kdc_util.c
U   branches/krb5-1-7/src/kdc/kdc_util.h
U   branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c
U   branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.h
U   branches/krb5-1-7/src/lib/crypto/etypes.c
U   branches/krb5-1-7/src/lib/krb5/asn.1/asn1_k_encode.c
U   branches/krb5-1-7/src/lib/krb5/asn.1/krb5_decode.c
U   branches/krb5-1-7/src/lib/krb5/krb/Makefile.in
U   branches/krb5-1-7/src/lib/krb5/krb/fast.c
U   branches/krb5-1-7/src/lib/krb5/krb/fast.h
U   branches/krb5-1-7/src/lib/krb5/krb/get_in_tkt.c
U   branches/krb5-1-7/src/lib/krb5/krb/kfree.c
U   branches/krb5-1-7/src/lib/krb5/krb/preauth2.c
A   branches/krb5-1-7/src/lib/krb5/krb/t_ad_fx_armor.c
U   branches/krb5-1-7/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c
Modified: branches/krb5-1-7/src/include/k5-int.h
===================================================================
--- branches/krb5-1-7/src/include/k5-int.h	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/include/k5-int.h	2009-04-15 20:07:21 UTC (rev 22245)
@@ -982,7 +982,7 @@
 
 typedef struct _krb5_fast_req {
     krb5_magic magic;
-    krb5_int32 fast_options;
+    krb5_flags fast_options;
     /* padata from req_body is used*/
    krb5_kdc_req *req_body;
 } krb5_fast_req;
@@ -1001,7 +1001,7 @@
 typedef struct _krb5_fast_response {
     krb5_magic magic;
     krb5_pa_data **padata;
-    krb5_keyblock *rep_key;
+    krb5_keyblock *strengthen_key;
     krb5_fast_finished *finished;
     krb5_int32 nonce;
 } krb5_fast_response;

Modified: branches/krb5-1-7/src/kdc/do_as_req.c
===================================================================
--- branches/krb5-1-7/src/kdc/do_as_req.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/kdc/do_as_req.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -119,6 +119,7 @@
     krb5_keylist_node *tmp_mkey_list;
     struct kdc_request_state *state = NULL;
     krb5_data encoded_req_body;
+    krb5_keyblock *as_encrypting_key = NULL;
     
 
 #if APPLE_PKINIT
@@ -592,7 +593,7 @@
 	goto errout;
     }
     ticket_reply.enc_part.kvno = server_key->key_data_kvno;
-    errcode = kdc_fast_response_handle_padata(state, request, &reply);
+    errcode = kdc_fast_response_handle_padata(state, request, &reply, client_keyblock.enctype);
     if (errcode) {
 	status = "fast response handling";
 	goto errout;
@@ -602,8 +603,13 @@
 
     reply.enc_part.enctype = client_keyblock.enctype;
 
-    errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart, 
-				  0, &client_keyblock,  &reply, response);
+    errcode = kdc_fast_handle_reply_key(state, &client_keyblock, &as_encrypting_key);
+    if (errcode) {
+	status = "generating reply key";
+	goto errout;
+    }
+        errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart, 
+				  0, as_encrypting_key,  &reply, response);
     reply.enc_part.kvno = client_key->key_data_kvno;
     if (errcode) {
 	status = "ENCODE_KDC_REP";
@@ -637,7 +643,8 @@
 egress:
     if (pa_context)
 	free_padata_context(kdc_context, &pa_context);
-
+    if (as_encrypting_key)
+	krb5_free_keyblock(kdc_context, as_encrypting_key);
     if (errcode)
 	emsg = krb5_get_error_message(kdc_context, errcode);
 
@@ -760,7 +767,7 @@
 	    if (pa == NULL)
 		retval = ENOMEM;
 	    else 		for (size = 0; td[size]; size++) {
-		krb5_pa_data *pad = malloc(sizeof(krb5_pa_data *));
+		krb5_pa_data *pad = malloc(sizeof(krb5_pa_data ));
 		if (pad == NULL) {
 		    retval = ENOMEM;
 		    break;

Modified: branches/krb5-1-7/src/kdc/do_tgs_req.c
===================================================================
--- branches/krb5-1-7/src/kdc/do_tgs_req.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/kdc/do_tgs_req.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -878,7 +878,8 @@
 
     reply.enc_part.enctype = subkey ? subkey->enctype :
     header_ticket->enc_part2->session->enctype;
-    errcode  = kdc_fast_response_handle_padata(state, request, &reply);
+    errcode  = kdc_fast_response_handle_padata(state, request, &reply,
+					       subkey?subkey->enctype:header_ticket->enc_part2->session->enctype);
     if (errcode !=0 ) {
 	status = "Preparing FAST padata";
 	goto cleanup;
@@ -972,7 +973,7 @@
                    krb5_data **response, const char *status)
 {
     krb5_error errpkt;
-    krb5_error_code retval;
+    krb5_error_code retval = 0;
     krb5_data *scratch;
 
     errpkt.ctime = request->nonce;
@@ -997,7 +998,8 @@
     }
     errpkt.e_data.length = 0;
     errpkt.e_data.data = NULL;
-    retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
+    if (state)
+	retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
     if (retval) {
 	free(scratch);
 	free(errpkt.text.data);

Modified: branches/krb5-1-7/src/kdc/fast_util.c
===================================================================
--- branches/krb5-1-7/src/kdc/fast_util.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/kdc/fast_util.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -50,7 +50,7 @@
     krb5_ticket *ticket = NULL;
     krb5_keyblock *subkey = NULL;
     
-    assert(armor->armor_type = KRB5_FAST_ARMOR_AP_REQUEST);
+    assert(armor->armor_type == KRB5_FAST_ARMOR_AP_REQUEST);
     krb5_clear_error_message(kdc_context);
     retval = krb5_auth_con_init(kdc_context, &authcontext);
     if (retval == 0)
@@ -211,7 +211,7 @@
     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) {
+	if (new_padata == NULL) {
 	    retval = ENOMEM;
 	} else {
 	    new_padata->pa_type = KRB5_PADATA_FX_COOKIE;
@@ -251,8 +251,8 @@
     return;
     if (s->armor_key)
 	krb5_free_keyblock(kdc_context, s->armor_key);
-    if (s->reply_key)
-	krb5_free_keyblock(kdc_context, s->reply_key);
+    if (s->strengthen_key)
+	krb5_free_keyblock(kdc_context, s->strengthen_key);
     if (s->cookie) {
 	free(s->cookie->contents);
 	free(s->cookie);
@@ -263,24 +263,33 @@
 krb5_error_code kdc_fast_response_handle_padata
 (struct kdc_request_state *state,
  krb5_kdc_req *request,
- krb5_kdc_rep *rep)
+ krb5_kdc_rep *rep, krb5_enctype enctype)
 {
     krb5_error_code retval = 0;
     krb5_fast_finished finish;
     krb5_fast_response fast_response;
     krb5_data *encoded_ticket = NULL;
     krb5_data *encrypted_reply = NULL;
-    krb5_pa_data *pa = NULL, **pa_array;
+    krb5_pa_data *pa = NULL, **pa_array = NULL;
     krb5_cksumtype cksumtype = CKSUMTYPE_RSA_MD5;
     krb5_pa_data *empty_padata[] = {NULL};
+    krb5_keyblock *strengthen_key = NULL;
     
     if (!state->armor_key)
 	return 0;
     memset(&finish, 0, sizeof(finish));
+    retval = krb5_init_keyblock(kdc_context, enctype, 0, &strengthen_key);
+    if (retval == 0)
+	retval = krb5_c_make_random_key(kdc_context, enctype, strengthen_key);
+    if (retval == 0) {
+	state->strengthen_key = strengthen_key;
+	strengthen_key = NULL;
+    }
+    
     fast_response.padata = rep->padata;
     if (fast_response.padata == NULL)
 	fast_response.padata = &empty_padata[0];
-        fast_response.rep_key = state->reply_key;
+        fast_response.strengthen_key = state->strengthen_key;
     fast_response.nonce = request->nonce;
     fast_response.finished = &finish;
     finish.client = rep->client;
@@ -309,15 +318,20 @@
 	pa_array[0] = &pa[0];
 	rep->padata = pa_array;
 	pa_array = NULL;
+	free(encrypted_reply);
 	encrypted_reply = NULL;
 	pa = NULL;
     }
     if (pa)
       free(pa);
+    if (pa_array)
+	free(pa_array);
     if (encrypted_reply)
 	krb5_free_data(kdc_context, encrypted_reply);
     if (encoded_ticket)
 	krb5_free_data(kdc_context, encoded_ticket);
+    if (strengthen_key != NULL)
+	krb5_free_keyblock(kdc_context, strengthen_key);
     if (finish.ticket_checksum.contents)
 	krb5_free_checksum_contents(kdc_context, &finish.ticket_checksum);
     return retval;
@@ -339,8 +353,8 @@
     krb5_fast_response resp;
     krb5_error fx_error;
     krb5_data *encoded_fx_error = NULL, *encrypted_reply = NULL;
-    krb5_pa_data pa[2];
-    krb5_pa_data *outer_pa[3];
+    krb5_pa_data pa[1];
+    krb5_pa_data *outer_pa[3], *cookie = NULL;
     krb5_pa_data **inner_pa = NULL;
     size_t size = 0;
     krb5_data *encoded_e_data = NULL;
@@ -366,15 +380,26 @@
 	pa[0].length = encoded_fx_error->length;
 	pa[0].contents = (unsigned char *) encoded_fx_error->data;
 	inner_pa[size++] = &pa[0];
-	resp.padata = inner_pa;
+	if (find_pa_data(inner_pa, KRB5_PADATA_FX_COOKIE) == NULL)
+	    retval = kdc_preauth_get_cookie(state, &cookie);
+    }
+    if (cookie != NULL)
+	inner_pa[size++] = cookie;
+    if (retval == 0) {
+		resp.padata = inner_pa;
 	resp.nonce = request->nonce;
-	resp.rep_key = NULL;
+	resp.strengthen_key = NULL;
 	resp.finished = NULL;
     }
     if (retval == 0)
 	retval = encrypt_fast_reply(state, &resp, &encrypted_reply);
     if (inner_pa)
 	free(inner_pa); /*contained storage from caller and our stack*/
+    if (cookie) {
+	free(cookie->contents);
+	free(cookie);
+	cookie = NULL;
+    }
     if (retval == 0) {
 	pa[0].pa_type = KRB5_PADATA_FX_FAST;
 	pa[0].length = encrypted_reply->length;
@@ -396,3 +421,45 @@
 	krb5_free_data(kdc_context, encoded_fx_error);
     return retval;
 }
+
+krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
+					  krb5_keyblock *existing_key,
+					  krb5_keyblock **out_key)
+{
+    krb5_error_code retval = 0;
+    if (state->armor_key)
+	retval = krb5_c_fx_cf2_simple(kdc_context,
+				      state->strengthen_key, "strengthenkey", 
+				      existing_key,
+				      "replykey", out_key);
+    else retval = krb5_copy_keyblock(kdc_context, existing_key, out_key);
+    return retval;
+}
+
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+				    krb5_pa_data **cookie)
+{
+    char *contents;
+    krb5_pa_data *pa = NULL;
+    /* In our current implementation, the only purpose served by
+     * returning a cookie is to indicate that a conversation should
+     * continue on error.  Thus, the cookie can have a constant
+     * string.  If cookies are used for real, versioning so that KDCs
+     * can be upgraded, keying, expiration and many other issues need
+     * to be considered.
+     */
+    contents = strdup("MIT");
+    if (contents == NULL)
+	return ENOMEM;
+    pa = calloc(1, sizeof(krb5_pa_data));
+    if (pa == NULL) {
+	free(contents);
+	return ENOMEM;
+    }
+    pa->pa_type = KRB5_PADATA_FX_COOKIE;
+    pa->length = strlen(contents);
+    pa->contents = (unsigned char *) contents;
+    *cookie = pa;
+    return 0;
+}

Modified: branches/krb5-1-7/src/kdc/kdc_preauth.c
===================================================================
--- branches/krb5-1-7/src/kdc/kdc_preauth.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/kdc/kdc_preauth.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -290,6 +290,17 @@
 	0
     },
     {
+	"FAST",
+        KRB5_PADATA_FX_FAST,
+        PA_HARDWARE,
+	NULL,
+	NULL,
+	NULL,
+        NULL,
+	NULL,
+	0
+    },
+    {
 	"etype-info",
 	KRB5_PADATA_ETYPE_INFO,
 	0,
@@ -961,7 +972,8 @@
     e_data->data = 0;
     
     hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
-    pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+1));
+    /* Allocate 1 entry for the terminator and one for the cookie*/
+    pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+21));
     if (pa_data == 0)
 	return;
     memset(pa_data, 0, sizeof(krb5_pa_data *) * (n_preauth_systems+1));
@@ -995,6 +1007,8 @@
 			  "%spreauth required but hint list is empty",
 			  hw_only ? "hw" : "");
     }
+/* If we fail to get the cookie it is probably still reasonable to continue with the response*/
+    kdc_preauth_get_cookie(request->kdc_state, pa);
     retval = encode_krb5_padata_sequence(pa_data, &edat);
     if (retval)
 	goto errout;

Modified: branches/krb5-1-7/src/kdc/kdc_util.c
===================================================================
--- branches/krb5-1-7/src/kdc/kdc_util.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/kdc/kdc_util.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -349,13 +349,13 @@
 				   authenticator->authorization_data,
 				   KRB5_AUTHDATA_FX_ARMOR, &authdata);
     if (retval != 0)
-	goto cleanup_auth_context;
+	goto cleanup_authenticator;
         if (authdata&& authdata[0]) {
 	krb5_set_error_message(kdc_context, KRB5KDC_ERR_POLICY,
 			       "ticket valid only as FAST armor");
 	retval = KRB5KDC_ERR_POLICY;
 	krb5_free_authdata(kdc_context, authdata);
-	goto cleanup_auth_context;
+	goto cleanup_authenticator;
     }
     krb5_free_authdata(kdc_context, authdata);
     

Modified: branches/krb5-1-7/src/kdc/kdc_util.h
===================================================================
--- branches/krb5-1-7/src/kdc/kdc_util.h	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/kdc/kdc_util.h	2009-04-15 20:07:21 UTC (rev 22245)
@@ -302,11 +302,12 @@
 
 struct kdc_request_state {
     krb5_keyblock *armor_key;
-  krb5_keyblock *reply_key; /*When replaced by FAST*/
+  krb5_keyblock *strengthen_key; 
     krb5_pa_data *cookie;
     krb5_int32 fast_options;
     krb5_int32 fast_internal_flags;
 };
+
 krb5_error_code kdc_make_rstate(struct kdc_request_state **out);
 void kdc_free_rstate
 (struct kdc_request_state *s);
@@ -325,12 +326,21 @@
 krb5_error_code kdc_fast_response_handle_padata
 (struct kdc_request_state *state,
  krb5_kdc_req *request,
- krb5_kdc_rep *rep);
+ krb5_kdc_rep *rep,
+ krb5_enctype enctype);
 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 kdc_fast_handle_reply_key(struct kdc_request_state *state,
+					  krb5_keyblock *existing_key,
+					  krb5_keyblock **out_key);
+
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+				    krb5_pa_data **cookie);
+
  
 
 

Modified: branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c
===================================================================
--- branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -8,6 +8,8 @@
 */
 #include "k5-int.h"
 #include "arcfour-int.h"
+#include "../hash_provider/hash_provider.h"
+
 const char *const krb5int_arcfour_l40 = "fortybits";
 
 void
@@ -304,3 +306,12 @@
   return (ret);
 }
 
+ krb5_error_code krb5int_arcfour_prf(
+					 const struct krb5_enc_provider *enc,
+					 const struct krb5_hash_provider *hash,
+					 const krb5_keyblock *key,
+					 const krb5_data *in, krb5_data *out)
+ {
+   assert(out->length == 20);
+   return krb5_hmac(&krb5int_hash_sha1, key, 1, in, out);
+ }

Modified: branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.h
===================================================================
--- branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.h	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.h	2009-04-15 20:07:21 UTC (rev 22245)
@@ -34,5 +34,10 @@
 
 extern const struct krb5_enc_provider krb5int_enc_arcfour;
 extern const struct krb5_aead_provider krb5int_aead_arcfour;
+ krb5_error_code krb5int_arcfour_prf(
+					 const struct krb5_enc_provider *enc,
+					 const struct krb5_hash_provider *hash,
+					 const krb5_keyblock *key,
+					 const krb5_data *in, krb5_data *out);
 
 #endif /* ARCFOUR_H */

Modified: branches/krb5-1-7/src/lib/crypto/etypes.c
===================================================================
--- branches/krb5-1-7/src/lib/crypto/etypes.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/crypto/etypes.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -119,10 +119,10 @@
       "ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5,
-      0,
+      20,
       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
       krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
-      NULL, /*PRF*/
+      krb5int_arcfour_prf, /*PRF*/
       CKSUMTYPE_HMAC_MD5_ARCFOUR,
       &krb5int_aead_arcfour,
       0 /*flags*/ },
@@ -131,10 +131,10 @@
       "Exportable ArcFour with HMAC/md5",
       &krb5int_enc_arcfour,
       &krb5int_hash_md5,
-      0,
+      20,
       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
       krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
-      NULL, /*PRF*/
+      krb5int_arcfour_prf, /*PRF*/
       CKSUMTYPE_HMAC_MD5_ARCFOUR,
       &krb5int_aead_arcfour,
       ETYPE_WEAK

Modified: branches/krb5-1-7/src/lib/krb5/asn.1/asn1_k_encode.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/asn.1/asn1_k_encode.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/asn.1/asn1_k_encode.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -1211,7 +1211,7 @@
 DEFPTRTYPE(ptr_fast_req_padata, fast_req_padata);
 
 static const struct field_info fast_req_fields[] = {
-    FIELDOF_NORM(krb5_fast_req, int32, fast_options, 0),
+    FIELDOF_NORM(krb5_fast_req, krb5_flags, fast_options, 0),
     FIELDOF_NORM( krb5_fast_req, ptr_fast_req_padata, req_body, 1),
     FIELDOF_NORM( krb5_fast_req, ptr_kdc_req_body, req_body, 2),
 };
@@ -1233,7 +1233,7 @@
 
 static const struct field_info fast_response_fields[] = {
     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_encryption_key, strengthen_key, 1, 1),
     FIELDOF_OPT( krb5_fast_response, ptr_fast_finished, finished, 2, 2),
     FIELDOF_NORM(krb5_fast_response, int32, nonce, 3),
 };
@@ -1242,7 +1242,7 @@
 {
     unsigned int optional = 0;
     const krb5_fast_response *val = p;
-    if (val->rep_key)
+    if (val->strengthen_key)
         optional |= (1u <<1);
     if (val->finished)
         optional |= (1u<<2);

Modified: branches/krb5-1-7/src/lib/krb5/asn.1/krb5_decode.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/asn.1/krb5_decode.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/asn.1/krb5_decode.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -1114,7 +1114,7 @@
     alloc_field(rep->req_body);
     clear_field(rep, req_body->padata);
     {begin_structure();
-    get_field(rep->fast_options, 0, asn1_decode_int32);
+    get_field(rep->fast_options, 0, asn1_decode_krb5_flags);
     opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data);
     get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body);
     end_structure(); }
@@ -1137,10 +1137,10 @@
     alloc_field(rep);
     clear_field(rep, finished);
     clear_field(rep, padata);
-    clear_field(rep,rep_key);
+    clear_field(rep,strengthen_key);
     {begin_structure();
     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->strengthen_key, 1, asn1_decode_encryption_key_ptr);
     opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr);
     get_field(rep->nonce, 3, asn1_decode_int32);
         end_structure(); }

Modified: branches/krb5-1-7/src/lib/krb5/krb/Makefile.in
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/Makefile.in	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/Makefile.in	2009-04-15 20:07:21 UTC (rev 22245)
@@ -271,6 +271,7 @@
 	$(srcdir)/srv_dec_tkt.c	\
 	$(srcdir)/srv_rcache.c	\
 	$(srcdir)/str_conv.c	\
+	$(srcdir)/t_ad_fx_armor.c \
 	$(srcdir)/tgtname.c	\
 	$(srcdir)/unparse.c	\
 	$(srcdir)/valid_times.c	\
@@ -317,6 +318,9 @@
 
 t_walk_rtree: $(T_WALK_RTREE_OBJS) $(KRB5_BASE_DEPLIBS)
 	$(CC_LINK) -o t_walk_rtree $(T_WALK_RTREE_OBJS) $(KRB5_BASE_LIBS)
+t_ad_fx_armor: t_ad_fx_armor.o
+	$(CC_LINK) -o $@ $< $(KRB5_BASE_LIBS)
+
 t_authdata: t_authdata.o copy_auth.o
 	$(CC_LINK) -o $@ $< copy_auth.o $(KRB5_BASE_LIBS)
 

Modified: branches/krb5-1-7/src/lib/krb5/krb/fast.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/fast.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/fast.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -299,6 +299,8 @@
 	free(scratch.data);
     if (encrypted_response)
 	krb5_free_enc_data(context, encrypted_response);
+    if (local_resp)
+	krb5_free_fast_response(context, local_resp);
     return retval;
 }
 
@@ -376,9 +378,11 @@
 	    fast_response->padata = NULL;
 	    /*
 	     * If there is more than the fx_error padata, then we want
-	     * to retry the error
+	     * to retry the error if a cookie is present
 	     */
 	    *retry = (*out_padata)[1] != NULL;
+	    if (krb5int_find_pa_data(context, *out_padata, KRB5_PADATA_FX_COOKIE) == NULL)
+		*retry = 0;
 	}
 	if (fx_error)
 	    krb5_free_error(context, fx_error);
@@ -408,14 +412,14 @@
 krb5_error_code krb5int_fast_process_response
 (krb5_context context, struct krb5int_fast_request_state *state,
  krb5_kdc_rep *resp,
- krb5_keyblock **as_key)
+ krb5_keyblock **strengthen_key)
 {
     krb5_error_code retval = 0;
     krb5_fast_response *fast_response = NULL;
     krb5_data *encoded_ticket = NULL;
     krb5_boolean cksum_valid;
     krb5_clear_error_message(context);
-    *as_key = NULL;
+    *strengthen_key = NULL;
     if (state->armor_key == 0)
 	return 0;
         retval = decrypt_fast_reply(context, state, resp->padata,
@@ -442,8 +446,8 @@
 	krb5_free_principal(context, resp->client);
 	resp->client = fast_response->finished->client;
 	fast_response->finished->client = NULL;
-	*as_key = fast_response->rep_key;
-	fast_response->rep_key = NULL;
+	*strengthen_key = fast_response->strengthen_key;
+	fast_response->strengthen_key = NULL;
 	krb5_free_pa_data(context, resp->padata);
 	resp->padata = fast_response->padata;
 	fast_response->padata = NULL;
@@ -454,6 +458,29 @@
 	krb5_free_data(context, encoded_ticket);
     return retval;
 }
+
+krb5_error_code krb5int_fast_reply_key(krb5_context context,
+				       krb5_keyblock *strengthen_key,
+				       krb5_keyblock *existing_key,
+				       krb5_keyblock *out_key)
+{
+    krb5_keyblock *key = NULL;
+    krb5_error_code retval = 0;
+    krb5_free_keyblock_contents(context, out_key);
+    if (strengthen_key) {
+	retval = krb5_c_fx_cf2_simple(context, strengthen_key,
+				      "strengthenkey", existing_key, "replykey", &key);
+	if (retval == 0) {
+	    *out_key = *key;
+	    free(key);
+	}
+    } else {
+	retval = krb5_copy_keyblock_contents(context, existing_key, out_key);
+    }
+    return retval;
+}
+
+
 krb5_error_code
 krb5int_fast_make_state( krb5_context context, struct krb5int_fast_request_state **state)
 {
@@ -473,11 +500,6 @@
     /*We are responsible for none of the store in the fast_outer_req*/
     krb5_free_keyblock(context, state->armor_key);
     krb5_free_fast_armor(context, state->armor);
-    if (state->cookie) {
-	free(state->cookie->contents);
-	free(state->cookie);
-	state->cookie = NULL;
-    }
     free(state);
 }
 

Modified: branches/krb5-1-7/src/lib/krb5/krb/fast.h
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/fast.h	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/fast.h	2009-04-15 20:07:21 UTC (rev 22245)
@@ -38,7 +38,6 @@
     krb5_fast_armor *armor;
     krb5_ui_4 fast_state_flags;
     krb5_ui_4 fast_options;
-  krb5_pa_data *cookie;
     krb5_int32 nonce;
 };
 
@@ -61,7 +60,7 @@
 krb5_error_code krb5int_fast_process_response
 (krb5_context context, struct krb5int_fast_request_state *state,
  krb5_kdc_rep *resp,
- krb5_keyblock **as_key);
+ krb5_keyblock **strengthen_key);
 
 krb5_error_code
 krb5int_fast_make_state( krb5_context context, struct krb5int_fast_request_state **state);
@@ -73,5 +72,11 @@
  krb5_gic_opt_ext *opte,
  krb5_kdc_req *request);
 
+krb5_error_code krb5int_fast_reply_key(krb5_context context,
+				       krb5_keyblock *strengthen_key,
+				       krb5_keyblock *existing_key,
+				       krb5_keyblock *output_key);
 
+				       
+
 #endif

Modified: branches/krb5-1-7/src/lib/krb5/krb/get_in_tkt.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/get_in_tkt.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/get_in_tkt.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -967,8 +967,8 @@
     int loopcount;
     krb5_data salt;
     krb5_data s2kparams;
-    krb5_keyblock as_key;
-    krb5_keyblock *fast_as_key = NULL;
+    krb5_keyblock as_key, encrypting_key;
+    krb5_keyblock *strengthen_key = NULL;
     krb5_error *err_reply;
     krb5_kdc_rep *local_as_reply;
     krb5_timestamp time_now;
@@ -994,6 +994,8 @@
     preauth_to_use = NULL;
     kdc_padata = NULL;
     as_key.length = 0;
+    encrypting_key.length = 0;
+    encrypting_key.contents = NULL;
         salt.length = 0;
     salt.data = NULL;
 
@@ -1340,8 +1342,6 @@
 		out_padata = NULL;
 		krb5_free_error(context, err_reply);
 		err_reply = NULL;
-		if (ret)
-		    goto cleanup;
 		ret = sort_krb5_padata_sequence(context,
 						&request.server->realm,
 						preauth_to_use);
@@ -1399,7 +1399,7 @@
     /* process any preauth data in the as_reply */
     krb5_clear_preauth_context_use_counts(context);
     ret = krb5int_fast_process_response(context, fast_state,
-				       local_as_reply, &fast_as_key);
+				       local_as_reply, &strengthen_key);
     if (ret)
 	goto cleanup;
     if ((ret = sort_krb5_padata_sequence(context, &request.server->realm,
@@ -1447,18 +1447,15 @@
        it.  If decrypting the as_rep fails, or if there isn't an
        as_key at all yet, then use the gak_fct to get one, and try
        again.  */
-    if (fast_as_key) {
-	if (as_key.length)
-	    krb5_free_keyblock_contents(context, &as_key);
-	as_key = *fast_as_key;
-	free(fast_as_key);
-	fast_as_key = NULL;
-    }
-        if (as_key.length)
-	ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
-			       NULL, &as_key, krb5_kdc_rep_decrypt_proc,
+    if (as_key.length) {
+      ret = krb5int_fast_reply_key(context, strengthen_key, &as_key,
+				   &encrypting_key);
+      if (ret)
+	goto cleanup;
+      	ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
+			       NULL, &encrypting_key, krb5_kdc_rep_decrypt_proc,
 			       NULL);
-    else
+    } else
 	ret = -1;
 	   
     if (ret) {
@@ -1470,8 +1467,12 @@
 			       &as_key, gak_data))))
 	    goto cleanup;
 
+	ret = krb5int_fast_reply_key(context, strengthen_key, &as_key,
+				     &encrypting_key);
+	if (ret)
+	  goto cleanup;
 	if ((ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
-				    NULL, &as_key, krb5_kdc_rep_decrypt_proc,
+				    NULL, &encrypting_key, krb5_kdc_rep_decrypt_proc,
 				    NULL)))
 	    goto cleanup;
     }
@@ -1511,8 +1512,10 @@
 	}
     }
     krb5_preauth_request_context_fini(context);
-	krb5_free_keyblock(context, fast_as_key);
-    if (fast_state)
+	krb5_free_keyblock(context, strengthen_key);
+	if (encrypting_key.contents)
+	  krb5_free_keyblock_contents(context, &encrypting_key);
+	    if (fast_state)
 	krb5int_fast_free_state(context, fast_state);
     if (out_padata)
 	krb5_free_pa_data(context, out_padata);

Modified: branches/krb5-1-7/src/lib/krb5/krb/kfree.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/kfree.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/kfree.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -819,6 +819,7 @@
     return;
   krb5_free_pa_data(context, val->padata);
   krb5_free_fast_finished(context, val->finished);
+  krb5_free_keyblock(context, val->strengthen_key);
   free(val);
 }
 

Modified: branches/krb5-1-7/src/lib/krb5/krb/preauth2.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/preauth2.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/preauth2.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -646,6 +646,36 @@
 }
 
 static
+krb5_error_code pa_fx_cookie(krb5_context context,
+				 krb5_kdc_req *request,
+				 krb5_pa_data *in_padata,
+				 krb5_pa_data **out_padata,
+				 krb5_data *salt,
+				 krb5_data *s2kparams,
+				 krb5_enctype *etype,
+				 krb5_keyblock *as_key,
+				 krb5_prompter_fct prompter,
+				 void *prompter_data,
+				 krb5_gic_get_as_key_fct gak_fct,
+				 void *gak_data)
+{
+    krb5_pa_data *pa = calloc(1, sizeof(krb5_pa_data));
+    krb5_octet *contents;
+    if (pa == NULL)
+	return ENOMEM;
+    contents = malloc(in_padata->length);
+    if (contents == NULL) {
+	free(pa);
+	return ENOMEM;
+    }
+    *pa = *in_padata;
+    pa->contents = contents;
+    memcpy(contents, in_padata->contents, pa->length);
+    *out_padata = pa;
+    return 0;
+}
+
+static
 krb5_error_code pa_enc_timestamp(krb5_context context,
 				 krb5_kdc_req *request,
 				 krb5_pa_data *in_padata,
@@ -1710,6 +1740,11 @@
 	PA_REAL,
     },
     {
+	KRB5_PADATA_FX_COOKIE,
+	pa_fx_cookie,
+	PA_INFO,
+    },
+    {
 	-1,
 	NULL,
 	0,

Added: branches/krb5-1-7/src/lib/krb5/krb/t_ad_fx_armor.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/t_ad_fx_armor.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/lib/krb5/krb/t_ad_fx_armor.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -0,0 +1,36 @@
+#include <memory.h>
+#include <stdio.h>
+#include <krb5/krb5.h>
+
+#define test(x) do {retval = (x); \
+  if(retval != 0) {						\
+  const char *errmsg = krb5_get_error_message(context, retval);	\
+  fprintf(stderr, "Error message: %s\n", errmsg); \
+  abort(); } \
+  } while(0);
+
+krb5_authdata ad_fx_armor = {0, KRB5_AUTHDATA_FX_ARMOR, 1, ""};
+krb5_authdata *array[] = {&ad_fx_armor, NULL};
+
+
+int main( int argc, char **argv)
+{
+    krb5_context context;
+    krb5_ccache ccache = NULL;
+    krb5_creds creds, *out_creds = NULL;
+    krb5_error_code retval = 0;
+    test(krb5_init_context(&context));
+    memset(&creds, 0, sizeof(creds));
+    creds.authdata = array;
+    test(krb5_cc_default(context, &ccache));
+    test(krb5_cc_get_principal(context, ccache, &creds.client));
+    test(krb5_parse_name(context, argv[1], &creds.server));
+    test(krb5_get_credentials(context, 0, ccache, &creds, &out_creds));
+    test(krb5_cc_destroy(context, ccache));
+    test(krb5_cc_default(context, &ccache));
+    test(krb5_cc_initialize(context, ccache, out_creds->client));
+    test(krb5_cc_store_cred(context, ccache, out_creds));
+    test(krb5_cc_close(context,ccache));
+    return 0;
+		 
+} 

Modified: branches/krb5-1-7/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c
===================================================================
--- branches/krb5-1-7/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c	2009-04-15 20:07:18 UTC (rev 22244)
+++ branches/krb5-1-7/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c	2009-04-15 20:07:21 UTC (rev 22245)
@@ -116,6 +116,7 @@
 	krb5_pa_data **pa_array = NULL;
 	krb5_data *encoded_ts = NULL;
 	krb5_pa_enc_ts ts;
+	enc.ciphertext.data = NULL;
 	if (retval == 0)
 	retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
 	if (retval == 0)
@@ -300,8 +301,6 @@
     }
     if (armor_key)
 	krb5_free_keyblock(context, armor_key);
-    if (challenge_key)
-	krb5_free_keyblock(context, challenge_key);
     if (plain.data) 
 	free(plain.data);
     if (enc)




More information about the cvs-krb5 mailing list