X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=unwrap_iov.c;h=ee2790daddce0bed4869c8d4b925eca8e0322258;hb=31355119edb3a282ab302c05e33e23430af67603;hp=45c4b2508c4fd87cfe7ec49d27ff42e8b2884965;hpb=9fbf196192538e4712b5596790db276b74b7e35a;p=mech_eap.orig diff --git a/unwrap_iov.c b/unwrap_iov.c index 45c4b25..ee2790d 100644 --- a/unwrap_iov.c +++ b/unwrap_iov.c @@ -73,15 +73,17 @@ unwrapToken(OM_uint32 *minor, gss_iov_buffer_t header; gss_iov_buffer_t padding; gss_iov_buffer_t trailer; - unsigned char acceptor_flag; + unsigned char flags; unsigned char *ptr = NULL; - int key_usage; + int keyUsage; size_t rrc, ec; - size_t data_length, assoc_data_length; + size_t dataLen, assocDataLen; uint64_t seqnum; int valid = 0; - krb5_cksumtype cksumtype; int conf_flag = 0; + krb5_context krbContext; + + GSSEAP_KRB_INIT(&krbContext); *minor = 0; @@ -97,34 +99,30 @@ unwrapToken(OM_uint32 *minor, trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); - acceptor_flag = CTX_IS_INITIATOR(ctx) ? TOK_FLAG_SENDER_IS_ACCEPTOR : 0; - key_usage = (toktype == TOK_TYPE_WRAP - ? (!CTX_IS_INITIATOR(ctx) - ? KEY_USAGE_INITIATOR_SEAL - : KEY_USAGE_ACCEPTOR_SEAL) - : (!CTX_IS_INITIATOR(ctx) - ? KEY_USAGE_INITIATOR_SIGN - : KEY_USAGE_ACCEPTOR_SIGN)); + flags = rfc4121Flags(ctx, TRUE); + + if (toktype == TOK_TYPE_WRAP) { + keyUsage = !CTX_IS_INITIATOR(ctx) + ? KEY_USAGE_INITIATOR_SEAL + : KEY_USAGE_ACCEPTOR_SEAL; + } else { + keyUsage = !CTX_IS_INITIATOR(ctx) + ? KEY_USAGE_INITIATOR_SIGN + : KEY_USAGE_ACCEPTOR_SIGN; + } - gssEapIovMessageLength(iov, iov_count, &data_length, &assoc_data_length); + gssEapIovMessageLength(iov, iov_count, &dataLen, &assocDataLen); ptr = (unsigned char *)header->buffer.value; - if (header->buffer.length < 16) { - *minor = 0; + if (header->buffer.length < 16) return GSS_S_DEFECTIVE_TOKEN; - } - - if ((ptr[2] & TOK_FLAG_SENDER_IS_ACCEPTOR) != acceptor_flag) { - return GSS_S_BAD_SIG; - } - if (ptr[2] & TOK_FLAG_ACCEPTOR_SUBKEY) { + if ((ptr[2] & flags) != flags) return GSS_S_BAD_SIG; - } if (toktype == TOK_TYPE_WRAP) { - unsigned int k5_trailerlen; + unsigned int krbTrailerLen; if (load_uint16_be(ptr) != TOK_TYPE_WRAP) goto defective; @@ -135,11 +133,11 @@ unwrapToken(OM_uint32 *minor, rrc = load_uint16_be(ptr + 6); seqnum = load_uint64_be(ptr + 8); - code = krb5_c_crypto_length(ctx->kerberosCtx, - KRB_KEYTYPE(ctx->encryptionKey), + code = krb5_c_crypto_length(krbContext, + ctx->encryptionType, conf_flag ? KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM, - &k5_trailerlen); + &krbTrailerLen); if (code != 0) { *minor = code; return GSS_S_FAILURE; @@ -147,7 +145,7 @@ unwrapToken(OM_uint32 *minor, /* Deal with RRC */ if (trailer == NULL) { - size_t desired_rrc = k5_trailerlen; + size_t desired_rrc = krbTrailerLen; if (conf_flag) { desired_rrc += 16; /* E(Header) */ @@ -167,10 +165,10 @@ unwrapToken(OM_uint32 *minor, unsigned char *althdr; /* Decrypt */ - code = gssEapDecrypt(ctx->kerberosCtx, + code = gssEapDecrypt(krbContext, ((ctx->gssFlags & GSS_C_DCE_STYLE) != 0), - ec, rrc, ctx->encryptionKey, - key_usage, 0, iov, iov_count); + ec, rrc, &ctx->rfc3961Key, + keyUsage, 0, iov, iov_count); if (code != 0) { *minor = code; return GSS_S_BAD_SIG; @@ -191,15 +189,15 @@ unwrapToken(OM_uint32 *minor, } } else { /* Verify checksum: note EC is checksum size here, not padding */ - if (ec != k5_trailerlen) + if (ec != krbTrailerLen) goto defective; /* Zero EC, RRC before computing checksum */ store_uint16_be(0, ptr + 4); store_uint16_be(0, ptr + 6); - code = gssEapVerify(ctx->kerberosCtx, cksumtype, rrc, - ctx->encryptionKey, key_usage, + code = gssEapVerify(krbContext, ctx->checksumType, rrc, + &ctx->rfc3961Key, keyUsage, iov, iov_count, &valid); if (code != 0 || valid == FALSE) { *minor = code; @@ -207,9 +205,9 @@ unwrapToken(OM_uint32 *minor, } } - code = sequenceCheck(&ctx->seqState, seqnum); + code = sequenceCheck(minor, &ctx->seqState, seqnum); } else if (toktype == TOK_TYPE_MIC) { - if (load_uint16_be(ptr) != TOK_TYPE_MIC) + if (load_uint16_be(ptr) != toktype) goto defective; verify_mic_1: @@ -217,16 +215,16 @@ unwrapToken(OM_uint32 *minor, goto defective; seqnum = load_uint64_be(ptr + 8); - code = gssEapVerify(ctx->kerberosCtx, cksumtype, 0, - ctx->encryptionKey, key_usage, + code = gssEapVerify(krbContext, ctx->checksumType, 0, + &ctx->rfc3961Key, keyUsage, iov, iov_count, &valid); if (code != 0 || valid == FALSE) { *minor = code; return GSS_S_BAD_SIG; } - code = sequenceCheck(&ctx->seqState, seqnum); - } else if (toktype == TOK_TYPE_DELETE) { - if (load_uint16_be(ptr) != TOK_TYPE_DELETE) + code = sequenceCheck(minor, &ctx->seqState, seqnum); + } else if (toktype == TOK_TYPE_DELETE_CONTEXT) { + if (load_uint16_be(ptr) != TOK_TYPE_DELETE_CONTEXT) goto defective; goto verify_mic_1; } else { @@ -284,13 +282,15 @@ unwrapStream(OM_uint32 *minor, { unsigned char *ptr; OM_uint32 code = 0, major = GSS_S_FAILURE; - krb5_context context = ctx->kerberosCtx; + krb5_context krbContext; int conf_req_flag, toktype2; int i = 0, j; gss_iov_buffer_desc *tiov = NULL; gss_iov_buffer_t stream, data = NULL; gss_iov_buffer_t theader, tdata = NULL, tpadding, ttrailer; + GSSEAP_KRB_INIT(&krbContext); + assert(toktype == TOK_TYPE_WRAP); if (toktype != TOK_TYPE_WRAP || (ctx->gssFlags & GSS_C_DCE_STYLE)) { @@ -359,8 +359,8 @@ unwrapStream(OM_uint32 *minor, { size_t ec, rrc; - unsigned int k5_headerlen = 0; - unsigned int k5_trailerlen = 0; + unsigned int krbHeaderLen = 0; + unsigned int krbTrailerLen = 0; conf_req_flag = ((ptr[0] & TOK_FLAG_WRAP_CONFIDENTIAL) != 0); ec = conf_req_flag ? load_uint16_be(ptr + 2) : 0; @@ -375,24 +375,24 @@ unwrapStream(OM_uint32 *minor, } if (conf_req_flag) { - code = krb5_c_crypto_length(context, ctx->encryptionType, - KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + code = krb5_c_crypto_length(krbContext, ctx->encryptionType, + KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); if (code != 0) goto cleanup; - theader->buffer.length += k5_headerlen; /* length validated later */ + theader->buffer.length += krbHeaderLen; /* length validated later */ } /* no PADDING for CFX, EC is used instead */ - code = krb5_c_crypto_length(context, ctx->encryptionType, + code = krb5_c_crypto_length(krbContext, ctx->encryptionType, conf_req_flag ? KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM, - &k5_trailerlen); + &krbTrailerLen); if (code != 0) goto cleanup; ttrailer->buffer.length = ec + (conf_req_flag ? 16 : 0 /* E(Header) */) + - k5_trailerlen; + krbTrailerLen; ttrailer->buffer.value = (unsigned char *)stream->buffer.value + stream->buffer.length - ttrailer->buffer.length; } @@ -463,8 +463,8 @@ gssEapUnwrapOrVerifyMIC(OM_uint32 *minor, { OM_uint32 major; - if (!CTX_IS_ESTABLISHED(ctx)) - return GSS_S_NO_CONTEXT; + if (ctx->encryptionType == ENCTYPE_NULL) + return GSS_S_UNAVAILABLE; if (gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_STREAM) != NULL) { major = unwrapStream(minor, ctx, conf_state, qop_state, @@ -485,6 +485,9 @@ gss_unwrap_iov(OM_uint32 *minor, gss_iov_buffer_desc *iov, int iov_count) { + if (!CTX_IS_ESTABLISHED(ctx)) + return GSS_S_NO_CONTEXT; + return gssEapUnwrapOrVerifyMIC(minor, ctx, conf_state, qop_state, iov, iov_count, TOK_TYPE_WRAP); }