size_t rrc = 0;
unsigned int gssHeaderLen, gssTrailerLen;
size_t dataLen, assocDataLen;
+ krb5_context krbContext;
- if (!CTX_IS_ESTABLISHED(ctx))
- return GSS_S_NO_CONTEXT;
+ if (ctx->encryptionType == ENCTYPE_NULL)
+ return GSS_S_UNAVAILABLE;
+
+ GSSEAP_KRB_INIT(&krbContext);
acceptorFlag = CTX_IS_INITIATOR(ctx) ? 0 : TOK_FLAG_SENDER_IS_ACCEPTOR;
- keyUsage = ((toktype == TOK_TYPE_WRAP)
- ? (CTX_IS_INITIATOR(ctx)
+
+ switch (toktype) {
+ case TOK_TYPE_WRAP:
+ keyUsage = CTX_IS_INITIATOR(ctx)
? KEY_USAGE_INITIATOR_SEAL
- : KEY_USAGE_ACCEPTOR_SEAL)
- : (CTX_IS_INITIATOR(ctx)
+ : KEY_USAGE_ACCEPTOR_SEAL;
+ break;
+ case TOK_TYPE_GSS_CB:
+ keyUsage = KEY_USAGE_CHANNEL_BINDINGS;
+ break;
+ case TOK_TYPE_MIC:
+ default:
+ keyUsage = CTX_IS_INITIATOR(ctx)
? KEY_USAGE_INITIATOR_SIGN
- : KEY_USAGE_ACCEPTOR_SIGN));
+ : KEY_USAGE_ACCEPTOR_SIGN;
+ break;
+ }
gssEapIovMessageLength(iov, iov_count, &dataLen, &assocDataLen);
size_t ec = 0;
size_t confDataLen = dataLen - assocDataLen;
- code = krb5_c_crypto_length(ctx->kerberosCtx, ctx->encryptionType,
+ code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
if (code != 0)
goto cleanup;
- code = krb5_c_padding_length(ctx->kerberosCtx, ctx->encryptionType,
+ code = krb5_c_padding_length(krbContext, ctx->encryptionType,
confDataLen + 16 /* E(Header) */,
&krbPadLen);
if (code != 0)
if (krbPadLen == 0 && (ctx->gssFlags & GSS_C_DCE_STYLE)) {
/* Windows rejects AEAD tokens with non-zero EC */
- code = krb5_c_block_size(ctx->kerberosCtx, ctx->encryptionType, &ec);
+ code = krb5_c_block_size(krbContext, ctx->encryptionType, &ec);
if (code != 0)
goto cleanup;
} else
ec = krbPadLen;
- code = krb5_c_crypto_length(ctx->kerberosCtx, ctx->encryptionType,
+ code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
KRB5_CRYPTO_TYPE_TRAILER, &krbTrailerLen);
if (code != 0)
goto cleanup;
store_uint16_be(ec, outbuf + 4);
/* RRC */
store_uint16_be(0, outbuf + 6);
- store_64_be(ctx->sendSeq, outbuf + 8);
+ store_uint64_be(ctx->sendSeq, outbuf + 8);
/*
* EC | copy of header to be encrypted, located in
memset(tbuf, 0xFF, ec);
memcpy(tbuf + ec, header->buffer.value, 16);
- code = gssEapEncrypt(ctx->kerberosCtx,
+ code = gssEapEncrypt(krbContext,
((ctx->gssFlags & GSS_C_DCE_STYLE) != 0),
- ec, rrc, ctx->rfc3961Key,
+ ec, rrc, &ctx->rfc3961Key,
keyUsage, 0, iov, iov_count);
if (code != 0)
goto cleanup;
gssHeaderLen = 16;
- code = krb5_c_crypto_length(ctx->kerberosCtx, ctx->encryptionType,
+ code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
KRB5_CRYPTO_TYPE_CHECKSUM,
&gssTrailerLen);
if (code != 0)
store_uint16_be(0xFFFF, outbuf + 4);
store_uint16_be(0xFFFF, outbuf + 6);
}
- store_64_be(ctx->sendSeq, outbuf + 8);
+ store_uint64_be(ctx->sendSeq, outbuf + 8);
- code = gssEapSign(ctx->kerberosCtx, ctx->checksumType,
- rrc, ctx->rfc3961Key, keyUsage,
+ code = gssEapSign(krbContext, ctx->checksumType,
+ rrc, &ctx->rfc3961Key, keyUsage,
iov, iov_count);
if (code != 0)
goto cleanup;
- ctx->sendSeq++;
+ if (toktype != TOK_TYPE_GSS_CB)
+ ctx->sendSeq++;
if (toktype == TOK_TYPE_WRAP) {
/* Fix up EC field */
/* Fix up RRC field */
store_uint16_be(rrc, outbuf + 6);
}
- } else if (toktype == TOK_TYPE_MIC) {
+ } else if (toktype == TOK_TYPE_MIC || toktype == TOK_TYPE_GSS_CB) {
trailer = NULL;
goto wrap_with_checksum;
- } else if (toktype == TOK_TYPE_DELETE) {
+ } else if (toktype == TOK_TYPE_DELETE_CONTEXT) {
+ trailer = NULL;
goto wrap_with_checksum;
} else {
abort();
*minor = code;
- if (code == 0)
- return GSS_S_FAILURE;
- else
- return GSS_S_COMPLETE;
+ return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
OM_uint32
gss_iov_buffer_desc *iov,
int iov_count)
{
+ if (!CTX_IS_ESTABLISHED(ctx))
+ return GSS_S_NO_CONTEXT;
+
return gssEapWrapOrGetMIC(minor, ctx, conf_req_flag, conf_state,
iov, iov_count, TOK_TYPE_WRAP);
}