diff options
Diffstat (limited to 'crypto/heimdal/lib/gssapi/verify_mic.c')
-rw-r--r-- | crypto/heimdal/lib/gssapi/verify_mic.c | 95 |
1 files changed, 70 insertions, 25 deletions
diff --git a/crypto/heimdal/lib/gssapi/verify_mic.c b/crypto/heimdal/lib/gssapi/verify_mic.c index 7915fa5..1775860 100644 --- a/crypto/heimdal/lib/gssapi/verify_mic.c +++ b/crypto/heimdal/lib/gssapi/verify_mic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "gssapi_locl.h" -RCSID("$Id: verify_mic.c,v 1.16 2002/05/20 15:14:00 nectar Exp $"); +RCSID("$Id: verify_mic.c,v 1.18.2.2 2003/05/05 18:59:42 lha Exp $"); static OM_uint32 verify_mic_des @@ -42,7 +42,8 @@ verify_mic_des const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, - krb5_keyblock *key + krb5_keyblock *key, + char *type ) { u_char *p; @@ -57,7 +58,7 @@ verify_mic_des p = token_buffer->value; ret = gssapi_krb5_verify_header (&p, token_buffer->length, - "\x01\x01"); + type); if (ret) { *minor_status = 0; return ret; @@ -87,6 +88,7 @@ verify_mic_des if (memcmp (p - 8, hash, 8) != 0) { memset (deskey, 0, sizeof(deskey)); memset (schedule, 0, sizeof(schedule)); + *minor_status = 0; return GSS_S_BAD_MIC; } @@ -112,6 +114,7 @@ verify_mic_des memset (schedule, 0, sizeof(schedule)); if (memcmp (p, seq_data, 8) != 0) { + *minor_status = 0; return GSS_S_BAD_MIC; } @@ -119,6 +122,7 @@ verify_mic_des context_handle->auth_context, ++seq_number); + *minor_status = 0; return GSS_S_COMPLETE; } @@ -129,7 +133,8 @@ verify_mic_des3 const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, - krb5_keyblock *key + krb5_keyblock *key, + char *type ) { u_char *p; @@ -138,14 +143,15 @@ verify_mic_des3 OM_uint32 ret; krb5_crypto crypto; krb5_data seq_data; - int cmp; + int cmp, docompat; Checksum csum; char *tmp; + char ivec[8]; p = token_buffer->value; ret = gssapi_krb5_verify_header (&p, token_buffer->length, - "\x01\x01"); + type); if (ret) { *minor_status = 0; return ret; @@ -167,22 +173,34 @@ verify_mic_des3 } /* verify sequence number */ + docompat = 0; +retry: + if (docompat) + memset(ivec, 0, 8); + else + memcpy(ivec, p + 8, 8); - ret = krb5_decrypt (gssapi_krb5_context, - crypto, - KRB5_KU_USAGE_SEQ, - p, 8, &seq_data); + ret = krb5_decrypt_ivec (gssapi_krb5_context, + crypto, + KRB5_KU_USAGE_SEQ, + p, 8, &seq_data, ivec); if (ret) { - gssapi_krb5_set_error_string (); - krb5_crypto_destroy (gssapi_krb5_context, crypto); - *minor_status = ret; - return GSS_S_FAILURE; + if (docompat++) { + gssapi_krb5_set_error_string (); + krb5_crypto_destroy (gssapi_krb5_context, crypto); + *minor_status = ret; + return GSS_S_FAILURE; + } else + goto retry; } if (seq_data.length != 8) { - krb5_crypto_destroy (gssapi_krb5_context, crypto); krb5_data_free (&seq_data); - return GSS_S_BAD_MIC; + if (docompat++) { + krb5_crypto_destroy (gssapi_krb5_context, crypto); + return GSS_S_BAD_MIC; + } else + goto retry; } krb5_auth_getremoteseqnumber (gssapi_krb5_context, @@ -198,8 +216,11 @@ verify_mic_des3 cmp = memcmp (seq, seq_data.data, seq_data.length); krb5_data_free (&seq_data); if (cmp != 0) { - krb5_crypto_destroy (gssapi_krb5_context, crypto); - return GSS_S_BAD_MIC; + if (docompat++) { + krb5_crypto_destroy (gssapi_krb5_context, crypto); + return GSS_S_BAD_MIC; + } else + goto retry; } /* verify checksum */ @@ -235,24 +256,24 @@ verify_mic_des3 ++seq_number); krb5_crypto_destroy (gssapi_krb5_context, crypto); + *minor_status = 0; return GSS_S_COMPLETE; } OM_uint32 -gss_verify_mic +gss_verify_mic_internal (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, - gss_qop_t * qop_state + gss_qop_t * qop_state, + char * type ) { krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; - if (qop_state != NULL) - *qop_state = GSS_C_QOP_DEFAULT; ret = gss_krb5_get_remotekey(context_handle, &key); if (ret) { gssapi_krb5_set_error_string (); @@ -263,11 +284,13 @@ gss_verify_mic switch (keytype) { case KEYTYPE_DES : ret = verify_mic_des (minor_status, context_handle, - message_buffer, token_buffer, qop_state, key); + message_buffer, token_buffer, qop_state, key, + type); break; case KEYTYPE_DES3 : ret = verify_mic_des3 (minor_status, context_handle, - message_buffer, token_buffer, qop_state, key); + message_buffer, token_buffer, qop_state, key, + type); break; default : *minor_status = KRB5_PROG_ETYPE_NOSUPP; @@ -275,5 +298,27 @@ gss_verify_mic break; } krb5_free_keyblock (gssapi_krb5_context, key); + + return ret; +} + +OM_uint32 +gss_verify_mic + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t message_buffer, + const gss_buffer_t token_buffer, + gss_qop_t * qop_state + ) +{ + OM_uint32 ret; + + if (qop_state != NULL) + *qop_state = GSS_C_QOP_DEFAULT; + + ret = gss_verify_mic_internal(minor_status, context_handle, + message_buffer, token_buffer, + qop_state, "\x01\x01"); + return ret; } |