svn rev #23514: branches/anonymous/src/ include/krb5/ lib/krb5/krb/
hartmans@MIT.EDU
hartmans at MIT.EDU
Wed Dec 23 16:11:06 EST 2009
http://src.mit.edu/fisheye/changelog/krb5/?cs=23514
Commit By: hartmans
Log Message:
Client side of PA_PKINIT_KX
The anonymous draft specifies the use of PA_PKINIT_KX to confirm that
both the client and KDc contributed to the session key and to confirm
the session key is fresh. Implement client support for this item.
* krb5.hin: define padata and key usage constants
* get_in_tkt.c: New function verify_anonymous to perform verification
Changed Files:
U branches/anonymous/src/include/krb5/krb5.hin
U branches/anonymous/src/lib/krb5/krb/get_in_tkt.c
Modified: branches/anonymous/src/include/krb5/krb5.hin
===================================================================
--- branches/anonymous/src/include/krb5/krb5.hin 2009-12-23 21:11:03 UTC (rev 23513)
+++ branches/anonymous/src/include/krb5/krb5.hin 2009-12-23 21:11:06 UTC (rev 23514)
@@ -638,7 +638,7 @@
#define KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY 27 /* XXX note conflict with above */
#define KRB5_KEYUSAGE_AD_SIGNEDPATH -21
-
+#define KRB5_KEYUSAGE_PA_PKINIT_KX 44
/* define in draft-ietf-krb-wg-preauth-framework*/
#define KRB5_KEYUSAGE_FAST_REQ_CHKSUM 50
#define KRB5_KEYUSAGE_FAST_ENC 51
@@ -1041,6 +1041,7 @@
#define KRB5_PADATA_FX_FAST 136
#define KRB5_PADATA_FX_ERROR 137
#define KRB5_PADATA_ENCRYPTED_CHALLENGE 138
+#define KRB5_PADATA_PKINIT_KX 147
#define KRB5_ENCPADATA_REQ_ENC_PA_REP 149
#define KRB5_SAM_USE_SAD_AS_KEY 0x80000000
Modified: branches/anonymous/src/lib/krb5/krb/get_in_tkt.c
===================================================================
--- branches/anonymous/src/lib/krb5/krb/get_in_tkt.c 2009-12-23 21:11:03 UTC (rev 23513)
+++ branches/anonymous/src/lib/krb5/krb/get_in_tkt.c 2009-12-23 21:11:06 UTC (rev 23514)
@@ -283,7 +283,72 @@
return (retval);
}
+/**
+ * Fully anonymous replies include a pa_pkinit_kx padata type including the KDC
+ * contribution key. This routine confirms that the session key is of the
+ * right form for fully anonymous requests. It is here rather than in the
+ * preauth code because the session key cannot be verified until the AS reply
+ * is decrypted and the preauth code all runs before the AS reply is decrypted.
+ */
static krb5_error_code
+verify_anonymous( krb5_context context, krb5_kdc_req *request,
+ krb5_kdc_rep *reply, krb5_keyblock *as_key)
+{
+ krb5_error_code ret = 0;
+ krb5_pa_data *pa;
+ krb5_data scratch;
+ krb5_keyblock *kdc_key = NULL, *expected = NULL;
+ krb5_enc_data *enc = NULL;
+ krb5_keyblock *session = reply->enc_part2->session;
+ if (!krb5_principal_compare_any_realm(context, request->client,
+ krb5_anonymous_principal()))
+ return 0; /*Only applies to fully anonymous*/
+ pa = krb5int_find_pa_data(context, reply->padata, KRB5_PADATA_PKINIT_KX);
+ if (pa == NULL)
+ goto verification_error;
+ scratch.length = pa->length;
+ scratch.data = (char *) pa->contents;
+ ret = decode_krb5_enc_data( &scratch, &enc);
+ if (ret)
+ goto cleanup;
+ scratch.data = k5alloc(enc->ciphertext.length, &ret);
+ if (ret)
+ goto cleanup;
+ scratch.length = enc->ciphertext.length;
+ ret = krb5_c_decrypt(context, as_key, KRB5_KEYUSAGE_PA_PKINIT_KX,
+ NULL /*cipherstate*/, enc, &scratch);
+ if (ret) {
+ free( scratch.data);
+ goto cleanup;
+ }
+ ret = decode_krb5_encryption_key( &scratch, &kdc_key);
+ zap(scratch.data, scratch.length);
+ free(scratch.data);
+ if (ret)
+ goto cleanup;
+ ret = krb5_c_fx_cf2_simple( context, kdc_key, "PKINIT",
+ as_key, "KEYEXCHANGE", &expected);
+ if (ret)
+ goto cleanup;
+ if ((expected->enctype != session->enctype)
+ || (expected->length != session->length)
+ || (memcmp(expected->contents, session->contents, expected->length) != 0))
+ goto verification_error;
+cleanup:
+ if (kdc_key)
+ krb5_free_keyblock(context, kdc_key);
+ if (expected)
+ krb5_free_keyblock(context, expected);
+ if (enc)
+ krb5_free_enc_data(context, enc);
+ return ret;
+verification_error:
+ ret = KRB5_KDCREP_MODIFIED;
+ krb5_set_error_message(context, ret, "Reply has wrong form of session key for anonymous request");
+ goto cleanup;
+}
+
+static krb5_error_code
verify_as_reply(krb5_context context,
krb5_timestamp time_now,
krb5_kdc_req *request,
@@ -1994,6 +2059,10 @@
ctx->request, ctx->reply);
if (code != 0)
goto cleanup;
+ code = verify_anonymous( context, ctx->request, ctx->reply,
+ &encrypting_key);
+ if (code)
+ goto cleanup;
code = stash_as_reply(context, ctx->request_time, ctx->request,
ctx->reply, &ctx->cred, NULL);
More information about the cvs-krb5
mailing list