From 026563966fcd55781651f3ec2de8011bdfa536cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Tue, 19 Dec 2006 18:19:07 +0000 Subject: [PATCH] Implement SEAL. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@19456 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/gssapi/ntlm/crypto.c | 104 +++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 10 deletions(-) diff --git a/lib/gssapi/ntlm/crypto.c b/lib/gssapi/ntlm/crypto.c index fe4648af7..5ebcf9b9a 100644 --- a/lib/gssapi/ntlm/crypto.c +++ b/lib/gssapi/ntlm/crypto.c @@ -102,12 +102,12 @@ OM_uint32 _gss_ntlm_get_mic message_buffer->length, 0); encode_le_uint32(0, &sigature[0]); encode_le_uint32(crc, &sigature[4]); - encode_le_uint32(ctx->crypto.send_seq, &sigature[8]); + encode_le_uint32(ctx->crypto_send.seq, &sigature[8]); - ctx->crypto.send_seq++; + ctx->crypto_send.seq++; encode_le_uint32(1, message_token->value); /* version */ - RC4(&ctx->crypto.key, sizeof(sigature), + RC4(&ctx->crypto_send.key, sizeof(sigature), sigature, ((unsigned char *)message_token->value) + 4); if (RAND_bytes(((unsigned char *)message_token->value) + 4, 4) != 1){ @@ -165,7 +165,7 @@ _gss_ntlm_verify_mic if (num != 1) return GSS_S_BAD_MIC; - RC4(&ctx->crypto.key, sizeof(sigature), + RC4(&ctx->crypto_recv.key, sizeof(sigature), ((unsigned char *)token_buffer->value) + 4, sigature); _krb5_crc_init_table(); @@ -176,9 +176,9 @@ _gss_ntlm_verify_mic if (num != crc) return GSS_S_BAD_MIC; decode_le_uint32(&sigature[8], &num); - if (ctx->crypto.recv_seq != num) + if (ctx->crypto_recv.seq != num) return GSS_S_BAD_MIC; - ctx->crypto.recv_seq++; + ctx->crypto_recv.seq++; return GSS_S_COMPLETE; } else if (ctx->flags & NTLM_NEG_ALWAYS_SIGN) { @@ -216,8 +216,20 @@ _gss_ntlm_wrap_size_limit ( OM_uint32 * max_input_size ) { + ntlm_ctx ctx = (ntlm_ctx)context_handle; + *minor_status = 0; - *max_input_size = 0; + + if(ctx->flags & NTLM_NEG_SEAL) { + + if (req_output_size < 16) + *max_input_size = 0; + else + *max_input_size = req_output_size - 16; + + return GSS_S_COMPLETE; + } + return GSS_S_UNAVAILABLE; } @@ -235,14 +247,50 @@ OM_uint32 _gss_ntlm_wrap gss_buffer_t output_message_buffer ) { + ntlm_ctx ctx = (ntlm_ctx)context_handle; + OM_uint32 ret; + if (minor_status) *minor_status = 0; if (conf_state) *conf_state = 0; - if (output_message_buffer) { - output_message_buffer->length = 0; - output_message_buffer->value = NULL; + if (output_message_buffer == GSS_C_NO_BUFFER) + return GSS_S_FAILURE; + + if(ctx->flags & NTLM_NEG_SEAL) { + gss_buffer_desc trailer; + OM_uint32 junk; + + output_message_buffer->length = input_message_buffer->length + 16; + output_message_buffer->value = malloc(output_message_buffer->length); + if (output_message_buffer->value == NULL) { + output_message_buffer->length = 0; + return GSS_S_FAILURE; + } + + RC4(&ctx->crypto_send.key, input_message_buffer->length, + input_message_buffer->value, output_message_buffer->value); + + ret = _gss_ntlm_get_mic(minor_status, context_handle, + 0, input_message_buffer, + &trailer); + if (ret) { + gss_release_buffer(&junk, output_message_buffer); + return ret; + } + if (trailer.length != 16) { + gss_release_buffer(&junk, output_message_buffer); + gss_release_buffer(&junk, &trailer); + return GSS_S_FAILURE; + } + memcpy(((unsigned char *)output_message_buffer->value) + + input_message_buffer->length, + trailer.value, trailer.length); + gss_release_buffer(&junk, &trailer); + + return GSS_S_COMPLETE; } + return GSS_S_UNAVAILABLE; } @@ -259,6 +307,9 @@ OM_uint32 _gss_ntlm_unwrap gss_qop_t * qop_state ) { + ntlm_ctx ctx = (ntlm_ctx)context_handle; + OM_uint32 ret; + if (minor_status) *minor_status = 0; if (output_message_buffer) { @@ -269,5 +320,38 @@ OM_uint32 _gss_ntlm_unwrap *conf_state = 0; if (qop_state) *qop_state = 0; + + if(ctx->flags & NTLM_NEG_SEAL) { + gss_buffer_desc trailer; + OM_uint32 junk; + + if (input_message_buffer->length < 16) + return GSS_S_BAD_MIC; + + output_message_buffer->length = input_message_buffer->length - 16; + output_message_buffer->value = malloc(output_message_buffer->length); + if (output_message_buffer->value == NULL) { + output_message_buffer->length = 0; + return GSS_S_FAILURE; + } + + RC4(&ctx->crypto_recv.key, output_message_buffer->length, + input_message_buffer->value, output_message_buffer->value); + + trailer.value = ((unsigned char *)input_message_buffer->value) + + output_message_buffer->length; + trailer.length = 16; + + ret = _gss_ntlm_verify_mic(minor_status, context_handle, + output_message_buffer, + &trailer, NULL); + if (ret) { + gss_release_buffer(&junk, output_message_buffer); + return ret; + } + + return GSS_S_COMPLETE; + } + return GSS_S_UNAVAILABLE; }