summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-10-26 17:18:22 +0000
committerGreg Hudson <ghudson@mit.edu>2010-10-26 17:18:22 +0000
commitc079477480c839bd983afd082ac7a7ec51e906ca (patch)
treecf42f68c929df371979ac25250168d2b4502a780 /src/lib/gssapi
parentc18b2675873acaf982878e52f7aee55a156bb646 (diff)
downloadkrb5-c079477480c839bd983afd082ac7a7ec51e906ca.tar.gz
krb5-c079477480c839bd983afd082ac7a7ec51e906ca.tar.xz
krb5-c079477480c839bd983afd082ac7a7ec51e906ca.zip
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(). ticket: 6770 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24485 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h6
-rw-r--r--src/lib/gssapi/krb5/k5seal.c9
-rw-r--r--src/lib/gssapi/krb5/k5sealiov.c9
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c10
-rw-r--r--src/lib/gssapi/krb5/k5unsealiov.c9
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c166
6 files changed, 108 insertions, 101 deletions
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index ce0265234..1cb1c1062 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -305,6 +305,12 @@ krb5_error_code kg_encrypt (krb5_context context,
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,
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index 18c83dfad..46accf1ac 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -211,10 +211,11 @@ make_seal_token_v1 (krb5_context context,
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);
diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c
index c15e4e744..d797ce930 100644
--- a/src/lib/gssapi/krb5/k5sealiov.c
+++ b/src/lib/gssapi/krb5/k5sealiov.c
@@ -192,10 +192,11 @@ make_seal_token_v1_iov(krb5_context context,
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;
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 5fa52feb4..4e9ee7739 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -298,10 +298,12 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
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);
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
index 2be7b82ae..9c821a6fc 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -228,10 +228,11 @@ kg_unseal_v1_iov(krb5_context context,
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;
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index 9699c2656..36c5ef380 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -206,29 +206,48 @@ kg_make_confounder(krb5_context context, krb5_enctype enctype,
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);
-
- 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 = iv_to_state(context, key, iv, &state);
+ if (code)
+ return code;
inputd.length = length;
inputd.data = (char *)in;
@@ -236,9 +255,27 @@ kg_encrypt(krb5_context context, krb5_key key, int usage, krb5_pointer iv,
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;
}
@@ -249,24 +286,12 @@ kg_decrypt(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, 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);
-
- 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 = iv_to_state(context, key, iv, &state);
+ if (code)
+ return code;
inputd.enctype = ENCTYPE_UNKNOWN;
inputd.ciphertext.length = length;
@@ -275,9 +300,8 @@ kg_decrypt(krb5_context context, krb5_key key, int usage, krb5_pointer iv,
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 @@ kg_encrypt_iov(krb5_context context, int proto, int dce_style, size_t ec,
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);
-
- 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 = iv_to_state(context, key, iv, &state);
+ if (code)
+ return code;
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 @@ kg_decrypt_iov(krb5_context context, int proto, int dce_style, size_t ec,
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);
-
- 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 = iv_to_state(context, key, iv, &state);
+ if (code)
+ return code;
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 @@ kg_arcfour_docrypt_iov(krb5_context context, const krb5_keyblock *keyblock,
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;
}