GSSAPI issue from Windows clients

Greg Hudson ghudson at MIT.EDU
Wed Feb 16 11:11:50 EST 2011


On Wed, 2011-02-16 at 03:07 -0500, Carson Gaspar wrote:
> Does anyone have any clues to lend? I see a note in 1.8.3 that some 
> things were taking the MS MD5 code path that shouldn't be, but 1.8.3 
> claims to fix that, and 1.8.3 fails the same way 1.8.2 does.

You've found an interop bug, which I think (and hope) only happens in
pretty specific circumstances.  Here's what I think is happening:

* The MS client authenticates to AD's KDC and gets a cross-realm TGT for
the MIT KDC, which contains a PAC.

* The MS client cross-realm gets a service ticket from the MIT KDC.  The
MIT KDC is presumably <1.8 which isn't smart enough to know anything
about PACs, so it just copies the PAC from the cross-realm TGT into the
service ticket.

* If compiled against 1.6, the application server isn't smart enough to
know anything about PACs and therefore ignores it.

* If compiled against 1.8, the application server tries to verify the
PAC signature.  This is doomed to fail because the PAC is signed with
the cross-realm TGT's service key.  But it doesn't even get to the point
of failing with a checksum mismatch, because...

* For whatever reason, PAC signatures from AD always use the hmac-md5
checksum type, regardless off the type of the key.  In 1.8.3 we made
hmac-md5 signature verification possible for any key type, but...

* We didn't test with DES keys, and there's a bug.
krb5int_hmacmd5_checksum() computes an intermediate 128-bit HMAC key,
and the container for that key is allocated based on the length of the
signing key.  If the signing key is more than 128 bits, that works okay
(the container is shortened to the length of the intermediate key), but
if it's less than 128 bits, you run into the internal length check
failure that you see in the debugger.

What I think we (MIT) need to do is:

* Fix krb5int_hmacmd5_checksum() to allocate the intermediate key
container based on the hash blocksize.  With this change alone, you will
still run into a checksum mismatch if my understanding of the situation
is correct.

* Our PAC verification code needs to get less strict, to handle the case
of PACs copied from a cross-realm TGT by a PAC-ignorant KDC.  We already
have code in the 1.8 branch (I think not yet released) to handle the
case of a missing PAC signature.

I've attached a lightly tested patch to make these changes if you want
to try it yourself.
-------------- next part --------------
Index: lib/crypto/krb/checksum/hmac_md5.c
===================================================================
--- lib/crypto/krb/checksum/hmac_md5.c	(revision 24634)
+++ lib/crypto/krb/checksum/hmac_md5.c	(working copy)
@@ -52,7 +52,7 @@
         return KRB5_BAD_ENCTYPE;
     if (ctp->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) {
 	/* Compute HMAC(key, "signaturekey\0") to get the signing key ks. */
-	ret = alloc_data(&ds, key->keyblock.length);
+	ret = alloc_data(&ds, ctp->hash->blocksize);
 	if (ret != 0)
 	    goto cleanup;
 
Index: lib/krb5/krb/pac.c
===================================================================
--- lib/krb5/krb/pac.c	(revision 24634)
+++ lib/krb5/krb/pac.c	(working copy)
@@ -637,17 +637,8 @@
         return EINVAL;
 
     ret = k5_pac_verify_server_checksum(context, pac, server);
-    if (ret == ENOENT) {
-        /*
-         * Apple Mac OS X Server Open Directory KDC (at least 10.6)
-         * appears to provide a PAC that lacks a server checksum.
-         */
-        TRACE_MSPAC_NOSRVCKSUM(context);
-        pac->verified = FALSE;
+    if (ret != 0)
         return ret;
-    } else if (ret != 0) {
-        return ret;
-    }
 
     if (privsvr != NULL) {
         ret = k5_pac_verify_kdc_checksum(context, pac, privsvr);
@@ -810,27 +801,17 @@
                            req->ticket->enc_part2->client,
                            key,
                            NULL);
-
-    /*
-     * If the server checksum is not found, return success to
-     * krb5int_authdata_verify() to work around an apparent Open
-     * Directory bug.  Non-verified PACs won't be returned by
-     * mspac_get_attribute().
-     */
-    if (code == ENOENT && !pacctx->pac->verified) {
-        code = 0;
-    }
-
-#if 0
-    /*
-     * Now, we could return 0 and just set pac->verified to FALSE.
-     * Thoughts?
-     */
-    if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+    if (code != 0) {
+        /*
+         * Don't fail the whole authentication, just don't mark the PAC as
+         * verified.  A checksum mismatch can occur if the PAC was copied from
+         * a cross-realm TGT by an ignorant KDC, and Apple Mac OS X Server Open
+         * Directory (as of 10.6) generates PACs with no server checksum at
+         * all.
+         */
         assert(pacctx->pac->verified == FALSE);
         code = 0;
     }
-#endif
 
     return code;
 }


More information about the Kerberos mailing list