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