summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/gssapi/krb5
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-09-20 23:18:34 -0700
committerAndrew Bartlett <abartlet@samba.org>2009-11-13 23:19:05 +1100
commit5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094 (patch)
tree82c3416f2211df07d5fe1e58ee6639f09e465a60 /source4/heimdal/lib/gssapi/krb5
parent12205347163b55e79651921c6858c4d04e1faa51 (diff)
downloadsamba-5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094.tar.gz
samba-5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094.tar.bz2
samba-5bc87c14a1f5b45ed86e7ff9663f5f0aa2f70094.zip
s4:heimdal: import lorikeet-heimdal-200909210500 (commit 290db8d23647a27c39b97c189a0b2ef6ec21ca69)
Diffstat (limited to 'source4/heimdal/lib/gssapi/krb5')
-rw-r--r--source4/heimdal/lib/gssapi/krb5/8003.c40
-rw-r--r--source4/heimdal/lib/gssapi/krb5/aeap.c6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/arcfour.c70
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/cfx.c380
-rw-r--r--source4/heimdal/lib/gssapi/krb5/creds.c1
-rw-r--r--source4/heimdal/lib/gssapi/krb5/decapsulate.c8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c1
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c27
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h5
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c17
-rw-r--r--source4/heimdal/lib/gssapi/krb5/prf.c1
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c61
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c39
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c45
14 files changed, 473 insertions, 228 deletions
diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c
index a6f0165e72..2c53d67003 100644
--- a/source4/heimdal/lib/gssapi/krb5/8003.c
+++ b/source4/heimdal/lib/gssapi/krb5/8003.c
@@ -74,32 +74,36 @@ hash_input_chan_bindings (const gss_channel_bindings_t b,
u_char *p)
{
u_char num[4];
- MD5_CTX md5;
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
- MD5_Init(&md5);
_gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);
- MD5_Update (&md5, num, sizeof(num));
+ EVP_DigestUpdate(ctx, num, sizeof(num));
_gsskrb5_encode_om_uint32 (b->initiator_address.length, num);
- MD5_Update (&md5, num, sizeof(num));
+ EVP_DigestUpdate(ctx, num, sizeof(num));
if (b->initiator_address.length)
- MD5_Update (&md5,
- b->initiator_address.value,
- b->initiator_address.length);
+ EVP_DigestUpdate(ctx,
+ b->initiator_address.value,
+ b->initiator_address.length);
_gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);
- MD5_Update (&md5, num, sizeof(num));
+ EVP_DigestUpdate(ctx, num, sizeof(num));
_gsskrb5_encode_om_uint32 (b->acceptor_address.length, num);
- MD5_Update (&md5, num, sizeof(num));
+ EVP_DigestUpdate(ctx, num, sizeof(num));
if (b->acceptor_address.length)
- MD5_Update (&md5,
- b->acceptor_address.value,
- b->acceptor_address.length);
+ EVP_DigestUpdate(ctx,
+ b->acceptor_address.value,
+ b->acceptor_address.length);
_gsskrb5_encode_om_uint32 (b->application_data.length, num);
- MD5_Update (&md5, num, sizeof(num));
+ EVP_DigestUpdate(ctx, num, sizeof(num));
if (b->application_data.length)
- MD5_Update (&md5,
- b->application_data.value,
- b->application_data.length);
- MD5_Final (p, &md5);
+ EVP_DigestUpdate(ctx,
+ b->application_data.value,
+ b->application_data.length);
+ EVP_DigestFinal_ex(ctx, p, NULL);
+ EVP_MD_CTX_destroy(ctx);
+
return 0;
}
@@ -204,7 +208,7 @@ _gsskrb5_verify_8003_checksum(
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
- if(memcmp(hash, p, sizeof(hash)) != 0) {
+ if(ct_memcmp(hash, p, sizeof(hash)) != 0) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c
index 38a5ac2dbe..f1aee4bbbf 100644
--- a/source4/heimdal/lib/gssapi/krb5/aeap.c
+++ b/source4/heimdal/lib/gssapi/krb5/aeap.c
@@ -35,7 +35,7 @@
#include <roken.h>
-OM_uint32 GSSAPI_LIB_FUNCTION
+OM_uint32
_gk_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -57,7 +57,7 @@ _gk_wrap_iov(OM_uint32 * minor_status,
return GSS_S_FAILURE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+OM_uint32
_gk_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
@@ -77,7 +77,7 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+OM_uint32
_gk_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c
index e7331b0119..dc59e997bd 100644
--- a/source4/heimdal/lib/gssapi/krb5/arcfour.c
+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c
@@ -173,7 +173,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
int32_t seq_number;
size_t len, total_len;
u_char k6_data[16], *p0, *p;
- RC4_KEY rc4_key;
+ EVP_CIPHER_CTX rc4_key;
_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
@@ -235,10 +235,11 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);
- RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
- RC4 (&rc4_key, 8, p, p);
-
- memset(&rc4_key, 0, sizeof(rc4_key));
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+
memset(k6_data, 0, sizeof(k6_data));
*minor_status = 0;
@@ -300,19 +301,20 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
return GSS_S_FAILURE;
}
- cmp = memcmp(cksum_data, p + 8, 8);
+ cmp = ct_memcmp(cksum_data, p + 8, 8);
if (cmp) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
{
- RC4_KEY rc4_key;
+ EVP_CIPHER_CTX rc4_key;
- RC4_set_key (&rc4_key, sizeof(k6_data), (void*)k6_data);
- RC4 (&rc4_key, 8, p, SND_SEQ);
-
- memset(&rc4_key, 0, sizeof(rc4_key));
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
+ EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+
memset(k6_data, 0, sizeof(k6_data));
}
@@ -459,12 +461,12 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
if(conf_req_flag) {
- RC4_KEY rc4_key;
-
- RC4_set_key (&rc4_key, sizeof(k6_data), (void *)k6_data);
- /* XXX ? */
- RC4 (&rc4_key, 8 + datalen, p0 + 24, p0 + 24); /* Confounder + data */
- memset(&rc4_key, 0, sizeof(rc4_key));
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
}
memset(k6_data, 0, sizeof(k6_data));
@@ -478,11 +480,12 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
}
{
- RC4_KEY rc4_key;
+ EVP_CIPHER_CTX rc4_key;
- RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
- RC4 (&rc4_key, 8, p0 + 8, p0 + 8); /* SND_SEQ */
- memset(&rc4_key, 0, sizeof(rc4_key));
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
@@ -577,11 +580,12 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
}
{
- RC4_KEY rc4_key;
+ EVP_CIPHER_CTX rc4_key;
- RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
- RC4 (&rc4_key, 8, p0 + 8, SND_SEQ); /* SND_SEQ */
- memset(&rc4_key, 0, sizeof(rc4_key));
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
@@ -624,13 +628,13 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
output_message_buffer->length = datalen;
if(conf_flag) {
- RC4_KEY rc4_key;
-
- RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
- RC4 (&rc4_key, 8, p0 + 24, Confounder); /* Confounder */
- RC4 (&rc4_key, datalen, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
- output_message_buffer->value);
- memset(&rc4_key, 0, sizeof(rc4_key));
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
+ EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
} else {
memcpy(Confounder, p0 + 24, 8); /* Confounder */
memcpy(output_message_buffer->value,
@@ -662,7 +666,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
- cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
+ cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
if (cmp) {
_gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = 0;
diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c
index 7cc7ee1e74..1a6e975279 100755
--- a/source4/heimdal/lib/gssapi/krb5/cfx.c
+++ b/source4/heimdal/lib/gssapi/krb5/cfx.c
@@ -213,8 +213,8 @@ _gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
return NULL;
}
-static OM_uint32
-allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
+OM_uint32
+_gk_allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
{
if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) {
if (buffer->buffer.length == size)
@@ -234,6 +234,43 @@ allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t siz
}
+OM_uint32
+_gk_verify_buffers(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ const gss_iov_buffer_desc *header,
+ const gss_iov_buffer_desc *padding,
+ const gss_iov_buffer_desc *trailer)
+{
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (IS_DCE_STYLE(ctx)) {
+ /*
+ * In DCE style mode we reject having a padding or trailer buffer
+ */
+ if (padding) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ if (trailer) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ /*
+ * In non-DCE style mode we require having a padding buffer
+ */
+ if (padding == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
OM_uint32
_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
@@ -248,44 +285,99 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
gss_iov_buffer_desc *header, *trailer, *padding;
size_t gsshsize, k5hsize;
size_t gsstsize, k5tsize;
- size_t i, padlength, rrc = 0, ec = 0;
+ size_t i, rrc = 0, ec = 0;
gss_cfx_wrap_token token;
krb5_error_code ret;
int32_t seq_number;
unsigned usage;
krb5_crypto_iov *data = NULL;
- int paddingoffset = 0;
-
+
header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
if (header == NULL) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength);
-
padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
- if (padlength != 0 && padding == NULL) {
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
+ if (padding != NULL) {
+ padding->buffer.length = 0;
}
trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
if (conf_req_flag) {
- ec = padlength;
+ size_t k5psize = 0;
+ size_t k5pbase = 0;
+ size_t k5bsize = 0;
+ size_t size = 0;
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ size += iov[i].buffer.length;
+ break;
+ default:
+ break;
+ }
+ }
- gsshsize = k5hsize + sizeof(*token);
- gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */
+ size += sizeof(gss_cfx_wrap_token_desc);
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_HEADER,
+ &k5hsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_TRAILER,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_PADDING,
+ &k5pbase);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ if (k5pbase > 1) {
+ k5psize = k5pbase - (size % k5pbase);
+ } else {
+ k5psize = 0;
+ }
+
+ if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
+ *minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
+ &k5bsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+ ec = k5bsize;
+ } else {
+ ec = k5psize;
+ }
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
+ gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
} else {
+ if (IS_DCE_STYLE(ctx)) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize);
+ k5hsize = 0;
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_CHECKSUM,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
- gsshsize = sizeof(*token);
+ gsshsize = sizeof(gss_cfx_wrap_token_desc);
gsstsize = k5tsize;
}
@@ -294,19 +386,13 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
*/
if (trailer == NULL) {
- /* conf_req_flag=0 doesn't support DCE_STYLE */
- if (conf_req_flag == 0) {
- *minor_status = EINVAL;
- major_status = GSS_S_FAILURE;
- goto failure;
- }
rrc = gsstsize;
if (IS_DCE_STYLE(ctx))
rrc -= ec;
gsshsize += gsstsize;
gsstsize = 0;
} else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
- major_status = allocate_buffer(minor_status, trailer, gsstsize);
+ major_status = _gk_allocate_buffer(minor_status, trailer, gsstsize);
if (major_status)
goto failure;
} else if (trailer->buffer.length < gsstsize) {
@@ -321,7 +407,7 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
*/
if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
- major_status = allocate_buffer(minor_status, header, gsshsize);
+ major_status = _gk_allocate_buffer(minor_status, header, gsshsize);
if (major_status != GSS_S_COMPLETE)
goto failure;
} else if (header->buffer.length < gsshsize) {
@@ -352,8 +438,8 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
* used to encode the size (in bytes) of the random filler.
*/
token->Flags |= CFXSealed;
- token->EC[0] = (padlength >> 8) & 0xFF;
- token->EC[1] = (padlength >> 0) & 0xFF;
+ token->EC[0] = (ec >> 8) & 0xFF;
+ token->EC[1] = (ec >> 0) & 0xFF;
} else {
/*
@@ -404,15 +490,15 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
/*
plain packet:
- {"header" | encrypt(plaintext-data | padding | E"header")}
+ {"header" | encrypt(plaintext-data | ec-padding | E"header")}
Expanded, this is with with RRC = 0:
- {"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer }
+ {"header" | krb5-header | plaintext-data | ec-padding | E"header" | krb5-trailer }
- In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer)
+ In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(ec-padding | E"header" | krb5-trailer)
- {"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
+ {"header" | ec-padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
*/
i = 0;
@@ -425,10 +511,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
case GSS_IOV_BUFFER_TYPE_DATA:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
- case GSS_IOV_BUFFER_TYPE_PADDING:
- data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
- paddingoffset = i;
- break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
break;
@@ -446,8 +528,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
* ciphertext.
*/
- /* XXX KRB5_CRYPTO_TYPE_PADDING */
-
/* encrypted CFX header in trailer (or after the header if in
DCE mode). Copy in header into E"header"
*/
@@ -455,15 +535,16 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
if (trailer)
data[i].data.data = trailer->buffer.value;
else
- data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+ data[i].data.data = ((uint8_t *)header->buffer.value) + sizeof(*token);
- data[i].data.length = sizeof(*token);
- memcpy(data[i].data.data, token, sizeof(*token));
+ data[i].data.length = ec + sizeof(*token);
+ memset(data[i].data.data, 0xFF, ec);
+ memcpy(((uint8_t *)data[i].data.data) + ec, token, sizeof(*token));
i++;
/* Kerberos trailer comes after the gss trailer */
data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
- data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + ec + sizeof(*token);
data[i].data.length = k5tsize;
i++;
@@ -479,9 +560,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
token->RRC[1] = (rrc >> 0) & 0xFF;
}
- if (paddingoffset)
- padding->buffer.length = data[paddingoffset].data.length;
-
} else {
/*
plain packet:
@@ -495,7 +573,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
for (i = 0; i < iov_count; i++) {
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
- case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
@@ -511,12 +588,17 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
data[i].data.data = header->buffer.value;
- data[i].data.length = header->buffer.length;
+ data[i].data.length = sizeof(gss_cfx_wrap_token_desc);
i++;
data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
- data[i].data.data = trailer->buffer.value;
- data[i].data.length = trailer->buffer.length;
+ if (trailer) {
+ data[i].data.data = trailer->buffer.value;
+ } else {
+ data[i].data.data = (uint8_t *)header->buffer.value +
+ sizeof(gss_cfx_wrap_token_desc);
+ }
+ data[i].data.length = k5tsize;
i++;
ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
@@ -526,8 +608,13 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
goto failure;
}
- token->EC[0] = (trailer->buffer.length >> 8) & 0xFF;
- token->EC[1] = (trailer->buffer.length >> 0) & 0xFF;
+ if (rrc) {
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+ }
+
+ token->EC[0] = (k5tsize >> 8) & 0xFF;
+ token->EC[1] = (k5tsize >> 0) & 0xFF;
}
if (conf_state != NULL)
@@ -606,7 +693,7 @@ unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int
GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
{
- memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip));
+ memcpy(q, iov[i].buffer.value, min(iov[i].buffer.length, skip));
if (iov[i].buffer.length > skip)
break;
skip -= iov[i].buffer.length;
@@ -627,7 +714,7 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
int iov_count)
{
OM_uint32 seq_number_lo, seq_number_hi, major_status, junk;
- gss_iov_buffer_desc *header, *trailer;
+ gss_iov_buffer_desc *header, *trailer, *padding;
gss_cfx_wrap_token token, ttoken;
u_char token_flags;
krb5_error_code ret;
@@ -647,8 +734,19 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
if (header->buffer.length < sizeof(*token)) /* we check exact below */
return GSS_S_DEFECTIVE_TOKEN;
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ if (padding != NULL && padding->buffer.length != 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
token = (gss_cfx_wrap_token)header->buffer.value;
if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04)
@@ -730,14 +828,16 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
size_t gsstsize = k5tsize + sizeof(*token);
size_t gsshsize = k5hsize + sizeof(*token);
- if (IS_DCE_STYLE(ctx))
- gsstsize += ec;
- gsshsize += gsstsize;
-
if (rrc != gsstsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
}
+
+ if (IS_DCE_STYLE(ctx))
+ gsstsize += ec;
+
+ gsshsize += gsstsize;
+
if (header->buffer.length != gsshsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
@@ -764,7 +864,6 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
for (j = 0; j < iov_count; i++, j++) {
switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
- case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
@@ -782,17 +881,20 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
DCE mode). Copy in header into E"header"
*/
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
- if (trailer)
+ if (trailer) {
data[i].data.data = trailer->buffer.value;
- else
- data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
- data[i].data.length = sizeof(*token);
- ttoken = (gss_cfx_wrap_token)data[i].data.data;
+ } else {
+ data[i].data.data = ((uint8_t *)header->buffer.value) +
+ header->buffer.length - k5hsize - k5tsize - ec- sizeof(*token);
+ }
+
+ data[i].data.length = ec + sizeof(*token);
+ ttoken = (gss_cfx_wrap_token)(((uint8_t *)data[i].data.data) + ec);
i++;
/* Kerberos trailer comes after the gss trailer */
data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
- data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + ec + sizeof(*token);
data[i].data.length = k5tsize;
i++;
@@ -807,34 +909,42 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
ttoken->RRC[1] = token->RRC[1];
/* Check the integrity of the header */
- if (memcmp(ttoken, token, sizeof(*token)) != 0) {
+ if (ct_memcmp(ttoken, token, sizeof(*token)) != 0) {
major_status = GSS_S_BAD_MIC;
goto failure;
}
} else {
- /* Check RRC */
- if (rrc != 0) {
- *minor_status = EINVAL;
- major_status = GSS_S_FAILURE;
- goto failure;
- }
+ size_t gsstsize = ec;
+ size_t gsshsize = sizeof(*token);
if (trailer == NULL) {
+ /* Check RRC */
+ if (rrc != gsstsize) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ gsshsize += gsstsize;
+ gsstsize = 0;
+ } else if (trailer->buffer.length != gsstsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (rrc != 0) {
+ /* Check RRC */
*minor_status = EINVAL;
major_status = GSS_S_FAILURE;
goto failure;
}
- if (trailer->buffer.length != ec) {
- *minor_status = EINVAL;
- major_status = GSS_S_FAILURE;
+ if (header->buffer.length != gsshsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
}
for (i = 0; i < iov_count; i++) {
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
- case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
@@ -850,12 +960,17 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
data[i].data.data = header->buffer.value;
- data[i].data.length = header->buffer.length;
+ data[i].data.length = sizeof(*token);
i++;
data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
- data[i].data.data = trailer->buffer.value;
- data[i].data.length = trailer->buffer.length;
+ if (trailer) {
+ data[i].data.data = trailer->buffer.value;
+ } else {
+ data[i].data.data = (uint8_t *)header->buffer.value +
+ sizeof(*token);
+ }
+ data[i].data.length = ec;
i++;
token = (gss_cfx_wrap_token)header->buffer.value;
@@ -900,9 +1015,16 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
+ OM_uint32 major_status;
size_t size;
int i;
- size_t *padding = NULL;
+ gss_iov_buffer_desc *header = NULL;
+ gss_iov_buffer_desc *padding = NULL;
+ gss_iov_buffer_desc *trailer = NULL;
+ size_t gsshsize = 0;
+ size_t gsstsize = 0;
+ size_t k5hsize = 0;
+ size_t k5tsize = 0;
GSSAPI_KRB5_INIT (&context);
*minor_status = 0;
@@ -915,21 +1037,25 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_HEADER:
- *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length);
- if (*minor_status)
+ if (header != NULL) {
+ *minor_status = 0;
return GSS_S_FAILURE;
+ }
+ header = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_TRAILER:
- *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length);
- if (*minor_status)
+ if (trailer != NULL) {
+ *minor_status = 0;
return GSS_S_FAILURE;
+ }
+ trailer = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_PADDING:
if (padding != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
- padding = &iov[i].buffer.length;
+ padding = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
break;
@@ -938,15 +1064,83 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
}
+
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ if (conf_req_flag) {
+ size_t k5psize = 0;
+ size_t k5pbase = 0;
+ size_t k5bsize = 0;
+ size_t ec = 0;
+
+ size += sizeof(gss_cfx_wrap_token_desc);
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_HEADER,
+ &k5hsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_TRAILER,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_PADDING,
+ &k5pbase);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ if (k5pbase > 1) {
+ k5psize = k5pbase - (size % k5pbase);
+ } else {
+ k5psize = 0;
+ }
+
+ if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
+ *minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
+ &k5bsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ ec = k5bsize;
+ } else {
+ ec = k5psize;
+ }
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
+ gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
+ } else {
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_CHECKSUM,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc);
+ gsstsize = k5tsize;
+ }
+
+ if (trailer != NULL) {
+ trailer->buffer.length = gsstsize;
+ } else {
+ gsshsize += gsstsize;
+ }
+
+ header->buffer.length = gsshsize;
+
if (padding) {
- size_t pad;
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad);
- if (pad > 1) {
- *padding = pad - (size % pad);
- if (*padding == pad)
- *padding = 0;
- } else
- *padding = 0;
+ /* padding is done via EC and is contained in the header or trailer */
+ padding->buffer.length = 0;
+ }
+
+ if (conf_state) {
+ *conf_state = conf_req_flag;
}
return GSS_S_COMPLETE;
@@ -1294,7 +1488,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
((gss_cfx_wrap_token)p)->RRC[1] = token->RRC[1];
/* Check the integrity of the header */
- if (memcmp(p, token, sizeof(*token)) != 0) {
+ if (ct_memcmp(p, token, sizeof(*token)) != 0) {
krb5_data_free(&data);
return GSS_S_BAD_MIC;
}
@@ -1496,7 +1690,7 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
return GSS_S_DEFECTIVE_TOKEN;
}
- if (memcmp(token->Filler, "\xff\xff\xff\xff\xff", 5) != 0) {
+ if (ct_memcmp(token->Filler, "\xff\xff\xff\xff\xff", 5) != 0) {
return GSS_S_DEFECTIVE_TOKEN;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/creds.c b/source4/heimdal/lib/gssapi/krb5/creds.c
index 68cb766bc3..fd40617040 100644
--- a/source4/heimdal/lib/gssapi/krb5/creds.c
+++ b/source4/heimdal/lib/gssapi/krb5/creds.c
@@ -250,5 +250,6 @@ _gsskrb5_import_cred(OM_uint32 * minor_status,
handle->cred_flags = flags;
*cred_handle = (gss_cred_id_t)handle;
+
return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
index 7ccf0b0f79..640c064d0b 100644
--- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c
+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
@@ -80,9 +80,9 @@ _gssapi_verify_mech_header(u_char **str,
if (mech_len != mech->length)
return GSS_S_BAD_MECH;
- if (memcmp(p,
- mech->elements,
- mech->length) != 0)
+ if (ct_memcmp(p,
+ mech->elements,
+ mech->length) != 0)
return GSS_S_BAD_MECH;
p += mech_len;
*str = rk_UNCONST(p);
@@ -108,7 +108,7 @@ _gsskrb5_verify_header(u_char **str,
if (len < 2)
return GSS_S_DEFECTIVE_TOKEN;
- if (memcmp (*str, type, 2) != 0)
+ if (ct_memcmp (*str, type, 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
*str += 2;
diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index fc835bd845..fd81f3ebeb 100644
--- a/source4/heimdal/lib/gssapi/krb5/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -434,6 +434,7 @@ static gssapi_mech_interface_desc krb5_mech = {
GMI_VERSION,
"kerberos 5",
{9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
+ 0,
_gsskrb5_acquire_cred,
_gsskrb5_release_cred,
_gsskrb5_init_sec_context,
diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c
index ad3009c73e..f3f7fff8ae 100644
--- a/source4/heimdal/lib/gssapi/krb5/get_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c
@@ -33,6 +33,8 @@
#include "gsskrb5_locl.h"
+#ifdef HEIM_WEAK_CRYPTO
+
static OM_uint32
mic_des
(OM_uint32 * minor_status,
@@ -45,9 +47,10 @@ mic_des
)
{
u_char *p;
- MD5_CTX md5;
+ EVP_MD_CTX *md5;
u_char hash[16];
DES_key_schedule schedule;
+ EVP_CIPHER_CTX des_ctx;
DES_cblock deskey;
DES_cblock zero;
int32_t seq_number;
@@ -79,10 +82,12 @@ mic_des
p += 16;
/* checksum */
- MD5_Init (&md5);
- MD5_Update (&md5, p - 24, 8);
- MD5_Update (&md5, message_buffer->value, message_buffer->length);
- MD5_Final (hash, &md5);
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
@@ -106,9 +111,10 @@ mic_des
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
- DES_set_key_unchecked (&deskey, &schedule);
- DES_cbc_encrypt ((void *)p, (void *)p, 8,
- &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
krb5_auth_con_setlocalseqnumber (context,
ctx->auth_context,
@@ -121,6 +127,7 @@ mic_des
*minor_status = 0;
return GSS_S_COMPLETE;
}
+#endif
static OM_uint32
mic_des3
@@ -297,8 +304,12 @@ OM_uint32 _gsskrb5_get_mic
switch (keytype) {
case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
ret = mic_des (minor_status, ctx, context, qop_req,
message_buffer, message_token, key);
+#else
+ ret = GSS_S_FAILURE;
+#endif
break;
case KEYTYPE_DES3 :
ret = mic_des3 (minor_status, ctx, context, qop_req,
diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
index aadb80db0d..d91670821a 100644
--- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
+++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
@@ -111,11 +111,6 @@ typedef struct Principal *gsskrb5_name;
extern krb5_keytab _gsskrb5_keytab;
extern HEIMDAL_MUTEX gssapi_keytab_mutex;
-struct gssapi_thr_context {
- HEIMDAL_MUTEX mutex;
- char *error_string;
-};
-
/*
* Prototypes
*/
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index b269d06798..1954c101c7 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -175,20 +175,21 @@ gsskrb5_get_creds(
const gss_name_t target_name,
int use_dns,
OM_uint32 time_req,
- OM_uint32 * time_rec,
- krb5_creds ** cred)
+ OM_uint32 * time_rec)
{
OM_uint32 ret;
krb5_error_code kret;
krb5_creds this_cred;
OM_uint32 lifetime_rec;
- *cred = NULL;
-
if (ctx->target) {
krb5_free_principal(context, ctx->target);
ctx->target = NULL;
}
+ if (ctx->kcred) {
+ krb5_free_creds(context, ctx->kcred);
+ ctx->kcred = NULL;
+ }
ret = _gsskrb5_canon_name(minor_status, context, use_dns,
ctx->source, target_name, &ctx->target);
@@ -214,13 +215,13 @@ gsskrb5_get_creds(
0,
ccache,
&this_cred,
- cred);
+ &ctx->kcred);
if (kret) {
*minor_status = kret;
return GSS_S_FAILURE;
}
- ctx->lifetime = (*cred)->times.endtime;
+ ctx->lifetime = ctx->kcred->times.endtime;
ret = _gsskrb5_lifetime_left(minor_status, context,
ctx->lifetime, &lifetime_rec);
@@ -427,11 +428,11 @@ init_auth
*/
ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
ctx, name, 0, time_req,
- time_rec, &ctx->kcred);
+ time_rec);
if (ret && allow_dns)
ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
ctx, name, 1, time_req,
- time_rec, &ctx->kcred);
+ time_rec);
if (ret)
goto failure;
diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c
index 76ae3b78ed..737ccb6834 100644
--- a/source4/heimdal/lib/gssapi/krb5/prf.c
+++ b/source4/heimdal/lib/gssapi/krb5/prf.c
@@ -132,6 +132,7 @@ _gsskrb5_pseudo_random(OM_uint32 *minor_status,
krb5_data_free(&output);
num++;
}
+ free(input.data);
krb5_crypto_destroy(context, crypto);
diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c
index 20cf952b4e..5e0042e28b 100644
--- a/source4/heimdal/lib/gssapi/krb5/unwrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c
@@ -33,6 +33,8 @@
#include "gsskrb5_locl.h"
+#ifdef HEIM_WEAK_CRYPTO
+
static OM_uint32
unwrap_des
(OM_uint32 * minor_status,
@@ -46,8 +48,9 @@ unwrap_des
{
u_char *p, *seq;
size_t len;
- MD5_CTX md5;
+ EVP_MD_CTX *md5;
u_char hash[16];
+ EVP_CIPHER_CTX des_ctx;
DES_key_schedule schedule;
DES_cblock deskey;
DES_cblock zero;
@@ -98,16 +101,13 @@ unwrap_des
for (i = 0; i < sizeof(deskey); ++i)
deskey[i] ^= 0xf0;
- DES_set_key_unchecked (&deskey, &schedule);
- memset (&zero, 0, sizeof(zero));
- DES_cbc_encrypt ((void *)p,
- (void *)p,
- input_message_buffer->length - len,
- &schedule,
- &zero,
- DES_DECRYPT);
-
- memset (deskey, 0, sizeof(deskey));
+
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
+ EVP_Cipher(&des_ctx, p, p, input_message_buffer->length - len);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+
memset (&schedule, 0, sizeof(schedule));
}
@@ -122,17 +122,19 @@ unwrap_des
return ret;
}
- MD5_Init (&md5);
- MD5_Update (&md5, p - 24, 8);
- MD5_Update (&md5, p, input_message_buffer->length - len);
- MD5_Final (hash, &md5);
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, p, input_message_buffer->length - len);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
- if (memcmp (p - 8, hash, 8) != 0)
+ if (ct_memcmp (p - 8, hash, 8) != 0)
return GSS_S_BAD_MIC;
/* verify sequence number */
@@ -140,9 +142,11 @@ unwrap_des
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 16;
- DES_set_key_unchecked (&deskey, &schedule);
- DES_cbc_encrypt ((void *)p, (void *)p, 8,
- &schedule, (DES_cblock *)hash, DES_DECRYPT);
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@@ -151,9 +155,9 @@ unwrap_des
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
- cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
- cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -180,6 +184,7 @@ unwrap_des
output_message_buffer->length);
return GSS_S_COMPLETE;
}
+#endif
static OM_uint32
unwrap_des3
@@ -224,16 +229,16 @@ unwrap_des3
if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
return GSS_S_BAD_SIG;
p += 2;
- if (memcmp (p, "\x02\x00", 2) == 0) {
+ if (ct_memcmp (p, "\x02\x00", 2) == 0) {
cstate = 1;
- } else if (memcmp (p, "\xff\xff", 2) == 0) {
+ } else if (ct_memcmp (p, "\xff\xff", 2) == 0) {
cstate = 0;
} else
return GSS_S_BAD_MIC;
p += 2;
if(conf_state != NULL)
*conf_state = cstate;
- if (memcmp (p, "\xff\xff", 2) != 0)
+ if (ct_memcmp (p, "\xff\xff", 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
p += 2;
p += 28;
@@ -314,9 +319,9 @@ unwrap_des3
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
- cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
- cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
krb5_data_free (&seq_data);
if (cmp != 0) {
@@ -414,9 +419,13 @@ OM_uint32 _gsskrb5_unwrap
switch (keytype) {
case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
ret = unwrap_des (minor_status, ctx,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
+#else
+ ret = GSS_S_FAILURE;
+#endif
break;
case KEYTYPE_DES3 :
ret = unwrap_des3 (minor_status, ctx, context,
diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index c7e16e81f7..0b5b6e1ccd 100644
--- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -33,6 +33,8 @@
#include "gsskrb5_locl.h"
+#ifdef HEIM_WEAK_CRYPTO
+
static OM_uint32
verify_mic_des
(OM_uint32 * minor_status,
@@ -46,9 +48,10 @@ verify_mic_des
)
{
u_char *p;
- MD5_CTX md5;
+ EVP_MD_CTX *md5;
u_char hash[16], *seq;
DES_key_schedule schedule;
+ EVP_CIPHER_CTX des_ctx;
DES_cblock zero;
DES_cblock deskey;
uint32_t seq_number;
@@ -72,11 +75,12 @@ verify_mic_des
p += 16;
/* verify checksum */
- MD5_Init (&md5);
- MD5_Update (&md5, p - 24, 8);
- MD5_Update (&md5, message_buffer->value,
- message_buffer->length);
- MD5_Final (hash, &md5);
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
@@ -84,7 +88,7 @@ verify_mic_des
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
- if (memcmp (p - 8, hash, 8) != 0) {
+ if (ct_memcmp (p - 8, hash, 8) != 0) {
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
return GSS_S_BAD_MIC;
@@ -95,9 +99,11 @@ verify_mic_des
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 16;
- DES_set_key_unchecked (&deskey, &schedule);
- DES_cbc_encrypt ((void *)p, (void *)p, 8,
- &schedule, (DES_cblock *)hash, DES_DECRYPT);
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@@ -106,9 +112,9 @@ verify_mic_des
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
- cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
- cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -125,6 +131,7 @@ verify_mic_des
return GSS_S_COMPLETE;
}
+#endif
static OM_uint32
verify_mic_des3
@@ -207,9 +214,9 @@ retry:
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
- cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
- cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
krb5_data_free (&seq_data);
if (cmp != 0) {
@@ -292,9 +299,13 @@ _gsskrb5_verify_mic_internal
krb5_enctype_to_keytype (context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
ret = verify_mic_des (minor_status, ctx, context,
message_buffer, token_buffer, qop_state, key,
type);
+#else
+ ret = GSS_S_FAILURE;
+#endif
break;
case KEYTYPE_DES3 :
ret = verify_mic_des3 (minor_status, ctx, context,
diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c
index 3de13f908f..9078fb3dd7 100644
--- a/source4/heimdal/lib/gssapi/krb5/wrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/wrap.c
@@ -168,7 +168,11 @@ _gsskrb5_wrap_size_limit (
switch (keytype) {
case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
+#else
+ ret = GSS_S_FAILURE;
+#endif
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
@@ -188,6 +192,8 @@ _gsskrb5_wrap_size_limit (
return ret;
}
+#ifdef HEIM_WEAK_CRYPTO
+
static OM_uint32
wrap_des
(OM_uint32 * minor_status,
@@ -202,9 +208,10 @@ wrap_des
)
{
u_char *p;
- MD5_CTX md5;
+ EVP_MD_CTX *md5;
u_char hash[16];
DES_key_schedule schedule;
+ EVP_CIPHER_CTX des_ctx;
DES_cblock deskey;
DES_cblock zero;
int i;
@@ -262,10 +269,12 @@ wrap_des
memset (p + 8 + input_message_buffer->length, padlength, padlength);
/* checksum */
- MD5_Init (&md5);
- MD5_Update (&md5, p - 24, 8);
- MD5_Update (&md5, p, datalen);
- MD5_Final (hash, &md5);
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, p, datalen);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
@@ -289,9 +298,10 @@ wrap_des
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
- DES_set_key_unchecked (&deskey, &schedule);
- DES_cbc_encrypt ((void *)p, (void *)p, 8,
- &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
krb5_auth_con_setlocalseqnumber (context,
ctx->auth_context,
@@ -306,14 +316,11 @@ wrap_des
for (i = 0; i < sizeof(deskey); ++i)
deskey[i] ^= 0xf0;
- DES_set_key_unchecked (&deskey, &schedule);
- memset (&zero, 0, sizeof(zero));
- DES_cbc_encrypt ((void *)p,
- (void *)p,
- datalen,
- &schedule,
- &zero,
- DES_ENCRYPT);
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 1);
+ EVP_Cipher(&des_ctx, p, p, datalen);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
}
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@@ -324,6 +331,8 @@ wrap_des
return GSS_S_COMPLETE;
}
+#endif
+
static OM_uint32
wrap_des3
(OM_uint32 * minor_status,
@@ -552,9 +561,13 @@ OM_uint32 _gsskrb5_wrap
switch (keytype) {
case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
ret = wrap_des (minor_status, ctx, context, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
+#else
+ ret = GSS_S_FAILURE;
+#endif
break;
case KEYTYPE_DES3 :
ret = wrap_des3 (minor_status, ctx, context, conf_req_flag,