svn rev #22374: branches/krb5-1-7/src/lib/ crypto/ crypto/arcfour/ krb5/krb/

tlyu@MIT.EDU tlyu at MIT.EDU
Sun May 24 18:50:59 EDT 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=22374
Commit By: tlyu
Log Message:
ticket: 6490
version_fixed: 1.7

pull up 22355, 22356, 22357 from trunk

 ------------------------------------------------------------------------
 r22357 | ghudson | 2009-05-20 04:05:53 +0200 (Wed, 20 May 2009) | 6 lines

 ticket: 6490

 Restore compatibility with KDCs using key usage 8 to encrypt TGS
 replies in a subkey, by implementing a fallback in
 krb5_arcfour_decrypt.

 ------------------------------------------------------------------------
 r22356 | ghudson | 2009-05-20 01:17:49 +0200 (Wed, 20 May 2009) | 13 lines

 ticket: 6490
 status: open
 tags: pullup

 When using keyed checksum types with TGS subkeys, Microsoft AD 2003
 verifies the checksum using the subkey, whereas MIT and Heimdal verify
 it using the TGS session key.  (RFC 4120 is actually silent on which
 is correct; RFC 4757 specifies the TGS session key.)  To sidestep this
 interop issue, don't use keyed checksum types with RC4 keys without
 explicit configuration in krb5.conf.  Using keyed checksum types with
 AES is fine since, experimentally, AD 2008 accepts checksums keyed
 with the TGS session key.

 ------------------------------------------------------------------------
 r22355 | hartmans | 2009-05-19 01:28:53 +0200 (Tue, 19 May 2009) | 5 lines

 ticket: 6490
 status: open

 In practice, key usage 9 requires no translation.


Changed Files:
U   branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c
U   branches/krb5-1-7/src/lib/crypto/t_encrypt.c
U   branches/krb5-1-7/src/lib/krb5/krb/send_tgs.c
Modified: branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c
===================================================================
--- branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c	2009-05-24 22:50:44 UTC (rev 22373)
+++ branches/krb5-1-7/src/lib/crypto/arcfour/arcfour.c	2009-05-24 22:50:58 UTC (rev 22374)
@@ -47,7 +47,7 @@
     case 8:
     return 8;
   case 9:			/* tgs-rep encrypted with subkey */
-    return 8;
+    return 9;
   case 10:			/* ap-rep authentication cksum */
     return 10;			/* xxx  Microsoft never uses this*/
   case 11:			/* app-req authenticator */
@@ -252,41 +252,58 @@
   checksum.length=hashsize;
   checksum.data=input->data;
 
-  /* compute the salt */
   ms_usage=krb5int_arcfour_translate_usage(usage);
-  if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
-    strncpy(salt.data, krb5int_arcfour_l40, salt.length);
-    store_32_le(ms_usage, salt.data+10);
-  } else {
-    salt.length=4;
-    store_32_le(ms_usage, salt.data);
-  }
-  ret=krb5_hmac(hash, key, 1, &salt, &d1);
-  if (ret)
-    goto cleanup;
 
-  memcpy(k2.contents, k1.contents, k2.length);
+  /* We may have to try two ms_usage values; see below. */
+  do {
+      /* compute the salt */
+      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+	  strncpy(salt.data, krb5int_arcfour_l40, salt.length);
+	  store_32_le(ms_usage, salt.data + 10);
+      } else {
+	  salt.length = 4;
+	  store_32_le(ms_usage, salt.data);
+      }
+      ret = krb5_hmac(hash, key, 1, &salt, &d1);
+      if (ret)
+	  goto cleanup;
 
-  if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
-    memset(k1.contents+7, 0xab, 9);
+      memcpy(k2.contents, k1.contents, k2.length);
+
+      if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+	  memset(k1.contents + 7, 0xab, 9);
   
-  ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
-  if (ret)
-    goto cleanup;
+      ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+      if (ret)
+	  goto cleanup;
 
-  ret=(*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
-  if (ret)
-    goto cleanup;
+      ret = (*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
+      if (ret)
+	  goto cleanup;
 
-  ret=krb5_hmac(hash, &k2, 1, &plaintext, &d1);
-  if (ret)
-    goto cleanup;
+      ret = krb5_hmac(hash, &k2, 1, &plaintext, &d1);
+      if (ret)
+	  goto cleanup;
 
-  if (memcmp(checksum.data, d1.data, hashsize) != 0) {
-    ret=KRB5KRB_AP_ERR_BAD_INTEGRITY;
-    goto cleanup;
-  }
+      if (memcmp(checksum.data, d1.data, hashsize) != 0) {
+	  if (ms_usage == 9) {
+	      /*
+	       * RFC 4757 specifies usage 8 for TGS-REP encrypted
+	       * parts encrypted in a subkey, but the value used by MS
+	       * is actually 9.  We now use 9 to start with, but fall
+	       * back to 8 on failure in case we are communicating
+	       * with a KDC using the value from the RFC.
+	       */
+	      ms_usage = 8;
+	      continue;
+	  }
+	  ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+	  goto cleanup;
+      }
 
+      break;
+  } while (1);
+
   memcpy(output->data, plaintext.data+CONFOUNDERLENGTH,
 	 (plaintext.length-CONFOUNDERLENGTH));
   output->length=plaintext.length-CONFOUNDERLENGTH;

Modified: branches/krb5-1-7/src/lib/crypto/t_encrypt.c
===================================================================
--- branches/krb5-1-7/src/lib/crypto/t_encrypt.c	2009-05-24 22:50:44 UTC (rev 22373)
+++ branches/krb5-1-7/src/lib/crypto/t_encrypt.c	2009-05-24 22:50:58 UTC (rev 22374)
@@ -47,14 +47,17 @@
   0
 };
 
-#define test(msg, exp) \
-printf ("%s: . . . ", msg); \
-retval = (exp);\
-if( retval) { \
-  printf( "Failed: %s\n", error_message(retval)); \
-  abort(); \
-} else printf ("OK\n");
-  
+static void
+test(const char *msg, krb5_error_code retval)
+{
+    printf("%s: . . . ", msg);
+    if (retval) {
+	printf("Failed: %s\n", error_message(retval));
+	abort();
+    } else
+	printf("OK\n");
+}
+
 static int compare_results(krb5_data *d1, krb5_data *d2)
 {
     if (d1->length != d2->length) {
@@ -186,6 +189,21 @@
     krb5_free_keyblock (context, key);
   }
 
+  /* Test the RC4 decrypt fallback from key usage 9 to 8. */
+  test ("Initializing an RC4 keyblock",
+	krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &key));
+  test ("Generating random RC4 key",
+	krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, key));
+  enc_out.ciphertext = out;
+  krb5_c_encrypt_length (context, key->enctype, in.length, &len);
+  enc_out.ciphertext.length = len;
+  check.length = 2048;
+  test ("Encrypting with RC4 key usage 8",
+	krb5_c_encrypt (context, key, 8, 0, &in, &enc_out));
+  test ("Decrypting with RC4 key usage 9",
+	krb5_c_decrypt (context, key, 9, 0, &enc_out, &check));
+  test ("Comparing", compare_results (&in, &check));
+
   free(out.data);
   free(out2.data);
   free(check.data);

Modified: branches/krb5-1-7/src/lib/krb5/krb/send_tgs.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/send_tgs.c	2009-05-24 22:50:44 UTC (rev 22373)
+++ branches/krb5-1-7/src/lib/krb5/krb/send_tgs.c	2009-05-24 22:50:58 UTC (rev 22374)
@@ -68,6 +68,8 @@
     case ENCTYPE_DES_CBC_CRC:
     case ENCTYPE_DES_CBC_MD4:
     case ENCTYPE_DES_CBC_MD5:
+    case ENCTYPE_ARCFOUR_HMAC:
+    case ENCTYPE_ARCFOUR_HMAC_EXP:
 	cksumtype = context->kdc_req_sumtype;
 	break;
     default:




More information about the cvs-krb5 mailing list