X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util.h;h=7d47e98b66523c67b5b248e47ef8869d21931ea7;hb=530b6b8e5bf392e22962e1e406ee85d7f9561b52;hp=246da381483c3d6fe939c6801e6681b42066c5c4;hpb=807a70e820e7e10df65ed14bc722b77b3f58c3df;p=mech_eap.git diff --git a/util.h b/util.h index 246da38..7d47e98 100644 --- a/util.h +++ b/util.h @@ -57,18 +57,163 @@ #ifndef _UTIL_H_ #define _UTIL_H_ 1 -/* Helper APIs */ +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MIN /* Usually found in . */ +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif + +#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_EXT_REQ = 0x0603, /* draft-howlett-eap-gss */ + TOK_TYPE_EXT_RESP = 0x0604, /* to be specified */ + TOK_TYPE_GSS_REAUTH = 0x0605, /* to be specified */ +}; + +#define EAP_EXPORT_CONTEXT_V1 1 + +/* util_alloc.c */ +void * +gssEapCalloc(size_t nmemb, size_t size); + +void * +gssEapMalloc(size_t size); + +void +gssEapFree(void *ptr); + +void * +gssEapRealloc(void *ptr, size_t size); + +/* 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, + 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); + +#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 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName); -OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName); - +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); + +OM_uint32 +gssEapContextTime(OM_uint32 *minor, + gss_ctx_id_t context_handle, + OM_uint32 *time_rec); + +OM_uint32 +gssEapDisplayName(OM_uint32 *minor, + gss_name_t name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type); + +/* 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); -/* Kerberos token services */ -#define KRB_KEYTYPE(key) ((key)->enctype) +OM_uint32 +gssEapAcquireCred(OM_uint32 *minor, + const gss_name_t desiredName, + const gss_buffer_t password, + OM_uint32 timeReq, + const gss_OID_set desiredMechs, + int cred_usage, + 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 @@ -104,55 +249,191 @@ 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); +OM_uint32 +gssEapDeriveRfc3961Key(OM_uint32 *minor, + const unsigned char *key, + size_t keyLength, + krb5_enctype enctype, + krb5_keyblock *pKey); + +/* util_krb.c */ +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); \ + if (GSS_ERROR(tmpMajor)) { \ + return tmpMajor; \ + } \ + } while (0) -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_lucid.c */ +OM_uint32 +gssEapExportLucidSecContext(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_OID desiredObject, + gss_buffer_set_t *data_set); -/* util_ordering.c */ -int -sequenceInternalize(void **vqueue, unsigned char **buf, size_t *lenremain); +/* util_mech.c */ +extern gss_OID GSS_EAP_MECHANISM; int -sequenceExternalize(void *vqueue, unsigned char **buf, size_t *lenremain); +gssEapInternalizeOid(const gss_OID oid, + gss_OID *const pInternalizedOid); -int -sequenceSize(void *vqueue, size_t *sizep); +OM_uint32 +gssEapDefaultMech(OM_uint32 *minor, + gss_OID *oid); -void -sequenceFree(void **vqueue); +OM_uint32 +gssEapIndicateMechs(OM_uint32 *minor, + gss_OID_set *mechs); + +OM_uint32 +gssEapEnctypeToOid(OM_uint32 *minor, + krb5_enctype enctype, + gss_OID *pOid); + +OM_uint32 +gssEapOidToEnctype(OM_uint32 *minor, + const gss_OID oid, + krb5_enctype *enctype); int -sequenceCheck(void **vqueue, uint64_t seqnum); +gssEapIsMechanismOid(const gss_OID oid); int -sequenceInit(void **vqueue, uint64_t seqnum, +gssEapIsConcreteMechanismOid(const gss_OID oid); + +OM_uint32 +gssEapValidateMechs(OM_uint32 *minor, + const gss_OID_set mechs); + +gss_buffer_t +gssEapOidToSaslName(const gss_OID oid); + +gss_OID +gssEapSaslNameToOid(const gss_buffer_t name); + +/* util_name.c */ +#define EXPORT_NAME_FLAG_OID 0x1 +#define EXPORT_NAME_FLAG_COMPOSITE 0x2 + +OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName); +OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName); +OM_uint32 gssEapExportName(OM_uint32 *minor, + const gss_name_t name, + gss_buffer_t exportedName); +OM_uint32 gssEapExportNameInternal(OM_uint32 *minor, + const gss_name_t name, + gss_buffer_t exportedName, + unsigned int flags); +OM_uint32 gssEapImportName(OM_uint32 *minor, + const gss_buffer_t input_name_buffer, + gss_OID input_name_type, + gss_name_t *output_name); +OM_uint32 gssEapImportNameInternal(OM_uint32 *minor, + const gss_buffer_t input_name_buffer, + gss_name_t *output_name, + unsigned int flags); +OM_uint32 +gssEapDuplicateName(OM_uint32 *minor, + const gss_name_t input_name, + gss_name_t *dest_name); + +/* util_oid.c */ +OM_uint32 +composeOid(OM_uint32 *minor_status, + const char *prefix, + size_t prefix_len, + int suffix, + gss_OID_desc *oid); + +OM_uint32 +decomposeOid(OM_uint32 *minor_status, + const char *prefix, + size_t prefix_len, + gss_OID_desc *oid, + int *suffix) ; + +OM_uint32 +duplicateOid(OM_uint32 *minor_status, + const gss_OID_desc * const oid, + gss_OID *new_oid); + +OM_uint32 +duplicateOidSet(OM_uint32 *minor, + const gss_OID_set src, + gss_OID_set *dst); + +static inline int +oidEqual(const gss_OID_desc *o1, const gss_OID_desc *o2) +{ + if (o1 == GSS_C_NO_OID) + return (o2 == GSS_C_NO_OID); + else if (o2 == GSS_C_NO_OID) + return (o1 == GSS_C_NO_OID); + else + return (o1->length == o2->length && + memcmp(o1->elements, o2->elements, o1->length) == 0); +} + +/* util_ordering.c */ +OM_uint32 +sequenceInternalize(OM_uint32 *minor, + void **vqueue, + unsigned char **buf, + size_t *lenremain); + +OM_uint32 +sequenceExternalize(OM_uint32 *minor, + void *vqueue, + unsigned char **buf, + size_t *lenremain); + +size_t +sequenceSize(void *vqueue); + +OM_uint32 +sequenceFree(OM_uint32 *minor, void **vqueue); + +OM_uint32 +sequenceCheck(OM_uint32 *minor, void **vqueue, uint64_t seqnum); + +OM_uint32 +sequenceInit(OM_uint32 *minor, void **vqueue, uint64_t seqnum, int do_replay, int do_sequence, int wide_nums); /* util_token.c */ size_t tokenSize(const gss_OID_desc *mech, size_t body_size); +void +makeTokenHeader(const gss_OID_desc *mech, + size_t body_size, + unsigned char **buf, + enum gss_eap_token_type tok_type); + +OM_uint32 +verifyTokenHeader(OM_uint32 *minor, + gss_OID mech, + size_t *body_size, + unsigned char **buf_in, + size_t toksize_in, + enum gss_eap_token_type *ret_tok_type); + /* 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_CALLOC(count, size) (gssEapCalloc((count), (size))) +#define GSSEAP_MALLOC(size) (gssEapMalloc((size))) +#define GSSEAP_FREE(ptr) (gssEapFree((ptr))) +#define GSSEAP_REALLOC(ptr, size) (gssEapRealloc((ptr), (size))) #define GSSEAP_NOT_IMPLEMENTED do { \ assert(0 && "not implemented"); \ @@ -160,6 +441,25 @@ tokenSize(const gss_OID_desc *mech, size_t body_size); return GSS_S_FAILURE; \ } while (0) +#include + +#define GSSEAP_MUTEX pthread_mutex_t +#define GSSEAP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#define GSSEAP_MUTEX_INIT(m) pthread_mutex_init((m), NULL) +#define GSSEAP_MUTEX_DESTROY(m) pthread_mutex_destroy((m)) +#define GSSEAP_MUTEX_LOCK(m) pthread_mutex_lock((m)) +#define GSSEAP_MUTEX_UNLOCK(m) pthread_mutex_unlock((m)) + +#define GSSEAP_THREAD_KEY pthread_key_t +#define GSSEAP_KEY_CREATE(k, d) pthread_key_create((k), (d)) +#define GSSEAP_GETSPECIFIC(k) pthread_getspecific((k)) +#define GSSEAP_SETSPECIFIC(k, d) pthread_setspecific((k), (d)) + +#define GSSEAP_THREAD_ONCE pthread_once_t +#define GSSEAP_ONCE(o, i) pthread_once((o), (i)) +#define GSSEAP_ONCE_INITIALIZER PTHREAD_ONCE_INIT + /* Helper functions */ static inline void store_uint16_be(uint16_t val, void *vp) @@ -222,11 +522,76 @@ load_uint64_be(const void *cvp) return ((uint64_t)load_uint32_be(p) << 32) | load_uint32_be(p + 4); } -static inline int -oidEqual(const gss_OID_desc *o1, const gss_OID_desc *o2) +static inline unsigned char * +store_buffer(gss_buffer_t buffer, void *vp, int wide_nums) { - return (o1->length == o2->length && - memcmp(o1->elements, o2->elements, o1->length) == 0); + unsigned char *p = (unsigned char *)vp; + + if (wide_nums) { + store_uint64_be(buffer->length, p); + p += 8; + } else { + store_uint32_be(buffer->length, p); + p += 4; + } + + if (buffer->value != NULL) { + memcpy(p, buffer->value, buffer->length); + p += buffer->length; + } + + return p; } +static inline unsigned char * +load_buffer(const void *cvp, size_t length, gss_buffer_t buffer) +{ + 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; +} + +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; + } + + return store_buffer(&buf, vp, FALSE); +} + +static inline void +krbDataToGssBuffer(krb5_data *data, gss_buffer_t buffer) +{ + buffer->value = (void *)data->data; + buffer->length = data->length; +} + +static inline void +gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data) +{ + data->data = (char *)buffer->value; + data->length = buffer->length; +} + +#ifdef __cplusplus +} +#endif + +#include "util_attr.h" +#ifdef GSSEAP_ENABLE_REAUTH +#include "util_reauth.h" +#endif + #endif /* _UTIL_H_ */