OM_uint32
gss_get_mic(OM_uint32 *minor,
- gss_ctx_id_t context_handle,
- gss_qop_t qop_req,
+ gss_ctx_id_t ctx,
+ gss_qop_t qop_req __attribute__((__unused__)),
gss_buffer_t message_buffer,
gss_buffer_t message_token)
{
- GSSEAP_NOT_IMPLEMENTED;
+ OM_uint32 major;
+ gss_iov_buffer_desc iov[2];
+
+ message_token->value = NULL;
+ message_token->length = 0;
+
+ iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
+ iov[0].buffer = *message_buffer;
+
+ iov[1].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
+ iov[1].buffer.value = NULL;
+ iov[1].buffer.length = 0;
+
+ major = gssEapWrapOrGetMIC(minor, ctx, FALSE, FALSE, iov, 2, TOK_TYPE_MIC);
+ if (major == GSS_S_COMPLETE) {
+ *message_token = iov[1].buffer;
+ }
+
+ return major;
}
gss_OID mechanismUsed;
krb5_enctype encryptionType;
krb5_cksumtype checksumType;
- krb5_keyblock *encryptionKey;
+ krb5_keyblock *rfc3961Key;
gss_name_t initiatorName;
gss_name_t acceptorName;
time_t expiryTime;
* SUCH DAMAGE.
*/
/*
- * lib/gssapi/krb5/prf.c
- *
* Copyright 2009 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
- *
*/
#include "gssapiP_eap.h"
while (desired_output_len > 0) {
store_uint32_be(i, ns.data);
- code = krb5_c_prf(ctx->kerberosCtx, ctx->encryptionKey, &ns, &t);
+ code = krb5_c_prf(ctx->kerberosCtx, ctx->rfc3961Key, &ns, &t);
if (code != 0)
goto cleanup;
gss_iov_buffer_t header;
gss_iov_buffer_t padding;
gss_iov_buffer_t trailer;
- unsigned char acceptor_flag;
+ unsigned char acceptorFlag;
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;
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));
+ acceptorFlag = CTX_IS_INITIATOR(ctx) ? TOK_FLAG_SENDER_IS_ACCEPTOR : 0;
+ keyUsage = (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));
- gssEapIovMessageLength(iov, iov_count, &data_length, &assoc_data_length);
+ gssEapIovMessageLength(iov, iov_count, &dataLen, &assocDataLen);
ptr = (unsigned char *)header->buffer.value;
return GSS_S_DEFECTIVE_TOKEN;
}
- if ((ptr[2] & TOK_FLAG_SENDER_IS_ACCEPTOR) != acceptor_flag) {
+ if ((ptr[2] & TOK_FLAG_SENDER_IS_ACCEPTOR) != acceptorFlag) {
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;
seqnum = load_uint64_be(ptr + 8);
code = krb5_c_crypto_length(ctx->kerberosCtx,
- KRB_KEYTYPE(ctx->encryptionKey),
+ ctx->encryptionType,
conf_flag ? KRB5_CRYPTO_TYPE_TRAILER :
KRB5_CRYPTO_TYPE_CHECKSUM,
- &k5_trailerlen);
+ &krbTrailerLen);
if (code != 0) {
*minor = code;
return GSS_S_FAILURE;
/* 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) */
/* Decrypt */
code = gssEapDecrypt(ctx->kerberosCtx,
((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;
}
} 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 + 6);
code = gssEapVerify(ctx->kerberosCtx, cksumtype, rrc,
- ctx->encryptionKey, key_usage,
+ ctx->rfc3961Key, keyUsage,
iov, iov_count, &valid);
if (code != 0 || valid == FALSE) {
*minor = code;
seqnum = load_uint64_be(ptr + 8);
code = gssEapVerify(ctx->kerberosCtx, cksumtype, 0,
- ctx->encryptionKey, key_usage,
+ ctx->rfc3961Key, keyUsage,
iov, iov_count, &valid);
if (code != 0 || valid == FALSE) {
*minor = code;
{
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;
if (conf_req_flag) {
code = krb5_c_crypto_length(context, ctx->encryptionType,
- KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
+ 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 */
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;
}
releaseAcceptorContext(&ctx->acceptorCtx);
}
- if (ctx->encryptionKey != NULL) {
- krb5_free_keyblock(ctx->kerberosCtx, ctx->encryptionKey);
+ if (ctx->rfc3961Key != NULL) {
+ krb5_free_keyblock(ctx->kerberosCtx, ctx->rfc3961Key);
}
if (ctx->kerberosCtx != NULL) {
OM_uint32
gss_verify_mic(OM_uint32 *minor,
- gss_ctx_id_t context_handle,
+ gss_ctx_id_t ctx,
gss_buffer_t message_buffer,
gss_buffer_t message_token,
gss_qop_t *qop_state)
{
- GSSEAP_NOT_IMPLEMENTED;
+ gss_iov_buffer_desc iov[2];
+ int conf_state;
+
+ iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
+ iov[0].buffer = *message_buffer;
+
+ iov[1].type = GSS_IOV_BUFFER_TYPE_HEADER;
+ iov[1].buffer = *message_token;
+
+ return gssEapUnwrapOrVerifyMIC(minor, ctx, &conf_state, qop_state,
+ iov, 2, TOK_TYPE_MIC);
}
gss_iov_buffer_t header;
gss_iov_buffer_t padding;
gss_iov_buffer_t trailer;
- unsigned char acceptor_flag;
+ unsigned char acceptorFlag;
unsigned char *outbuf = NULL;
unsigned char *tbuf = NULL;
- int key_usage;
+ int keyUsage;
size_t rrc = 0;
- unsigned int gss_headerlen, gss_trailerlen;
- size_t data_length, assoc_data_length;
+ unsigned int gssHeaderLen, gssTrailerLen;
+ size_t dataLen, assocDataLen;
if (!CTX_IS_ESTABLISHED(ctx))
return GSS_S_NO_CONTEXT;
- acceptor_flag = CTX_IS_INITIATOR(ctx) ? 0 : TOK_FLAG_SENDER_IS_ACCEPTOR;
- 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));
+ acceptorFlag = CTX_IS_INITIATOR(ctx) ? 0 : TOK_FLAG_SENDER_IS_ACCEPTOR;
+ keyUsage = ((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));
- gssEapIovMessageLength(iov, iov_count, &data_length, &assoc_data_length);
+ gssEapIovMessageLength(iov, iov_count, &dataLen, &assocDataLen);
header = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
if (header == NULL) {
trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
if (toktype == TOK_TYPE_WRAP && conf_req_flag) {
- unsigned int k5_headerlen, k5_trailerlen, k5_padlen;
+ unsigned int krbHeaderLen, krbTrailerLen, krbPadLen;
size_t ec = 0;
- size_t conf_data_length = data_length - assoc_data_length;
+ size_t confDataLen = dataLen - assocDataLen;
code = krb5_c_crypto_length(ctx->kerberosCtx, ctx->encryptionType,
- KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
+ KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
if (code != 0)
goto cleanup;
code = krb5_c_padding_length(ctx->kerberosCtx, ctx->encryptionType,
- conf_data_length + 16 /* E(Header) */,
- &k5_padlen);
+ confDataLen + 16 /* E(Header) */,
+ &krbPadLen);
if (code != 0)
goto cleanup;
- if (k5_padlen == 0 && (ctx->gssFlags & GSS_C_DCE_STYLE)) {
+ 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);
if (code != 0)
goto cleanup;
} else
- ec = k5_padlen;
+ ec = krbPadLen;
code = krb5_c_crypto_length(ctx->kerberosCtx, ctx->encryptionType,
- KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
+ KRB5_CRYPTO_TYPE_TRAILER, &krbTrailerLen);
if (code != 0)
goto cleanup;
- gss_headerlen = 16 /* Header */ + k5_headerlen;
- gss_trailerlen = ec + 16 /* E(Header) */ + k5_trailerlen;
+ gssHeaderLen = 16 /* Header */ + krbHeaderLen;
+ gssTrailerLen = ec + 16 /* E(Header) */ + krbTrailerLen;
if (trailer == NULL) {
- rrc = gss_trailerlen;
+ rrc = gssTrailerLen;
/* Workaround for Windows bug where it rotates by EC + RRC */
if (ctx->gssFlags & GSS_C_DCE_STYLE)
rrc -= ec;
- gss_headerlen += gss_trailerlen;
+ gssHeaderLen += gssTrailerLen;
}
if (header->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
- code = gssEapAllocIov(header, (size_t) gss_headerlen);
- } else if (header->buffer.length < gss_headerlen)
+ code = gssEapAllocIov(header, (size_t)gssHeaderLen);
+ } else if (header->buffer.length < gssHeaderLen)
code = KRB5_BAD_MSIZE;
if (code != 0)
goto cleanup;
outbuf = (unsigned char *)header->buffer.value;
- header->buffer.length = (size_t) gss_headerlen;
+ header->buffer.length = (size_t)gssHeaderLen;
if (trailer != NULL) {
if (trailer->type & GSS_IOV_BUFFER_FLAG_ALLOCATE)
- code = gssEapAllocIov(trailer, (size_t) gss_trailerlen);
- else if (trailer->buffer.length < gss_trailerlen)
+ code = gssEapAllocIov(trailer, (size_t)gssTrailerLen);
+ else if (trailer->buffer.length < gssTrailerLen)
code = KRB5_BAD_MSIZE;
if (code != 0)
goto cleanup;
- trailer->buffer.length = (size_t) gss_trailerlen;
+ trailer->buffer.length = (size_t)gssTrailerLen;
}
/* TOK_ID */
store_uint16_be((uint16_t)toktype, outbuf);
/* flags */
- outbuf[2] = (acceptor_flag
+ outbuf[2] = (acceptorFlag
| (conf_req_flag ? TOK_FLAG_WRAP_CONFIDENTIAL : 0)
| (0 ? TOK_FLAG_ACCEPTOR_SUBKEY : 0));
/* filler */
code = gssEapEncrypt(ctx->kerberosCtx,
((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)
goto cleanup;
} else if (toktype == TOK_TYPE_WRAP && !conf_req_flag) {
wrap_with_checksum:
- gss_headerlen = 16;
+ gssHeaderLen = 16;
code = krb5_c_crypto_length(ctx->kerberosCtx, ctx->encryptionType,
KRB5_CRYPTO_TYPE_CHECKSUM,
- &gss_trailerlen);
+ &gssTrailerLen);
if (code != 0)
goto cleanup;
- assert(gss_trailerlen <= 0xFFFF);
+ assert(gssTrailerLen <= 0xFFFF);
if (trailer == NULL) {
- rrc = gss_trailerlen;
- gss_headerlen += gss_trailerlen;
+ rrc = gssTrailerLen;
+ gssHeaderLen += gssTrailerLen;
}
if (header->type & GSS_IOV_BUFFER_FLAG_ALLOCATE)
- code = gssEapAllocIov(header, (size_t) gss_headerlen);
- else if (header->buffer.length < gss_headerlen)
+ code = gssEapAllocIov(header, (size_t)gssHeaderLen);
+ else if (header->buffer.length < gssHeaderLen)
code = KRB5_BAD_MSIZE;
if (code != 0)
goto cleanup;
outbuf = (unsigned char *)header->buffer.value;
- header->buffer.length = (size_t) gss_headerlen;
+ header->buffer.length = (size_t)gssHeaderLen;
if (trailer != NULL) {
if (trailer->type & GSS_IOV_BUFFER_FLAG_ALLOCATE)
- code = gssEapAllocIov(trailer, (size_t) gss_trailerlen);
- else if (trailer->buffer.length < gss_trailerlen)
+ code = gssEapAllocIov(trailer, (size_t)gssTrailerLen);
+ else if (trailer->buffer.length < gssTrailerLen)
code = KRB5_BAD_MSIZE;
if (code != 0)
goto cleanup;
- trailer->buffer.length = (size_t) gss_trailerlen;
+ trailer->buffer.length = (size_t)gssTrailerLen;
}
/* TOK_ID */
store_uint16_be((uint16_t)toktype, outbuf);
/* flags */
- outbuf[2] = (acceptor_flag
+ outbuf[2] = (acceptorFlag
| (0 ? TOK_FLAG_ACCEPTOR_SUBKEY : 0));
/* filler */
outbuf[3] = 0xFF;
store_64_be(ctx->sendSeq, outbuf + 8);
code = gssEapSign(ctx->kerberosCtx, ctx->checksumType,
- rrc, ctx->encryptionKey, key_usage,
+ rrc, ctx->rfc3961Key, keyUsage,
iov, iov_count);
if (code != 0)
goto cleanup;
if (toktype == TOK_TYPE_WRAP) {
/* Fix up EC field */
- store_uint16_be(gss_trailerlen, outbuf + 4);
+ store_uint16_be(gssTrailerLen, outbuf + 4);
/* Fix up RRC field */
store_uint16_be(rrc, outbuf + 6);
}