util_cred.c \
util_crypt.c \
util_name.c \
+ util_ordering.c \
verify_mic.c \
wrap.c \
wrap_iov.c \
--- /dev/null
+- SAML
+- encoders
+- OID encoders
+- stream
/* Kerberos includes */
#include <krb5.h>
+#include "util.h"
struct gss_name_struct {
OM_uint32 flags;
#define TOK_FLAG_WRAP_CONFIDENTIAL 0x02
#define TOK_FLAG_ACCEPTOR_SUBKEY 0x04
+#define KEY_USAGE_ACCEPTOR_SEAL 512
+#define KEY_USAGE_ACCEPTOR_SIGN 513
+#define KEY_USAGE_INITIATOR_SEAL 514
+#define KEY_USAGE_INITIATOR_SIGN 515
+
enum gss_eap_token_type {
TOK_TYPE_MIC = 0x0404,
TOK_TYPE_WRAP = 0x0504,
TOK_TYPE_DELETE = 0x0405
};
-/* Helper APIs */
-OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
-OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
-
-OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName);
-OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName);
-
-OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
-OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
-
-/* Kerberos token services */
-#define KRB_USAGE_ACCEPTOR_SEAL 22
-#define KRB_USAGE_ACCEPTOR_SIGN 23
-#define KRB_USAGE_INITIATOR_SEAL 24
-#define KRB_USAGE_INITIATOR_SIGN 25
-
-#if 0
-#define KRB_KEYTYPE(key) ((key)->keytype)
-#else
-#define KRB_KEYTYPE(key) ((key)->enctype)
-#endif
-
-/* util_crypt.c */
-int
-gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
- size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
- gss_iov_buffer_desc *iov, int iov_count);
-
-int
-gssEapDecrypt(krb5_context context, int dce_style, size_t ec,
- size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
- gss_iov_buffer_desc *iov, int iov_count);
-
-krb5_cryptotype
-gssEapTranslateCryptoFlag(OM_uint32 type);
-
-gss_iov_buffer_t
-gssEapLocateIov(gss_iov_buffer_desc *iov,
- int iov_count,
- OM_uint32 type);
-
-void
-gssEapIovMessageLength(gss_iov_buffer_desc *iov,
- int iov_count,
- size_t *data_length,
- size_t *assoc_data_length);
-
-void
-gssEapReleaseIov(gss_iov_buffer_desc *iov, int iov_count);
-
-int
-gssEapIsIntegrityOnly(gss_iov_buffer_desc *iov, int iov_count);
-
-int
-gssEapAllocIov(gss_iov_buffer_t iov, size_t size);
-
-/* util_cksum.c */
-int
-gssEapSign(krb5_context context,
- krb5_cksumtype type,
- size_t rrc,
- krb5_keyblock *key,
- krb5_keyusage sign_usage,
- gss_iov_buffer_desc *iov,
- int iov_count);
-
-int
-gssEapVerify(krb5_context context,
- krb5_cksumtype type,
- size_t rrc,
- krb5_keyblock *key,
- krb5_keyusage sign_usage,
- gss_iov_buffer_desc *iov,
- int iov_count,
- int *valid);
-
/* wrap_iov.c */
OM_uint32
gssEapWrapOrGetMIC(OM_uint32 *minor,
int iov_count,
enum gss_eap_token_type toktype);
-/* Helper macros */
-#define GSSEAP_CALLOC(count, size) (calloc((count), (size)))
-#define GSSEAP_FREE(ptr) (free((ptr)))
-#define GSSEAP_MALLOC(size) (malloc((size)))
-#define GSSEAP_REALLOC(ptr, size) (realloc((ptr), (size)))
-
-#define GSSEAP_NOT_IMPLEMENTED do { \
- assert(0 && "not implemented"); \
- *minor = ENOSYS; \
- return GSS_S_FAILURE; \
- } while (0)
#endif /* _GSSAPIP_EAP_H_ */
-
* SUCH DAMAGE.
*/
/*
- * lib/gssapi/krb5/k5sealv3iov.c
- *
* Copyright 2008 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"
+/*
+ * Caller must provide TOKEN | DATA | PADDING | TRAILER, except
+ * for DCE in which case it can just provide TOKEN | DATA (must
+ * guarantee that DATA is padded)
+ */
OM_uint32
-gssEapUnwrapOrVerifyMIC(OM_uint32 *minor_status,
- gss_ctx_id_t ctx,
- int *conf_state,
- gss_qop_t *qop_state,
- gss_iov_buffer_desc *iov,
- int iov_count,
- enum gss_eap_token_type toktype)
+unwrapToken(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count,
+ enum gss_eap_token_type toktype)
{
OM_uint32 code;
gss_iov_buffer_t header;
size_t rrc, ec;
size_t data_length, assoc_data_length;
uint64_t seqnum;
- krb5_boolean valid;
+ int valid = 0;
krb5_cksumtype cksumtype;
int conf_flag = 0;
- *minor_status = 0;
+ *minor = 0;
if (qop_state != NULL)
*qop_state = GSS_C_QOP_DEFAULT;
- if (!CTX_IS_ESTABLISHED(ctx))
- return GSS_S_NO_CONTEXT;
-
header = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
assert(header != NULL);
acceptor_flag = CTX_IS_INITIATOR(ctx) ? TOK_FLAG_SENDER_IS_ACCEPTOR : 0;
key_usage = (toktype == TOK_TYPE_WRAP
? (!CTX_IS_INITIATOR(ctx)
- ? KRB_USAGE_INITIATOR_SEAL
- : KRB_USAGE_ACCEPTOR_SEAL)
+ ? KEY_USAGE_INITIATOR_SEAL
+ : KEY_USAGE_ACCEPTOR_SEAL)
: (!CTX_IS_INITIATOR(ctx)
- ? KRB_USAGE_INITIATOR_SIGN
- : KRB_USAGE_ACCEPTOR_SIGN));
+ ? KEY_USAGE_INITIATOR_SIGN
+ : KEY_USAGE_ACCEPTOR_SIGN));
gssEapIovMessageLength(iov, iov_count, &data_length, &assoc_data_length);
ptr = (unsigned char *)header->buffer.value;
if (header->buffer.length < 16) {
- *minor_status = 0;
+ *minor = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
if (toktype == TOK_TYPE_WRAP) {
unsigned int k5_trailerlen;
- if (load_16_be(ptr) != TOK_TYPE_WRAP)
+ if (load_uint16_be(ptr) != TOK_TYPE_WRAP)
goto defective;
conf_flag = ((ptr[2] & TOK_FLAG_WRAP_CONFIDENTIAL) != 0);
if (ptr[3] != 0xFF)
goto defective;
- ec = load_16_be(ptr + 4);
- rrc = load_16_be(ptr + 6);
- seqnum = load_64_be(ptr + 8);
+ ec = load_uint16_be(ptr + 4);
+ rrc = load_uint16_be(ptr + 6);
+ seqnum = load_uint64_be(ptr + 8);
code = krb5_c_crypto_length(ctx->kerberosCtx,
KRB_KEYTYPE(ctx->encryptionKey),
KRB5_CRYPTO_TYPE_CHECKSUM,
&k5_trailerlen);
if (code != 0) {
- *minor_status = code;
+ *minor = code;
return GSS_S_FAILURE;
}
ec, rrc, ctx->encryptionKey,
key_usage, 0, iov, iov_count);
if (code != 0) {
- *minor_status = code;
+ *minor = code;
return GSS_S_BAD_SIG;
}
else
althdr = (unsigned char *)trailer->buffer.value + ec;
- if (load_16_be(althdr) != TOK_TYPE_WRAP
+ if (load_uint16_be(althdr) != TOK_TYPE_WRAP
|| althdr[2] != ptr[2]
|| althdr[3] != ptr[3]
|| memcmp(althdr + 8, ptr + 8, 8) != 0) {
- *minor_status = 0;
+ *minor = 0;
return GSS_S_BAD_SIG;
}
} else {
goto defective;
/* Zero EC, RRC before computing checksum */
- store_16_be(0, ptr + 4);
- store_16_be(0, ptr + 6);
+ store_uint16_be(0, ptr + 4);
+ store_uint16_be(0, ptr + 6);
code = gssEapVerify(ctx->kerberosCtx, cksumtype, rrc,
ctx->encryptionKey, key_usage,
iov, iov_count, &valid);
if (code != 0 || valid == FALSE) {
- *minor_status = code;
+ *minor = code;
return GSS_S_BAD_SIG;
}
}
- code = g_order_check(&ctx->seqState, seqnum);
+ code = sequenceCheck(&ctx->seqState, seqnum);
} else if (toktype == TOK_TYPE_MIC) {
- if (load_16_be(ptr) != TOK_TYPE_MIC)
+ if (load_uint16_be(ptr) != TOK_TYPE_MIC)
goto defective;
verify_mic_1:
if (ptr[3] != 0xFF)
goto defective;
- seqnum = load_64_be(ptr + 8);
+ seqnum = load_uint64_be(ptr + 8);
code = gssEapVerify(ctx->kerberosCtx, cksumtype, 0,
ctx->encryptionKey, key_usage,
iov, iov_count, &valid);
if (code != 0 || valid == FALSE) {
- *minor_status = code;
+ *minor = code;
return GSS_S_BAD_SIG;
}
- code = g_order_check(&ctx->seqState, seqnum);
+ code = sequenceCheck(&ctx->seqState, seqnum);
} else if (toktype == TOK_TYPE_DELETE) {
- if (load_16_be(ptr) != TOK_TYPE_DELETE)
+ if (load_uint16_be(ptr) != TOK_TYPE_DELETE)
goto defective;
goto verify_mic_1;
} else {
goto defective;
}
- *minor_status = 0;
+ *minor = 0;
if (conf_state != NULL)
*conf_state = conf_flag;
return code;
defective:
- *minor_status = 0;
+ *minor = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
+int
+rotateLeft(void *ptr, size_t bufsiz, size_t rc)
+{
+ void *tbuf;
+
+ if (bufsiz == 0)
+ return 0;
+ rc = rc % bufsiz;
+ if (rc == 0)
+ return 0;
+
+ tbuf = GSSEAP_MALLOC(rc);
+ if (tbuf == NULL)
+ return ENOMEM;
+
+ memcpy(tbuf, ptr, rc);
+ memmove(ptr, (char *)ptr + rc, bufsiz - rc);
+ memcpy((char *)ptr + bufsiz - rc, tbuf, rc);
+ GSSEAP_FREE(tbuf);
+
+ return 0;
+}
+
+/*
+ * Split a STREAM | SIGN_DATA | DATA into
+ * HEADER | SIGN_DATA | DATA | PADDING | TRAILER
+ */
+static OM_uint32
+unwrapStream(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count,
+ enum gss_eap_token_type toktype)
+{
+ unsigned char *ptr;
+ OM_uint32 code = 0, major = GSS_S_FAILURE;
+ krb5_context context = ctx->kerberosCtx;
+ 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;
+
+ assert(toktype == TOK_TYPE_WRAP);
+
+ if (toktype != TOK_TYPE_WRAP || (ctx->gssFlags & GSS_C_DCE_STYLE)) {
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ stream = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_STREAM);
+ assert(stream != NULL);
+
+ if (stream->buffer.length < 16) {
+ major = GSS_S_DEFECTIVE_TOKEN;
+ goto cleanup;
+ }
+
+ ptr = (unsigned char *)stream->buffer.value;
+ toktype2 = load_uint16_be(ptr);
+ ptr += 2;
+
+ tiov = (gss_iov_buffer_desc *)GSSEAP_CALLOC((size_t)iov_count + 2,
+ sizeof(gss_iov_buffer_desc));
+ if (tiov == NULL) {
+ code = ENOMEM;
+ goto cleanup;
+ }
+
+ /* HEADER */
+ theader = &tiov[i++];
+ theader->type = GSS_IOV_BUFFER_TYPE_HEADER;
+ theader->buffer.value = stream->buffer.value;
+ theader->buffer.length = 16;
+
+ /* n[SIGN_DATA] | DATA | m[SIGN_DATA] */
+ for (j = 0; j < iov_count; j++) {
+ OM_uint32 type = GSS_IOV_BUFFER_TYPE(iov[j].type);
+
+ if (type == GSS_IOV_BUFFER_TYPE_DATA) {
+ if (data != NULL) {
+ /* only a single DATA buffer can appear */
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ data = &iov[j];
+ tdata = &tiov[i];
+ }
+ if (type == GSS_IOV_BUFFER_TYPE_DATA ||
+ type == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
+ tiov[i++] = iov[j];
+ }
+
+ if (data == NULL) {
+ /* a single DATA buffer must be present */
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ /* PADDING | TRAILER */
+ tpadding = &tiov[i++];
+ tpadding->type = GSS_IOV_BUFFER_TYPE_PADDING;
+ tpadding->buffer.length = 0;
+ tpadding->buffer.value = NULL;
+
+ ttrailer = &tiov[i++];
+ ttrailer->type = GSS_IOV_BUFFER_TYPE_TRAILER;
+
+ {
+ size_t ec, rrc;
+ unsigned int k5_headerlen = 0;
+ unsigned int k5_trailerlen = 0;
+
+ conf_req_flag = ((ptr[0] & TOK_FLAG_WRAP_CONFIDENTIAL) != 0);
+ ec = conf_req_flag ? load_uint16_be(ptr + 2) : 0;
+ rrc = load_uint16_be(ptr + 4);
+
+ if (rrc != 0) {
+ code = rotateLeft((unsigned char *)stream->buffer.value + 16,
+ stream->buffer.length - 16, rrc);
+ if (code != 0)
+ goto cleanup;
+ store_uint16_be(0, ptr + 4); /* set RRC to zero */
+ }
+
+ if (conf_req_flag) {
+ code = krb5_c_crypto_length(context, ctx->encryptionType,
+ KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
+ if (code != 0)
+ goto cleanup;
+ theader->buffer.length += k5_headerlen; /* length validated later */
+ }
+
+ /* no PADDING for CFX, EC is used instead */
+ code = krb5_c_crypto_length(context, ctx->encryptionType,
+ conf_req_flag
+ ? KRB5_CRYPTO_TYPE_TRAILER
+ : KRB5_CRYPTO_TYPE_CHECKSUM,
+ &k5_trailerlen);
+ if (code != 0)
+ goto cleanup;
+
+ ttrailer->buffer.length = ec + (conf_req_flag ? 16 : 0 /* E(Header) */) +
+ k5_trailerlen;
+ ttrailer->buffer.value = (unsigned char *)stream->buffer.value +
+ stream->buffer.length - ttrailer->buffer.length;
+ }
+
+ /* IOV: -----------0-------------+---1---+--2--+----------------3--------------*/
+ /* Old: GSS-Header | Conf | Data | Pad | */
+ /* CFX: GSS-Header | Kerb-Header | Data | | EC | E(Header) | Kerb-Trailer */
+ /* GSS: -------GSS-HEADER--------+-DATA--+-PAD-+----------GSS-TRAILER----------*/
+
+ /* validate lengths */
+ if (stream->buffer.length < theader->buffer.length +
+ tpadding->buffer.length +
+ ttrailer->buffer.length) {
+ code = KRB5_BAD_MSIZE;
+ major = GSS_S_DEFECTIVE_TOKEN;
+ goto cleanup;
+ }
+
+ /* setup data */
+ tdata->buffer.length = stream->buffer.length - ttrailer->buffer.length -
+ tpadding->buffer.length - theader->buffer.length;
+
+ assert(data != NULL);
+
+ if (data->type & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
+ code = gssEapAllocIov(tdata, tdata->buffer.length);
+ if (code != 0)
+ goto cleanup;
+
+ memcpy(tdata->buffer.value,
+ (unsigned char *)stream->buffer.value + theader->buffer.length,
+ tdata->buffer.length);
+ } else {
+ tdata->buffer.value = (unsigned char *)stream->buffer.value +
+ theader->buffer.length;
+ }
+
+ assert(i <= iov_count + 2);
+
+ major = unwrapToken(&code, ctx, conf_state, qop_state,
+ tiov, i, toktype);
+ if (major == GSS_S_COMPLETE) {
+ *data = *tdata;
+ } else if (tdata->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
+ OM_uint32 tmp;
+
+ gss_release_buffer(&tmp, &tdata->buffer);
+ tdata->type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED);
+ }
+
+cleanup:
+ if (tiov != NULL)
+ GSSEAP_FREE(tiov);
+
+ *minor = code;
+
+ return major;
+}
+
+OM_uint32
+gssEapUnwrapOrVerifyMIC(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count,
+ enum gss_eap_token_type toktype)
+{
+ OM_uint32 major;
+
+ if (!CTX_IS_ESTABLISHED(ctx))
+ return GSS_S_NO_CONTEXT;
+
+ if (gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_STREAM) != NULL) {
+ major = unwrapStream(minor, ctx, conf_state, qop_state,
+ iov, iov_count, toktype);
+ } else {
+ major = unwrapToken(minor, ctx, conf_state, qop_state,
+ iov, iov_count, toktype);
+ }
+
+ return major;
+}
+
OM_uint32
gss_unwrap_iov(OM_uint32 *minor,
gss_ctx_id_t ctx,
gss_iov_buffer_desc *iov,
int iov_count)
{
- return gssEapUnwrapOrVerifyMIC(minor, ctx,
- iov, iov_count, conf_state,
- qop_state, TOK_TYPE_WRAP);
-
+ return gssEapUnwrapOrVerifyMIC(minor, ctx, conf_state, qop_state,
+ iov, iov_count, TOK_TYPE_WRAP);
}
--- /dev/null
+/*
+ * Copyright (c) 2010, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Portions Copyright 2003-2010 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+
+#ifndef _UTIL_H_
+#define _UTIL_H_ 1
+
+/* Helper APIs */
+OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
+OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
+
+OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName);
+OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName);
+
+OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
+OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
+
+/* Kerberos token services */
+#define KRB_KEYTYPE(key) ((key)->enctype)
+
+/* util_crypt.c */
+int
+gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
+ size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
+ gss_iov_buffer_desc *iov, int iov_count);
+
+int
+gssEapDecrypt(krb5_context context, int dce_style, size_t ec,
+ size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
+ gss_iov_buffer_desc *iov, int iov_count);
+
+krb5_cryptotype
+gssEapMapCryptoFlag(OM_uint32 type);
+
+gss_iov_buffer_t
+gssEapLocateIov(gss_iov_buffer_desc *iov,
+ int iov_count,
+ OM_uint32 type);
+
+void
+gssEapIovMessageLength(gss_iov_buffer_desc *iov,
+ int iov_count,
+ size_t *data_length,
+ size_t *assoc_data_length);
+
+void
+gssEapReleaseIov(gss_iov_buffer_desc *iov, int iov_count);
+
+int
+gssEapIsIntegrityOnly(gss_iov_buffer_desc *iov, int iov_count);
+
+int
+gssEapAllocIov(gss_iov_buffer_t iov, size_t size);
+
+/* util_cksum.c */
+int
+gssEapSign(krb5_context context,
+ krb5_cksumtype type,
+ size_t rrc,
+ krb5_keyblock *key,
+ krb5_keyusage sign_usage,
+ gss_iov_buffer_desc *iov,
+ int iov_count);
+
+int
+gssEapVerify(krb5_context context,
+ krb5_cksumtype type,
+ size_t rrc,
+ krb5_keyblock *key,
+ krb5_keyusage sign_usage,
+ gss_iov_buffer_desc *iov,
+ int iov_count,
+ int *valid);
+
+/* util_ordering.c */
+int
+sequenceInternalize(void **vqueue, unsigned char **buf, size_t *lenremain);
+
+int
+sequenceExternalize(void *vqueue, unsigned char **buf, size_t *lenremain);
+
+int
+sequenceSize(void *vqueue, size_t *sizep);
+
+void
+sequenceFree(void **vqueue);
+
+int
+sequenceCheck(void **vqueue, uint64_t seqnum);
+
+int
+sequenceInit(void **vqueue, uint64_t seqnum,
+ int do_replay, int do_sequence, int wide_nums);
+
+/* Helper macros */
+#define GSSEAP_CALLOC(count, size) (calloc((count), (size)))
+#define GSSEAP_FREE(ptr) (free((ptr)))
+#define GSSEAP_MALLOC(size) (malloc((size)))
+#define GSSEAP_REALLOC(ptr, size) (realloc((ptr), (size)))
+
+#define GSSEAP_NOT_IMPLEMENTED do { \
+ assert(0 && "not implemented"); \
+ *minor = ENOSYS; \
+ return GSS_S_FAILURE; \
+ } while (0)
+
+/* Helper functions */
+static inline void
+store_uint16_be(uint16_t val, void *vp)
+{
+ unsigned char *p = (unsigned char *)vp;
+
+ p[0] = (val >> 8) & 0xff;
+ p[1] = (val ) & 0xff;
+}
+
+static inline uint16_t
+load_uint16_be(const void *cvp)
+{
+ const unsigned char *p = (const unsigned char *)cvp;
+
+ return (p[1] | (p[0] << 8));
+}
+
+static inline void
+store_uint32_be(uint32_t val, void *vp)
+{
+ unsigned char *p = (unsigned char *)vp;
+
+ p[0] = (val >> 24) & 0xff;
+ p[1] = (val >> 16) & 0xff;
+ p[2] = (val >> 8) & 0xff;
+ p[3] = (val ) & 0xff;
+}
+
+static inline uint32_t
+load_uint32_be(const void *cvp)
+{
+ const unsigned char *p = (const unsigned char *)cvp;
+
+ return (p[3] | (p[2] << 8)
+ | ((uint32_t) p[1] << 16)
+ | ((uint32_t) p[0] << 24));
+}
+
+static inline void
+store_uint64_be(uint64_t val, void *vp)
+{
+ unsigned char *p = (unsigned char *)vp;
+
+ p[0] = (unsigned char)((val >> 56) & 0xff);
+ p[1] = (unsigned char)((val >> 48) & 0xff);
+ p[2] = (unsigned char)((val >> 40) & 0xff);
+ p[3] = (unsigned char)((val >> 32) & 0xff);
+ p[4] = (unsigned char)((val >> 24) & 0xff);
+ p[5] = (unsigned char)((val >> 16) & 0xff);
+ p[6] = (unsigned char)((val >> 8) & 0xff);
+ p[7] = (unsigned char)((val ) & 0xff);
+}
+
+static inline uint64_t
+load_uint64_be(const void *cvp)
+{
+ const unsigned char *p = (const unsigned char *)cvp;
+
+ return ((uint64_t)load_uint32_be(p) << 32) | load_uint32_be(p + 4);
+}
+
+#endif /* _UTIL_H_ */
if (verify)
*valid = FALSE;
- code = krb5_c_crypto_length(context, KRB_KEYTYPE(key), KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen);
+ code = krb5_c_crypto_length(context, KRB_KEYTYPE(key),
+ KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen);
if (code != 0)
return code;
/* Data */
for (j = 0; j < iov_count; j++) {
- kiov[i].flags = gssEapTranslateCryptoFlag(iov[j].type);
+ kiov[i].flags = gssEapMapCryptoFlag(iov[j].type);
kiov[i].data.length = iov[j].buffer.length;
kiov[i].data.data = (char *)iov[j].buffer.value;
i++;
gssEapReleaseName(&tmpMinor, &ctx->initiatorName);
gssEapReleaseName(&tmpMinor, &ctx->acceptorName);
+ sequenceFree(ctx->seqState);
+
memset(ctx, 0, sizeof(*ctx));
GSSEAP_FREE(ctx);
*pCtx = GSS_C_NO_CONTEXT;
* RRC is rotate count.
*/
static krb5_error_code
-translateIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
- krb5_enctype enctype, gss_iov_buffer_desc *iov,
- int iov_count, krb5_crypto_iov **pkiov,
- size_t *pkiov_count)
+mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
+ krb5_enctype enctype, gss_iov_buffer_desc *iov,
+ int iov_count, krb5_crypto_iov **pkiov,
+ size_t *pkiov_count)
{
gss_iov_buffer_t header;
gss_iov_buffer_t trailer;
i++;
for (j = 0; j < iov_count; j++) {
- kiov[i].flags = gssEapTranslateCryptoFlag(iov[j].type);
+ kiov[i].flags = gssEapMapCryptoFlag(iov[j].type);
if (kiov[i].flags == KRB5_CRYPTO_TYPE_EMPTY)
continue;
pivd = NULL;
}
- code = translateIov(context, dce_style, ec, rrc,
- KRB_KEYTYPE(key), iov, iov_count,
- &kiov, &kiov_count);
+ code = mapIov(context, dce_style, ec, rrc,
+ KRB_KEYTYPE(key), iov, iov_count,
+ &kiov, &kiov_count);
if (code == 0) {
code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count);
GSSEAP_FREE(kiov);
pivd = NULL;
}
- code = translateIov(context, dce_style, ec, rrc,
- KRB_KEYTYPE(key), iov, iov_count,
- &kiov, &kiov_count);
+ code = mapIov(context, dce_style, ec, rrc,
+ KRB_KEYTYPE(key), iov, iov_count,
+ &kiov, &kiov_count);
if (code == 0) {
code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count);
GSSEAP_FREE(kiov);
}
krb5_cryptotype
-gssEapTranslateCryptoFlag(OM_uint32 type)
+gssEapMapCryptoFlag(OM_uint32 type)
{
krb5_cryptotype ktype;
unsigned int gss_headerlen, gss_trailerlen;
size_t data_length, assoc_data_length;
- if (!CTX_IS_ESTABLISHED(ctx)) {
+ 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)
- ? KRB_USAGE_INITIATOR_SEAL
- : KRB_USAGE_ACCEPTOR_SEAL)
+ ? KEY_USAGE_INITIATOR_SEAL
+ : KEY_USAGE_ACCEPTOR_SEAL)
: (CTX_IS_INITIATOR(ctx)
- ? KRB_USAGE_INITIATOR_SIGN
- : KRB_USAGE_ACCEPTOR_SIGN));
+ ? KEY_USAGE_INITIATOR_SIGN
+ : KEY_USAGE_ACCEPTOR_SIGN));
gssEapIovMessageLength(iov, iov_count, &data_length, &assoc_data_length);
}
/* TOK_ID */
- store_16_be((uint16_t)toktype, outbuf);
+ store_uint16_be((uint16_t)toktype, outbuf);
/* flags */
outbuf[2] = (acceptor_flag
| (conf_req_flag ? TOK_FLAG_WRAP_CONFIDENTIAL : 0)
/* filler */
outbuf[3] = 0xFF;
/* EC */
- store_16_be(ec, outbuf + 4);
+ store_uint16_be(ec, outbuf + 4);
/* RRC */
- store_16_be(0, outbuf + 6);
+ store_uint16_be(0, outbuf + 6);
store_64_be(ctx->sendSeq, outbuf + 8);
- /* EC | copy of header to be encrypted, located in (possibly rotated) trailer */
+ /*
+ * EC | copy of header to be encrypted, located in
+ * (possibly rotated) trailer
+ */
if (trailer == NULL)
tbuf = (unsigned char *)header->buffer.value + 16; /* Header */
else
goto cleanup;
/* RRC */
- store_16_be(rrc, outbuf + 6);
+ store_uint16_be(rrc, outbuf + 6);
ctx->sendSeq++;
} else if (toktype == TOK_TYPE_WRAP && !conf_req_flag) {
}
/* TOK_ID */
- store_16_be((uint16_t)toktype, outbuf);
+ store_uint16_be((uint16_t)toktype, outbuf);
/* flags */
outbuf[2] = (acceptor_flag
| (0 ? TOK_FLAG_ACCEPTOR_SUBKEY : 0));
* checksum length later.
*/
/* EC */
- store_16_be(0, outbuf + 4);
+ store_uint16_be(0, outbuf + 4);
/* RRC */
- store_16_be(0, outbuf + 6);
+ store_uint16_be(0, outbuf + 6);
} else {
/* MIC and DEL store 0xFF in EC and RRC */
- store_16_be(0xFFFF, outbuf + 4);
- store_16_be(0xFFFF, outbuf + 6);
+ store_uint16_be(0xFFFF, outbuf + 4);
+ store_uint16_be(0xFFFF, outbuf + 6);
}
store_64_be(ctx->sendSeq, outbuf + 8);
if (toktype == TOK_TYPE_WRAP) {
/* Fix up EC field */
- store_16_be(gss_trailerlen, outbuf + 4);
+ store_uint16_be(gss_trailerlen, outbuf + 4);
/* Fix up RRC field */
- store_16_be(rrc, outbuf + 6);
+ store_uint16_be(rrc, outbuf + 6);
}
} else if (toktype == TOK_TYPE_MIC) {
trailer = NULL;