#ifndef _UTIL_H_
#define _UTIL_H_ 1
+#include <string.h>
+#include <errno.h>
+
#include <krb5.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "util_saml.h"
-#include "util_radius.h"
-#define KRB_KEYTYPE(key) ((key)->enctype)
+#define KRB_KEY_TYPE(key) ((key)->enctype)
+#define KRB_KEY_DATA(key) ((key)->contents)
+#define KRB_KEY_LENGTH(key) ((key)->length)
+#define KRB_KEY_INIT(key) do { \
+ KRB_KEY_TYPE(key) = ENCTYPE_NULL; \
+ KRB_KEY_DATA(key) = NULL; \
+ KRB_KEY_LENGTH(key) = 0; \
+ } while (0)
+
+enum gss_eap_token_type {
+ TOK_TYPE_NONE = 0x0000, /* no token */
+ TOK_TYPE_MIC = 0x0404, /* RFC 4121 MIC token */
+ TOK_TYPE_WRAP = 0x0504, /* RFC 4121 wrap token */
+ TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */
+ TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* draft-ietf-kitten-gss-naming */
+ TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */
+ TOK_TYPE_EAP_RESP = 0x0601, /* draft-howlett-eap-gss */
+ TOK_TYPE_EAP_REQ = 0x0602, /* draft-howlett-eap-gss */
+ TOK_TYPE_GSS_CB = 0x0603, /* draft-howlett-eap-gss */
+};
+
+#define EAP_EXPORT_CONTEXT_V1 1
+
+/* util_buffer.c */
+OM_uint32
+makeStringBuffer(OM_uint32 *minor,
+ const char *string,
+ gss_buffer_t buffer);
+
+OM_uint32
+bufferToString(OM_uint32 *minor,
+ const gss_buffer_t buffer,
+ char **pString);
+
+OM_uint32
+duplicateBuffer(OM_uint32 *minor,
+ const gss_buffer_t src,
+ gss_buffer_t dst);
+
+static inline int
+bufferEqual(const gss_buffer_t b1, const gss_buffer_t b2)
+{
+ return (b1->length == b2->length &&
+ memcmp(b1->value, b2->value, b2->length) == 0);
+}
+
+static inline int
+bufferEqualString(const gss_buffer_t b1, const char *s)
+{
+ gss_buffer_desc b2;
+
+ b2.length = strlen(s);
+ b2.value = (char *)s;
+ return bufferEqual(b1, &b2);
+}
+
+/* util_cksum.c */
int
gssEapSign(krb5_context context,
krb5_cksumtype type,
int iov_count,
int *valid);
+#if 0
+OM_uint32
+gssEapEncodeGssChannelBindings(OM_uint32 *minor,
+ gss_channel_bindings_t chanBindings,
+ gss_buffer_t encodedBindings);
+#endif
+
/* util_context.c */
OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
+OM_uint32
+gssEapMakeToken(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ const gss_buffer_t innerToken,
+ enum gss_eap_token_type tokenType,
+ gss_buffer_t outputToken);
+
+OM_uint32
+gssEapVerifyToken(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ const gss_buffer_t inputToken,
+ enum gss_eap_token_type tokenType,
+ gss_buffer_t innerInputToken);
+
/* util_cred.c */
OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
gss_OID_set *pActualMechs,
OM_uint32 *timeRec);
+int gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech);
+
/* util_crypt.c */
int
gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
gssEapAllocIov(gss_iov_buffer_t iov, size_t size);
OM_uint32
-gssEapDeriveRFC3961Key(OM_uint32 *minor,
- gss_buffer_t msk,
+gssEapDeriveRfc3961Key(OM_uint32 *minor,
+ const unsigned char *key,
+ size_t keyLength,
krb5_enctype enctype,
krb5_keyblock *pKey);
OM_uint32
gssEapKerberosInit(OM_uint32 *minor, krb5_context *context);
+OM_uint32
+rfc3961ChecksumTypeForKey(OM_uint32 *minor,
+ krb5_keyblock *key,
+ krb5_cksumtype *cksumtype);
+
#define GSSEAP_KRB_INIT(ctx) do { \
OM_uint32 tmpMajor; \
tmpMajor = gssEapKerberosInit(minor, ctx); \
int
gssEapIsMechanismOid(const gss_OID oid);
+int
+gssEapIsConcreteMechanismOid(const gss_OID oid);
+
OM_uint32
gssEapValidateMechs(OM_uint32 *minor,
const gss_OID_set mechs);
int
sequenceExternalize(void *vqueue, unsigned char **buf, size_t *lenremain);
-int
-sequenceSize(void *vqueue, size_t *sizep);
+size_t
+sequenceSize(void *vqueue);
void
sequenceFree(void **vqueue);
int do_replay, int do_sequence, int wide_nums);
/* util_token.c */
-enum gss_eap_token_type {
- TOK_TYPE_NONE = 0x0000, /* no token */
- TOK_TYPE_MIC = 0x0404, /* RFC 4121 MIC token */
- TOK_TYPE_WRAP = 0x0504, /* RFC 4121 wrap token */
- TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */
- TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* draft-ietf-kitten-gss-naming */
- TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */
- TOK_TYPE_EAP_RESP = 0x0601, /* draft-howlett-eap-gss */
- TOK_TYPE_EAP_REQ = 0x0602, /* draft-howlett-eap-gss */
- TOK_TYPE_GSS_CHANNEL_BINDINGS = 0x0603, /* draft-howlett-eap-gss */
-};
-
size_t
tokenSize(const gss_OID_desc *mech, size_t body_size);
unsigned char **buf,
enum gss_eap_token_type tok_type);
-int
-verifyTokenHeader(const gss_OID_desc * mech,
+OM_uint32
+verifyTokenHeader(OM_uint32 *minor,
+ gss_OID mech,
size_t *body_size,
unsigned char **buf_in,
size_t toksize_in,
return ((uint64_t)load_uint32_be(p) << 32) | load_uint32_be(p + 4);
}
-static OM_uint32
-makeStringBuffer(OM_uint32 *minor,
- const char *string,
- gss_buffer_t buffer)
+static inline unsigned char *
+store_buffer(gss_buffer_t buffer, void *vp, int wide_nums)
{
- size_t len = strlen(string);
+ unsigned char *p = (unsigned char *)vp;
- buffer->value = GSSEAP_MALLOC(len + 1);
- if (buffer->value == NULL) {
- *minor = ENOMEM;
- return GSS_S_FAILURE;
+ if (wide_nums) {
+ store_uint64_be(buffer->length, p);
+ p += 8;
+ } else {
+ store_uint32_be(buffer->length, p);
+ p += 4;
}
- memcpy(buffer->value, string, len + 1);
- buffer->length = len;
-
- *minor = 0;
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-bufferToString(OM_uint32 *minor,
- const gss_buffer_t buffer,
- char **pString)
-{
- char *s;
- s = GSSEAP_MALLOC(buffer->length + 1);
- if (s == NULL) {
- *minor = ENOMEM;
- return GSS_S_FAILURE;
+ if (buffer->value != NULL) {
+ memcpy(p, buffer->value, buffer->length);
+ p += buffer->length;
}
- memcpy(s, buffer->value, buffer->length);
- s[buffer->length] = '\0';
-
- *pString = s;
- *minor = 0;
- return GSS_S_COMPLETE;
+ return p;
}
-static OM_uint32
-duplicateBuffer(OM_uint32 *minor,
- const gss_buffer_t src,
- gss_buffer_t dst)
+static inline unsigned char *
+load_buffer(const void *cvp, size_t length, gss_buffer_t buffer)
{
- dst->length = 0;
- dst->value = NULL;
-
- if (src == GSS_C_NO_BUFFER)
- return GSS_S_COMPLETE;
+ buffer->length = 0;
+ buffer->value = GSSEAP_MALLOC(length);
+ if (buffer->value == NULL)
+ return NULL;
+ buffer->length = length;
+ memcpy(buffer->value, cvp, length);
+ return (unsigned char *)cvp + length;
+}
- dst->value = GSSEAP_MALLOC(src->length + 1);
- if (dst->value == NULL) {
- *minor = ENOMEM;
- return GSS_S_FAILURE;
+static inline unsigned char *
+store_oid(gss_OID oid, void *vp)
+{
+ gss_buffer_desc buf;
+
+ if (oid != GSS_C_NO_OID) {
+ buf.length = oid->length;
+ buf.value = oid->elements;
+ } else {
+ buf.length = 0;
+ buf.value = NULL;
}
- dst->length = src->length;
- memcpy(dst->value, src->value, dst->length);
-
- ((unsigned char *)dst->value)[dst->length] = '\0';
+ return store_buffer(&buf, vp, FALSE);
+}
- *minor = 0;
- return GSS_S_COMPLETE;
+#ifdef __cplusplus
}
+#endif
#endif /* _UTIL_H_ */