svn rev #24485: trunk/src/lib/gssapi/krb5/

ghudson@MIT.EDU ghudson at MIT.EDU
Tue Oct 26 13:18:22 EDT 2010


http://src.mit.edu/fisheye/changelog/krb5/?cs=24485
Commit By: ghudson
Log Message:
ticket: 6770

Add a kg_encrypt_inplace() utility function to the krb5 GSS mech, and
use it where we do in-place encryption of checksums in the non-CFX
seal tokens with raw DES enctypes.  Avoids a harmless but incorrect
in-place memcpy().



Changed Files:
U   trunk/src/lib/gssapi/krb5/gssapiP_krb5.h
U   trunk/src/lib/gssapi/krb5/k5seal.c
U   trunk/src/lib/gssapi/krb5/k5sealiov.c
U   trunk/src/lib/gssapi/krb5/k5unseal.c
U   trunk/src/lib/gssapi/krb5/k5unsealiov.c
U   trunk/src/lib/gssapi/krb5/util_crypt.c
Modified: trunk/src/lib/gssapi/krb5/gssapiP_krb5.h
===================================================================
--- trunk/src/lib/gssapi/krb5/gssapiP_krb5.h	2010-10-26 16:41:38 UTC (rev 24484)
+++ trunk/src/lib/gssapi/krb5/gssapiP_krb5.h	2010-10-26 17:18:22 UTC (rev 24485)
@@ -305,6 +305,12 @@
                             krb5_pointer out,
                             unsigned int length);
 
+/* Encrypt length bytes at ptr in place, with the given key and usage.  If
+ * iv is not NULL, use it as the cipher state. */
+krb5_error_code kg_encrypt_inplace(krb5_context context, krb5_key key,
+                                   int usage, krb5_pointer iv,
+                                   krb5_pointer ptr, unsigned int length);
+
 krb5_error_code kg_encrypt_iov (krb5_context context,
                                 int proto, int dce_style,
                                 size_t ec, size_t rrc,

Modified: trunk/src/lib/gssapi/krb5/k5seal.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5seal.c	2010-10-26 16:41:38 UTC (rev 24484)
+++ trunk/src/lib/gssapi/krb5/k5seal.c	2010-10-26 17:18:22 UTC (rev 24485)
@@ -211,10 +211,11 @@
     case SGN_ALG_DES_MAC_MD5:
     case 3:
 
-        if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL,
-                               (g_OID_equal(oid, gss_mech_krb5_old) ?
-                                seq->keyblock.contents : NULL),
-                               md5cksum.contents, md5cksum.contents, 16))) {
+        code = kg_encrypt_inplace(context, seq, KG_USAGE_SEAL,
+                                  (g_OID_equal(oid, gss_mech_krb5_old) ?
+                                   seq->keyblock.contents : NULL),
+                                  md5cksum.contents, 16);
+        if (code) {
             krb5_free_checksum_contents(context, &md5cksum);
             xfree (plain);
             xfree(t);

Modified: trunk/src/lib/gssapi/krb5/k5sealiov.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5sealiov.c	2010-10-26 16:41:38 UTC (rev 24484)
+++ trunk/src/lib/gssapi/krb5/k5sealiov.c	2010-10-26 17:18:22 UTC (rev 24485)
@@ -192,10 +192,11 @@
     switch (ctx->signalg) {
     case SGN_ALG_DES_MAC_MD5:
     case SGN_ALG_3:
-        code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
-                          (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
-                           ctx->seq->keyblock.contents : NULL),
-                          md5cksum.contents, md5cksum.contents, 16);
+        code = kg_encrypt_inplace(context, ctx->seq, KG_USAGE_SEAL,
+                                  (g_OID_equal(ctx->mech_used,
+                                               gss_mech_krb5_old) ?
+                                   ctx->seq->keyblock.contents : NULL),
+                                  md5cksum.contents, 16);
         if (code != 0)
             goto cleanup;
 

Modified: trunk/src/lib/gssapi/krb5/k5unseal.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5unseal.c	2010-10-26 16:41:38 UTC (rev 24484)
+++ trunk/src/lib/gssapi/krb5/k5unseal.c	2010-10-26 17:18:22 UTC (rev 24485)
@@ -298,10 +298,12 @@
             return(GSS_S_FAILURE);
         }
 
-        if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
-                               (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
-                                ctx->seq->keyblock.contents : NULL),
-                               md5cksum.contents, md5cksum.contents, 16))) {
+        code = kg_encrypt_inplace(context, ctx->seq, KG_USAGE_SEAL,
+                                  (g_OID_equal(ctx->mech_used,
+                                               gss_mech_krb5_old) ?
+                                   ctx->seq->keyblock.contents : NULL),
+                                  md5cksum.contents, 16);
+        if (code) {
             krb5_free_checksum_contents(context, &md5cksum);
             if (toktype == KG_TOK_SEAL_MSG)
                 xfree(token.value);

Modified: trunk/src/lib/gssapi/krb5/k5unsealiov.c
===================================================================
--- trunk/src/lib/gssapi/krb5/k5unsealiov.c	2010-10-26 16:41:38 UTC (rev 24484)
+++ trunk/src/lib/gssapi/krb5/k5unsealiov.c	2010-10-26 17:18:22 UTC (rev 24485)
@@ -228,10 +228,11 @@
     switch (signalg) {
     case SGN_ALG_DES_MAC_MD5:
     case SGN_ALG_3:
-        code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
-                          (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
-                           ctx->seq->keyblock.contents : NULL),
-                          md5cksum.contents, md5cksum.contents, 16);
+        code = kg_encrypt_inplace(context, ctx->seq, KG_USAGE_SEAL,
+                                  (g_OID_equal(ctx->mech_used,
+                                               gss_mech_krb5_old) ?
+                                   ctx->seq->keyblock.contents : NULL),
+                                  md5cksum.contents, 16);
         if (code != 0) {
             retval = GSS_S_FAILURE;
             goto cleanup;

Modified: trunk/src/lib/gssapi/krb5/util_crypt.c
===================================================================
--- trunk/src/lib/gssapi/krb5/util_crypt.c	2010-10-26 16:41:38 UTC (rev 24484)
+++ trunk/src/lib/gssapi/krb5/util_crypt.c	2010-10-26 17:18:22 UTC (rev 24485)
@@ -206,42 +206,79 @@
     return(krb5_c_random_make_octets(context, &lrandom));
 }
 
+/* Set *data_out to a krb5_data structure containing iv, or to NULL if iv is
+ * NULL. */
+static krb5_error_code
+iv_to_state(krb5_context context, krb5_key key, krb5_pointer iv,
+            krb5_data **data_out)
+{
+    krb5_error_code code;
+    krb5_data *data;
+    size_t blocksize;
+
+    *data_out = NULL;
+    if (iv == NULL)
+        return 0;
+
+    code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
+    if (code)
+        return code;
+
+    data = k5alloc(sizeof(*data), &code);
+    if (data == NULL)
+        return code;
+    code = alloc_data(data, blocksize);
+    if (code) {
+        free(data);
+        return code;
+    }
+    memcpy(data->data, iv, blocksize);
+    *data_out = data;
+    return 0;
+}
+
 krb5_error_code
 kg_encrypt(krb5_context context, krb5_key key, int usage, krb5_pointer iv,
            krb5_const_pointer in, krb5_pointer out, unsigned int length)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd, inputd;
+    krb5_data *state, inputd;
     krb5_enc_data outputd;
 
-    if (iv) {
-        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
-        if (code)
-            return(code);
+    code = iv_to_state(context, key, iv, &state);
+    if (code)
+        return code;
 
-        ivd.length = blocksize;
-        ivd.data = malloc(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
-
     inputd.length = length;
     inputd.data = (char *)in;
 
     outputd.ciphertext.length = length;
     outputd.ciphertext.data = out;
 
-    code = krb5_k_encrypt(context, key, usage, pivd, &inputd, &outputd);
-    if (pivd != NULL)
-        free(pivd->data);
+    code = krb5_k_encrypt(context, key, usage, state, &inputd, &outputd);
+    krb5_free_data(context, state);
     return code;
 }
 
+krb5_error_code
+kg_encrypt_inplace(krb5_context context, krb5_key key, int usage,
+                   krb5_pointer iv, krb5_pointer ptr, unsigned int length)
+{
+    krb5_error_code code;
+    krb5_crypto_iov iov;
+    krb5_data *state;
+
+    code = iv_to_state(context, key, iv, &state);
+    if (code)
+        return code;
+
+    iov.flags = KRB5_CRYPTO_TYPE_DATA;
+    iov.data = make_data((void *)ptr, length);
+    code = krb5_k_encrypt_iov(context, key, usage, state, &iov, 1);
+    krb5_free_data(context, state);
+    return code;
+}
+
 /* length is the length of the cleartext. */
 
 krb5_error_code
@@ -249,25 +286,13 @@
            krb5_const_pointer in, krb5_pointer out, unsigned int length)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd, outputd;
+    krb5_data *state, outputd;
     krb5_enc_data inputd;
 
-    if (iv) {
-        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
-        if (code)
-            return(code);
+    code = iv_to_state(context, key, iv, &state);
+    if (code)
+        return code;
 
-        ivd.length = blocksize;
-        ivd.data = malloc(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
-
     inputd.enctype = ENCTYPE_UNKNOWN;
     inputd.ciphertext.length = length;
     inputd.ciphertext.data = (char *)in;
@@ -275,9 +300,8 @@
     outputd.length = length;
     outputd.data = out;
 
-    code = krb5_k_decrypt(context, key, usage, pivd, &inputd, &outputd);
-    if (pivd != NULL)
-        free(pivd->data);
+    code = krb5_k_decrypt(context, key, usage, state, &inputd, &outputd);
+    krb5_free_data(context, state);
     return code;
 }
 
@@ -499,37 +523,23 @@
                gss_iov_buffer_desc *iov, int iov_count)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd;
-    size_t kiov_count;
+    krb5_data *state;
+    size_t kiov_len;
     krb5_crypto_iov *kiov;
 
-    if (iv) {
-        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
-        if (code)
-            return(code);
+    code = iv_to_state(context, key, iv, &state);
+    if (code)
+        return code;
 
-        ivd.length = blocksize;
-        ivd.data = malloc(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
-
     code = kg_translate_iov(context, proto, dce_style, ec, rrc,
                             key->keyblock.enctype, iov, iov_count,
-                            &kiov, &kiov_count);
+                            &kiov, &kiov_len);
     if (code == 0) {
-        code = krb5_k_encrypt_iov(context, key, usage, pivd, kiov, kiov_count);
+        code = krb5_k_encrypt_iov(context, key, usage, state, kiov, kiov_len);
         free(kiov);
     }
 
-    if (pivd != NULL)
-        free(pivd->data);
-
+    krb5_free_data(context, state);
     return code;
 }
 
@@ -541,37 +551,23 @@
                gss_iov_buffer_desc *iov, int iov_count)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd;
-    size_t kiov_count;
+    krb5_data *state;
+    size_t kiov_len;
     krb5_crypto_iov *kiov;
 
-    if (iv) {
-        code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize);
-        if (code)
-            return(code);
+    code = iv_to_state(context, key, iv, &state);
+    if (code)
+        return code;
 
-        ivd.length = blocksize;
-        ivd.data = malloc(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
-
     code = kg_translate_iov(context, proto, dce_style, ec, rrc,
                             key->keyblock.enctype, iov, iov_count,
-                            &kiov, &kiov_count);
+                            &kiov, &kiov_len);
     if (code == 0) {
-        code = krb5_k_decrypt_iov(context, key, usage, pivd, kiov, kiov_count);
+        code = krb5_k_decrypt_iov(context, key, usage, state, kiov, kiov_len);
         free(kiov);
     }
 
-    if (pivd != NULL)
-        free(pivd->data);
-
+    krb5_free_data(context, state);
     return code;
 }
 
@@ -585,17 +581,17 @@
     krb5_data kd = make_data((char *) kd_data, kd_data_len);
     krb5int_access kaccess;
     krb5_crypto_iov *kiov = NULL;
-    size_t kiov_count = 0;
+    size_t kiov_len = 0;
 
     code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
     if (code)
         return code;
     code = kg_translate_iov(context, 0 /* proto */, 0 /* dce_style */,
                             0 /* ec */, 0 /* rrc */, keyblock->enctype,
-                            iov, iov_count, &kiov, &kiov_count);
+                            iov, iov_count, &kiov, &kiov_len);
     if (code)
         return code;
-    code = (*kaccess.arcfour_gsscrypt)(keyblock, usage, &kd, kiov, kiov_count);
+    code = (*kaccess.arcfour_gsscrypt)(keyblock, usage, &kd, kiov, kiov_len);
     free(kiov);
     return code;
 }




More information about the cvs-krb5 mailing list