aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-05-20 02:05:53 +0000
committerGreg Hudson <ghudson@mit.edu>2009-05-20 02:05:53 +0000
commit689473cbbd1fc5a750e0edc8292ad8f6f51e0496 (patch)
tree571fe08cae64439a1be3c00b8984d5c0a681baf3 /src/lib/crypto
parent05c7822d0e5118df745685ab2f9b20fe07dcfb6c (diff)
downloadkrb5-689473cbbd1fc5a750e0edc8292ad8f6f51e0496.zip
krb5-689473cbbd1fc5a750e0edc8292ad8f6f51e0496.tar.gz
krb5-689473cbbd1fc5a750e0edc8292ad8f6f51e0496.tar.bz2
Restore compatibility with KDCs using key usage 8 to encrypt TGS
replies in a subkey, by implementing a fallback in krb5_arcfour_decrypt. ticket: 6490 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22357 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto')
-rw-r--r--src/lib/crypto/arcfour/arcfour.c79
-rw-r--r--src/lib/crypto/t_encrypt.c34
2 files changed, 74 insertions, 39 deletions
diff --git a/src/lib/crypto/arcfour/arcfour.c b/src/lib/crypto/arcfour/arcfour.c
index 4999982..7e527cf 100644
--- a/src/lib/crypto/arcfour/arcfour.c
+++ b/src/lib/crypto/arcfour/arcfour.c
@@ -252,40 +252,57 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
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);
-
- if (key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
- memset(k1.contents+7, 0xab, 9);
+ /* 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;
+
+ 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=(*(enc->decrypt))(&k3, ivec, &ciphertext, &plaintext);
- 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;
- }
+ ret = krb5_hmac(hash, &k1, 1, &checksum, &d3);
+ 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;
+
+ 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));
diff --git a/src/lib/crypto/t_encrypt.c b/src/lib/crypto/t_encrypt.c
index c4ecbde..974dc58 100644
--- a/src/lib/crypto/t_encrypt.c
+++ b/src/lib/crypto/t_encrypt.c
@@ -47,14 +47,17 @@ krb5_enctype interesting_enctypes[] = {
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 @@ main ()
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);