From 163856b1a70d7773c46d4ea5495b85c4dce0f089 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 31 Dec 2010 19:45:03 +1100 Subject: [PATCH] Heimdal portability fixes (except for reauth) --- Makefile.am | 10 +-- accept_sec_context.c | 14 ++-- acinclude.m4 | 3 + gssapiP_eap.h | 23 +++++- inquire_mech_for_saslname.c | 14 ++-- inquire_names_for_mech.c | 1 + radsec_err.et | 2 + unwrap_iov.c | 133 +++++++++++++++++++++------------ util.h | 114 ++++++++++++++++++++++++++++- util_attr.h | 5 ++ util_cksum.c | 45 +++++++++--- util_crypt.c | 127 ++++++++++++++++---------------- util_krb.c | 175 +++++++++++++++++++++++++++++++++++++++++++- util_name.c | 40 +++++++++- util_reauth.c | 2 +- wrap_iov.c | 49 ++++++++----- wrap_iov_length.c | 29 +++++--- 17 files changed, 604 insertions(+), 182 deletions(-) diff --git a/Makefile.am b/Makefile.am index f44d87b..fa81241 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,14 +8,14 @@ gss_LTLIBRARIES = mech_eap.la mech_eap_la_CPPFLAGS = -DBUILD_GSSEAP_LIB -DSYSCONFDIR=\"${sysconfdir}\" -DDATAROOTDIR=\"${datarootdir}\" mech_eap_la_CFLAGS = -g -Wall -fno-strict-aliasing \ - @EAP_CFLAGS@ @RADSEC_CFLAGS@ @KRB5_CFLAGS@ @TARGET_CFLAGS@ + @KRB5_CFLAGS@ @EAP_CFLAGS@ @RADSEC_CFLAGS@ @TARGET_CFLAGS@ mech_eap_la_CXXFLAGS = -g -Wall \ - @EAP_CFLAGS@ @RADSEC_CFLAGS@ @KRB5_CFLAGS@ \ + @KRB5_CFLAGS@ @EAP_CFLAGS@ @RADSEC_CFLAGS@ \ @SHIBSP_CXXFLAGS@ @SHIBRESOLVER_CXXFLAGS@ @TARGET_CFLAGS@ mech_eap_la_LDFLAGS = -avoid-version -module \ -export-symbols mech_eap.exports -no-undefined \ @EAP_LDFLAGS@ @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@ -mech_eap_la_LIBADD = @EAP_LIBS@ @RADSEC_LIBS@ @KRB5_LIBS@ @SHIBSP_LIBS@ \ +mech_eap_la_LIBADD = @KRB5_LIBS@ @EAP_LIBS@ @RADSEC_LIBS@ @SHIBSP_LIBS@ \ @SHIBRESOLVER_LIBS@ mech_eap_la_SOURCES = \ @@ -106,12 +106,12 @@ radius_ad_la_SOURCES = util_adshim.c endif gsseap_err.h: gsseap_err.et - $(prefix)/bin/compile_et $< + $(COMPILE_ET) $< gsseap_err.c: gsseap_err.h radsec_err.h: radsec_err.et - $(prefix)/bin/compile_et $< + $(COMPILE_ET) $< radsec_err.c: radsec_err.h diff --git a/accept_sec_context.c b/accept_sec_context.c index 7fa39ef..d7a4708 100644 --- a/accept_sec_context.c +++ b/accept_sec_context.c @@ -197,10 +197,10 @@ setAcceptorIdentity(OM_uint32 *minor, krbPrinc = ctx->acceptorName->krbPrincipal; assert(krbPrinc != NULL); - assert(krb5_princ_size(krbContext, krbPrinc) >= 2); + assert(KRB_PRINC_LENGTH(krbPrinc) >= 2); /* Acceptor-Service-Name */ - krbDataToGssBuffer(krb5_princ_component(krbContext, krbPrinc, 0), &nameBuf); + krbPrincComponentToGssBuffer(krbPrinc, 0, &nameBuf); major = gssEapRadiusAddAvp(minor, vps, PW_GSS_ACCEPTOR_SERVICE_NAME, @@ -210,7 +210,7 @@ setAcceptorIdentity(OM_uint32 *minor, return major; /* Acceptor-Host-Name */ - krbDataToGssBuffer(krb5_princ_component(krbContext, krbPrinc, 1), &nameBuf); + krbPrincComponentToGssBuffer(krbPrinc, 1, &nameBuf); major = gssEapRadiusAddAvp(minor, vps, PW_GSS_ACCEPTOR_HOST_NAME, @@ -219,13 +219,13 @@ setAcceptorIdentity(OM_uint32 *minor, if (GSS_ERROR(major)) return major; - if (krb5_princ_size(krbContext, krbPrinc) > 2) { + if (KRB_PRINC_LENGTH(krbPrinc) > 2) { /* Acceptor-Service-Specific */ krb5_principal_data ssiPrinc = *krbPrinc; char *ssi; - krb5_princ_size(krbContext, &ssiPrinc) -= 2; - krb5_princ_name(krbContext, &ssiPrinc) += 2; + KRB_PRINC_LENGTH(&ssiPrinc) -= 2; + KRB_PRINC_NAME(&ssiPrinc) += 2; *minor = krb5_unparse_name_flags(krbContext, &ssiPrinc, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &ssi); @@ -247,7 +247,7 @@ setAcceptorIdentity(OM_uint32 *minor, krb5_free_unparsed_name(krbContext, ssi); } - krbDataToGssBuffer(krb5_princ_realm(krbContext, krbPrinc), &nameBuf); + krbPrincRealmToGssBuffer(krbPrinc, &nameBuf); if (nameBuf.length != 0) { /* Acceptor-Realm-Name */ major = gssEapRadiusAddAvp(minor, vps, diff --git a/acinclude.m4 b/acinclude.m4 index 2cff774..242a1f0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -15,6 +15,7 @@ for dir in $check_krb5_dir /usr /usr/local ; do found_krb5="yes"; KRB5_CFLAGS=`$dir/bin/krb5-config gssapi --cflags`; KRB5_LIBS=`$dir/bin/krb5-config gssapi --libs`; + COMPILE_ET="$dir/bin/compile_et"; break; fi done @@ -32,9 +33,11 @@ else printf "Kerberos found in $krb5dir\n"; AC_SUBST(KRB5_CFLAGS) AC_SUBST(KRB5_LIBS) + AC_SUBST(COMPILE_ET) AC_CHECK_LIB(gssapi_krb5, GSS_C_NT_COMPOSITE_EXPORT, [AC_DEFINE_UNQUOTED([HAVE_GSS_C_NT_COMPOSITE_EXPORT], 1, [Define if GSS-API library supports recent naming extensions draft])], [], "$KRB5_LIBS") AC_CHECK_LIB(gssapi_krb5, gss_inquire_attrs_for_mech, [AC_DEFINE_UNQUOTED([HAVE_GSS_INQUIRE_ATTRS_FOR_MECH], 1, [Define if GSS-API library supports RFC 5587])], [], "$KRB5_LIBS") AC_CHECK_LIB(gssapi_krb5, gss_krb5_import_cred, [AC_DEFINE_UNQUOTED([HAVE_GSS_KRB5_IMPORT_CRED], 1, [Define if GSS-API library supports gss_krb5_import_cred])], [], "$KRB5_LIBS") + AC_CHECK_LIB(krb5, heimdal_version, [AC_DEFINE_UNQUOTED([HAVE_HEIMDAL_VERSION], 1, [Define if building against Heimdal Kerberos implementation])], [], "$KRB5_LIBS") fi ])dnl diff --git a/gssapiP_eap.h b/gssapiP_eap.h index 274d694..b53e131 100644 --- a/gssapiP_eap.h +++ b/gssapiP_eap.h @@ -46,7 +46,9 @@ /* GSS headers */ #include #include +#ifndef HAVE_HEIMDAL_VERSION #include +#endif #include "gssapi_eap.h" /* Kerberos headers */ @@ -89,7 +91,12 @@ extern "C" { struct gss_eap_saml_attr_ctx; struct gss_eap_attr_ctx; -struct gss_name_struct { +#ifdef HAVE_HEIMDAL_VERSION +struct gss_name_t_desc_struct +#else +struct gss_name_struct +#endif +{ GSSEAP_MUTEX mutex; /* mutex protects attrCtx */ OM_uint32 flags; krb5_principal krbPrincipal; /* this is immutable */ @@ -103,7 +110,12 @@ struct gss_name_struct { #define CRED_FLAG_DEFAULT_CCACHE 0x00100000 #define CRED_FLAG_PUBLIC_MASK 0x0000FFFF -struct gss_cred_id_struct { +#ifdef HAVE_HEIMDAL_VERSION +struct gss_cred_id_t_desc_struct +#else +struct gss_cred_id_struct +#endif +{ GSSEAP_MUTEX mutex; OM_uint32 flags; gss_name_t name; @@ -167,7 +179,12 @@ struct gss_eap_acceptor_ctx { VALUE_PAIR *vps; }; -struct gss_ctx_id_struct { +#ifdef HAVE_HEIMDAL_VERSION +struct gss_ctx_id_t_desc_struct +#else +struct gss_ctx_id_struct +#endif +{ GSSEAP_MUTEX mutex; enum gss_eap_state state; OM_uint32 flags; diff --git a/inquire_mech_for_saslname.c b/inquire_mech_for_saslname.c index 536f3c7..6de0399 100644 --- a/inquire_mech_for_saslname.c +++ b/inquire_mech_for_saslname.c @@ -46,18 +46,20 @@ gss_inquire_saslname_for_mech(OM_uint32 *minor, OM_uint32 major; gss_buffer_t name; krb5_enctype etype = ENCTYPE_NULL; - char krbBuf[128] = "eap-"; /* Dynamically construct mechanism name from Kerberos string enctype */ major = gssEapOidToEnctype(minor, mech, &etype); if (GSS_ERROR(major)) return major; - if (mech_name != GSS_C_NO_BUFFER && - krb5_enctype_to_name(etype, 0, &krbBuf[4], sizeof(krbBuf) - 4) == 0) { - major = makeStringBuffer(minor, krbBuf, mech_name); - if (GSS_ERROR(major)) - return major; + if (mech_name != GSS_C_NO_BUFFER) { + krb5_context krbContext; + + GSSEAP_KRB_INIT(&krbContext); + + *minor = krbEnctypeToString(krbContext, etype, "eap-", mech_name); + if (*minor != 0) + return GSS_S_FAILURE; } if (mech_description != GSS_C_NO_BUFFER) { diff --git a/inquire_names_for_mech.c b/inquire_names_for_mech.c index 7217e33..3f53217 100644 --- a/inquire_names_for_mech.c +++ b/inquire_names_for_mech.c @@ -50,6 +50,7 @@ gss_inquire_names_for_mech(OM_uint32 *minor, GSS_C_NT_COMPOSITE_EXPORT, #endif GSS_EAP_NT_PRINCIPAL_NAME, + GSS_C_NT_ANONYMOUS, }; size_t i; diff --git a/radsec_err.et b/radsec_err.et index 07aa549..887ef0a 100644 --- a/radsec_err.et +++ b/radsec_err.et @@ -33,4 +33,6 @@ # Placeholders only error_table rse +error_code GSSEAP_RSE_OK, "" + end diff --git a/unwrap_iov.c b/unwrap_iov.c index 8af08ef..e76f3d4 100644 --- a/unwrap_iov.c +++ b/unwrap_iov.c @@ -67,13 +67,18 @@ OM_uint32 unwrapToken(OM_uint32 *minor, gss_ctx_id_t ctx, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *unused __attribute__((__unused__)), +#endif 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; + OM_uint32 major = GSS_S_FAILURE, code; gss_iov_buffer_t header; gss_iov_buffer_t padding; gss_iov_buffer_t trailer; @@ -86,6 +91,9 @@ unwrapToken(OM_uint32 *minor, int valid = 0; int conf_flag = 0; krb5_context krbContext; +#ifdef HAVE_HEIMDAL_VERSION + int freeCrypto = (krbCrypto == NULL); +#endif GSSEAP_KRB_INIT(&krbContext); @@ -99,8 +107,9 @@ unwrapToken(OM_uint32 *minor, padding = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); if (padding != NULL && padding->buffer.length != 0) { - *minor = GSSEAP_BAD_PADDING_IOV; - return GSS_S_DEFECTIVE_TOKEN; + code = GSSEAP_BAD_PADDING_IOV; + major = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; } trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); @@ -122,17 +131,28 @@ unwrapToken(OM_uint32 *minor, ptr = (unsigned char *)header->buffer.value; if (header->buffer.length < 16) { - *minor = GSSEAP_TOK_TRUNC; - return GSS_S_DEFECTIVE_TOKEN; + code = GSSEAP_TOK_TRUNC; + major = GSS_S_DEFECTIVE_TOKEN; + goto cleanup; } if ((ptr[2] & flags) != flags) { - *minor = GSSEAP_BAD_DIRECTION; - return GSS_S_BAD_SIG; + code = GSSEAP_BAD_DIRECTION; + major = GSS_S_BAD_SIG; + goto cleanup; } +#ifdef HAVE_HEIMDAL_VERSION + if (krbCrypto == NULL) { + code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, + ETYPE_NULL, &krbCrypto); + if (code != 0) + goto cleanup; + } +#endif + if (toktype == TOK_TYPE_WRAP) { - unsigned int krbTrailerLen; + size_t krbTrailerLen; if (load_uint16_be(ptr) != TOK_TYPE_WRAP) goto defective; @@ -143,15 +163,12 @@ unwrapToken(OM_uint32 *minor, rrc = load_uint16_be(ptr + 6); seqnum = load_uint64_be(ptr + 8); - code = krb5_c_crypto_length(krbContext, - ctx->encryptionType, - conf_flag ? KRB5_CRYPTO_TYPE_TRAILER : - KRB5_CRYPTO_TYPE_CHECKSUM, - &krbTrailerLen); - if (code != 0) { - *minor = code; - return GSS_S_FAILURE; - } + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + conf_flag ? KRB5_CRYPTO_TYPE_TRAILER : + KRB5_CRYPTO_TYPE_CHECKSUM, + &krbTrailerLen); + if (code != 0) + goto cleanup; /* Deal with RRC */ if (trailer == NULL) { @@ -177,11 +194,11 @@ unwrapToken(OM_uint32 *minor, /* Decrypt */ code = gssEapDecrypt(krbContext, ((ctx->gssFlags & GSS_C_DCE_STYLE) != 0), - ec, rrc, &ctx->rfc3961Key, - keyUsage, 0, iov, iov_count); + ec, rrc, KRB_CRYPTO_CONTEXT(ctx), keyUsage, + iov, iov_count); if (code != 0) { - *minor = code; - return GSS_S_BAD_SIG; + major = GSS_S_BAD_SIG; + goto cleanup; } /* Validate header integrity */ @@ -194,8 +211,9 @@ unwrapToken(OM_uint32 *minor, || althdr[2] != ptr[2] || althdr[3] != ptr[3] || memcmp(althdr + 8, ptr + 8, 8) != 0) { - *minor = GSSEAP_BAD_WRAP_TOKEN; - return GSS_S_BAD_SIG; + code = GSSEAP_BAD_WRAP_TOKEN; + major = GSS_S_BAD_SIG; + goto cleanup; } } else { /* Verify checksum: note EC is checksum size here, not padding */ @@ -207,11 +225,11 @@ unwrapToken(OM_uint32 *minor, store_uint16_be(0, ptr + 6); code = gssEapVerify(krbContext, ctx->checksumType, rrc, - &ctx->rfc3961Key, keyUsage, + KRB_CRYPTO_CONTEXT(ctx), keyUsage, iov, iov_count, &valid); if (code != 0 || valid == FALSE) { - *minor = code; - return GSS_S_BAD_SIG; + major = GSS_S_BAD_SIG; + goto cleanup; } } @@ -226,11 +244,11 @@ unwrapToken(OM_uint32 *minor, seqnum = load_uint64_be(ptr + 8); code = gssEapVerify(krbContext, ctx->checksumType, 0, - &ctx->rfc3961Key, keyUsage, + KRB_CRYPTO_CONTEXT(ctx), keyUsage, iov, iov_count, &valid); if (code != 0 || valid == FALSE) { - *minor = code; - return GSS_S_BAD_SIG; + major = GSS_S_BAD_SIG; + goto cleanup; } code = sequenceCheck(minor, &ctx->seqState, seqnum); } else if (toktype == TOK_TYPE_DELETE_CONTEXT) { @@ -241,17 +259,25 @@ unwrapToken(OM_uint32 *minor, goto defective; } - *minor = 0; - if (conf_state != NULL) *conf_state = conf_flag; - return code; + code = 0; + major = GSS_S_COMPLETE; + goto cleanup; defective: - *minor = GSSEAP_BAD_WRAP_TOKEN; + code = GSSEAP_BAD_WRAP_TOKEN; + major = GSS_S_DEFECTIVE_TOKEN; - return GSS_S_DEFECTIVE_TOKEN; +cleanup: + *minor = code; +#ifdef HAVE_HEIMDAL_VERSION + if (freeCrypto && krbCrypto != NULL) + krb5_crypto_destroy(krbContext, krbCrypto); +#endif + + return major; } int @@ -298,6 +324,9 @@ unwrapStream(OM_uint32 *minor, gss_iov_buffer_desc *tiov = NULL; gss_iov_buffer_t stream, data = NULL; gss_iov_buffer_t theader, tdata = NULL, tpadding, ttrailer; +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto = NULL; +#endif GSSEAP_KRB_INIT(&krbContext); @@ -367,10 +396,16 @@ unwrapStream(OM_uint32 *minor, ttrailer = &tiov[i++]; ttrailer->type = GSS_IOV_BUFFER_TYPE_TRAILER; +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, ETYPE_NULL, &krbCrypto); + if (code != 0) + goto cleanup; +#endif + { size_t ec, rrc; - unsigned int krbHeaderLen = 0; - unsigned int krbTrailerLen = 0; + size_t krbHeaderLen = 0; + size_t krbTrailerLen = 0; conf_req_flag = ((ptr[0] & TOK_FLAG_WRAP_CONFIDENTIAL) != 0); ec = conf_req_flag ? load_uint16_be(ptr + 2) : 0; @@ -385,19 +420,19 @@ unwrapStream(OM_uint32 *minor, } if (conf_req_flag) { - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); if (code != 0) goto cleanup; theader->buffer.length += krbHeaderLen; /* length validated later */ } /* no PADDING for CFX, EC is used instead */ - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - conf_req_flag - ? KRB5_CRYPTO_TYPE_TRAILER - : KRB5_CRYPTO_TYPE_CHECKSUM, - &krbTrailerLen); + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + conf_req_flag + ? KRB5_CRYPTO_TYPE_TRAILER + : KRB5_CRYPTO_TYPE_CHECKSUM, + &krbTrailerLen); if (code != 0) goto cleanup; @@ -441,8 +476,8 @@ unwrapStream(OM_uint32 *minor, assert(i <= iov_count + 2); - major = unwrapToken(&code, ctx, conf_state, qop_state, - tiov, i, toktype); + major = unwrapToken(&code, ctx, KRB_CRYPTO_CONTEXT(ctx), + conf_state, qop_state, tiov, i, toktype); if (major == GSS_S_COMPLETE) { *data = *tdata; } else if (tdata->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { @@ -455,6 +490,10 @@ unwrapStream(OM_uint32 *minor, cleanup: if (tiov != NULL) GSSEAP_FREE(tiov); +#ifdef HAVE_HEIMDAL_VERSION + if (krbCrypto != NULL) + krb5_crypto_destroy(krbContext, krbCrypto); +#endif *minor = code; @@ -481,7 +520,9 @@ gssEapUnwrapOrVerifyMIC(OM_uint32 *minor, major = unwrapStream(minor, ctx, conf_state, qop_state, iov, iov_count, toktype); } else { - major = unwrapToken(minor, ctx, conf_state, qop_state, + major = unwrapToken(minor, ctx, + NULL, /* krbCrypto */ + conf_state, qop_state, iov, iov_count, toktype); } diff --git a/util.h b/util.h index de8dcb8..16af15e 100644 --- a/util.h +++ b/util.h @@ -114,7 +114,11 @@ int gssEapSign(krb5_context context, krb5_cksumtype type, size_t rrc, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else krb5_keyblock *key, +#endif krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count); @@ -123,7 +127,11 @@ int gssEapVerify(krb5_context context, krb5_cksumtype type, size_t rrc, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else krb5_keyblock *key, +#endif krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, @@ -202,15 +210,27 @@ int gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech); /* 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, + size_t rrc, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *key, +#endif + int usage, 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, + size_t rrc, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *key, +#endif + int usage, gss_iov_buffer_desc *iov, int iov_count); -krb5_cryptotype +int gssEapMapCryptoFlag(OM_uint32 type); gss_iov_buffer_t @@ -279,15 +299,41 @@ gssEapVerifyExtensions(OM_uint32 *minor, const gss_buffer_t buffer); /* util_krb.c */ +#ifdef HAVE_HEIMDAL_VERSION +#define KRB_KEY_TYPE(key) ((key)->keytype) +#define KRB_KEY_DATA(key) ((key)->keyvalue.data) +#define KRB_KEY_LENGTH(key) ((key)->keyvalue.length) +#else #define KRB_KEY_TYPE(key) ((key)->enctype) #define KRB_KEY_DATA(key) ((key)->contents) #define KRB_KEY_LENGTH(key) ((key)->length) +#endif /* HAVE_HEIMDAL_VERSION */ + #define KRB_KEY_INIT(key) do { \ KRB_KEY_TYPE(key) = ENCTYPE_NULL; \ KRB_KEY_DATA(key) = NULL; \ KRB_KEY_LENGTH(key) = 0; \ } while (0) +#ifdef HAVE_HEIMDAL_VERSION +#define KRB_PRINC_LENGTH(princ) ((princ)->name.name_string.len) +#define KRB_PRINC_TYPE(princ) ((princ)->name.name_type) +#define KRB_PRINC_NAME(princ) ((princ)->name.name_string.val) +#define KRB_CRYPTO_CONTEXT(ctx) (krbCrypto) +#else +#define KRB_PRINC_LENGTH(princ) (krb5_princ_size(NULL, (princ))) +#define KRB_PRINC_TYPE(princ) (krb5_princ_type(NULL, (princ))) +#define KRB_PRINC_NAME(princ) (krb5_princ_name(NULL, (princ))) +#define KRB_CRYPTO_CONTEXT(ctx) (&(ctx)->rfc3961Key) +#endif /* HAVE_HEIMDAL_VERSION */ + +#ifdef HAVE_HEIMDAL_VERSION +#define GSS_IOV_BUFFER_FLAG_ALLOCATE GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE +#define GSS_IOV_BUFFER_FLAG_ALLOCATED GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED + +#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE +#endif + #define GSSEAP_KRB_INIT(ctx) do { \ OM_uint32 tmpMajor; \ \ @@ -305,6 +351,44 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor, krb5_keyblock *key, krb5_cksumtype *cksumtype); +krb5_const_principal +krbAnonymousPrincipal(void); + +krb5_error_code +krbCryptoLength(krb5_context krbContext, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *key, +#endif + int type, + size_t *length); + +krb5_error_code +krbPaddingLength(krb5_context krbContext, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *key, +#endif + size_t dataLength, + size_t *padLength); + +krb5_error_code +krbBlockSize(krb5_context krbContext, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *key, +#endif + size_t *blockSize); + +krb5_error_code +krbEnctypeToString(krb5_context krbContext, + krb5_enctype enctype, + const char *prefix, + gss_buffer_t string); + /* util_lucid.c */ OM_uint32 gssEapExportLucidSecContext(OM_uint32 *minor, @@ -611,6 +695,30 @@ krbDataToGssBuffer(krb5_data *data, gss_buffer_t buffer) } static inline void +krbPrincComponentToGssBuffer(krb5_principal krbPrinc, + int index, gss_buffer_t buffer) +{ +#ifdef HAVE_HEIMDAL_VERSION + buffer->value = (void *)krbPrinc->name.name_string.val[index]; + buffer->length = strlen((char *)buffer->value); +#else + buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data; + buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length; +#endif /* HAVE_HEIMDAL_VERSION */ +} + +static inline void +krbPrincRealmToGssBuffer(krb5_principal krbPrinc, gss_buffer_t buffer) +{ +#ifdef HAVE_HEIMDAL_VERSION + buffer->value = (void *)krbPrinc->realm; + buffer->length = strlen(krbPrinc->realm); +#else + krbDataToGssBuffer(krb5_princ_realm(NULL, krbPrinc), buffer); +#endif +} + +static inline void gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data) { data->data = (char *)buffer->value; diff --git a/util_attr.h b/util_attr.h index e55e9a9..01f8e2f 100644 --- a/util_attr.h +++ b/util_attr.h @@ -37,6 +37,11 @@ #ifndef _UTIL_ATTR_H_ #define _UTIL_ATTR_H_ 1 +#ifdef HAVE_HEIMDAL_VERSION +/* Removed in draft-ietf-kitten-gssapi-naming-exts-08 */ +typedef struct gss_any *gss_any_t; +#endif + #ifdef __cplusplus #include #include diff --git a/util_cksum.c b/util_cksum.c index 9616e9c..cbd531d 100644 --- a/util_cksum.c +++ b/util_cksum.c @@ -61,7 +61,11 @@ static int gssEapChecksum(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *crypto, +#endif krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, @@ -74,13 +78,15 @@ gssEapChecksum(krb5_context context, krb5_crypto_iov *kiov; size_t kiov_count; int i = 0, j; - unsigned int k5_checksumlen; + size_t k5_checksumlen; +#ifdef HAVE_HEIMDAL_VERSION + krb5_cksumtype cksumtype; +#endif if (verify) *valid = FALSE; - code = krb5_c_crypto_length(context, KRB_KEY_TYPE(key), - KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen); + code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen); if (code != 0) return code; @@ -130,17 +136,28 @@ gssEapChecksum(krb5_context context, } i++; +#ifdef HAVE_HEIMDAL_VERSION + if (verify) { + code = krb5_verify_checksum_iov(context, crypto, sign_usage, + kiov, kiov_count, &cksumtype); + *valid = (code == 0); + } else { + code = krb5_create_checksum_iov(context, crypto, sign_usage, + kiov, kiov_count, &cksumtype); + } +#else if (verify) { krb5_boolean kvalid = FALSE; - code = krb5_c_verify_checksum_iov(context, type, key, + code = krb5_c_verify_checksum_iov(context, type, crypto, sign_usage, kiov, kiov_count, &kvalid); *valid = kvalid; } else { - code = krb5_c_make_checksum_iov(context, type, key, + code = krb5_c_make_checksum_iov(context, type, crypto, sign_usage, kiov, kiov_count); } +#endif /* HAVE_HEIMDAL_VERSION */ GSSEAP_FREE(kiov); @@ -151,12 +168,16 @@ int gssEapSign(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *crypto, +#endif krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count) { - return gssEapChecksum(context, type, rrc, key, + return gssEapChecksum(context, type, rrc, crypto, sign_usage, iov, iov_count, 0, NULL); } @@ -164,13 +185,17 @@ int gssEapVerify(krb5_context context, krb5_cksumtype type, size_t rrc, - krb5_keyblock *key, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *crypto, +#endif krb5_keyusage sign_usage, gss_iov_buffer_desc *iov, int iov_count, int *valid) { - return gssEapChecksum(context, type, rrc, key, + return gssEapChecksum(context, type, rrc, crypto, sign_usage, iov, iov_count, 1, valid); } diff --git a/util_crypt.c b/util_crypt.c index 62e880e..9841c9d 100644 --- a/util_crypt.c +++ b/util_crypt.c @@ -90,7 +90,12 @@ */ static krb5_error_code mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc, - krb5_enctype enctype, gss_iov_buffer_desc *iov, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *crypto, +#endif + gss_iov_buffer_desc *iov, int iov_count, krb5_crypto_iov **pkiov, size_t *pkiov_count) { @@ -99,7 +104,7 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc, int i = 0, j; size_t kiov_count; krb5_crypto_iov *kiov; - unsigned int k5_headerlen = 0, k5_trailerlen = 0; + size_t k5_headerlen = 0, k5_trailerlen = 0; size_t gss_headerlen, gss_trailerlen; krb5_error_code code; @@ -112,13 +117,11 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc, trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); assert(trailer == NULL || rrc == 0); - code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_HEADER, - &k5_headerlen); + code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); if (code != 0) return code; - code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_TRAILER, - &k5_trailerlen); + code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); if (code != 0) return code; @@ -198,89 +201,83 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc, } 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) +gssEapEncrypt(krb5_context context, + int dce_style, + size_t ec, + size_t rrc, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *crypto, +#endif + int usage, + gss_iov_buffer_desc *iov, + int iov_count) { krb5_error_code code; - size_t blocksize; - krb5_data ivd, *pivd; size_t kiov_count; - krb5_crypto_iov *kiov; + krb5_crypto_iov *kiov = NULL; - if (iv) { - code = krb5_c_block_size(context, KRB_KEY_TYPE(key), &blocksize); - if (code) - return(code); - - ivd.length = blocksize; - ivd.data = GSSEAP_MALLOC(ivd.length); - if (ivd.data == NULL) - return ENOMEM; - memcpy(ivd.data, iv, ivd.length); - pivd = &ivd; - } else { - pivd = NULL; - } + code = mapIov(context, dce_style, ec, rrc, crypto, + iov, iov_count, &kiov, &kiov_count); + if (code != 0) + goto cleanup; - code = mapIov(context, dce_style, ec, rrc, - KRB_KEY_TYPE(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); - } +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_encrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL); +#else + code = krb5_c_encrypt_iov(context, crypto, usage, NULL, kiov, kiov_count); +#endif + if (code != 0) + goto cleanup; - if (pivd != NULL) - GSSEAP_FREE(pivd->data); +cleanup: + if (kiov != NULL) + GSSEAP_FREE(kiov); return code; } 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) +gssEapDecrypt(krb5_context context, + int dce_style, + size_t ec, + size_t rrc, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto crypto, +#else + krb5_keyblock *crypto, +#endif + int usage, + gss_iov_buffer_desc *iov, + int iov_count) { krb5_error_code code; - size_t blocksize; - krb5_data ivd, *pivd; size_t kiov_count; krb5_crypto_iov *kiov; - if (iv) { - code = krb5_c_block_size(context, KRB_KEY_TYPE(key), &blocksize); - if (code) - return(code); - - ivd.length = blocksize; - ivd.data = GSSEAP_MALLOC(ivd.length); - if (ivd.data == NULL) - return ENOMEM; - memcpy(ivd.data, iv, ivd.length); - pivd = &ivd; - } else { - pivd = NULL; - } + code = mapIov(context, dce_style, ec, rrc, crypto, + iov, iov_count, &kiov, &kiov_count); + if (code != 0) + goto cleanup; - code = mapIov(context, dce_style, ec, rrc, - KRB_KEY_TYPE(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); - } +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_decrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL); +#else + code = krb5_c_decrypt_iov(context, crypto, usage, NULL, kiov, kiov_count); +#endif - if (pivd != NULL) - GSSEAP_FREE(pivd->data); +cleanup: + if (kiov != NULL) + GSSEAP_FREE(kiov); return code; } -krb5_cryptotype +int gssEapMapCryptoFlag(OM_uint32 type) { - krb5_cryptotype ktype; + int ktype; switch (GSS_IOV_BUFFER_TYPE(type)) { case GSS_IOV_BUFFER_TYPE_DATA: diff --git a/util_krb.c b/util_krb.c index 4cc4b14..82d6c50 100644 --- a/util_krb.c +++ b/util_krb.c @@ -93,7 +93,10 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, krb5_keyblock *pKey) { krb5_context krbContext; - krb5_data data, ns, t, prfOut; +#ifndef HAVE_HEIMDAL_VERSION + krb5_data data; +#endif + krb5_data ns, t, prfOut; krb5_keyblock kd; krb5_error_code code; size_t randomLength, keyLength, prfLength; @@ -120,9 +123,6 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, if (code != 0) goto cleanup; - data.length = MIN(inputKeyLength, randomLength); - data.data = (char *)inputKey; - KRB_KEY_DATA(&kd) = GSSEAP_MALLOC(keyLength); if (KRB_KEY_DATA(&kd) == NULL) { code = ENOMEM; @@ -131,7 +131,15 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, KRB_KEY_LENGTH(&kd) = keyLength; /* Convert MSK into a Kerberos key */ +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_random_to_key(krbContext, encryptionType, inputKey, + MIN(inputKeyLength, randomLength), &kd); +#else + data.length = MIN(inputKeyLength, randomLength); + data.data = (char *)inputKey; + code = krb5_c_random_to_key(krbContext, encryptionType, &data, &kd); +#endif if (code != 0) goto cleanup; @@ -174,7 +182,12 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, } /* Finally, convert PRF output into a new key which we will return */ +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_random_to_key(krbContext, encryptionType, + prfOut.data, prfOut.length, &kd); +#else code = krb5_c_random_to_key(krbContext, encryptionType, &prfOut, &kd); +#endif if (code != 0) goto cleanup; @@ -236,7 +249,11 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor, if (*minor != 0) return GSS_S_FAILURE; +#ifdef HAVE_HEIMDAL_VERSION + *cksumtype = cksum.cksumtype; +#else *cksumtype = cksum.checksum_type; +#endif krb5_free_checksum_contents(krbContext, &cksum); #endif /* HAVE_KRB5INT_C_MANDATORY_CKSUMTYPE */ @@ -248,3 +265,153 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor, return GSS_S_COMPLETE; } + +#ifdef HAVE_HEIMDAL_VERSION +static heim_general_string krbAnonymousPrincipalComponents[] = + { KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME }; + +static const Principal krbAnonymousPrincipalData = { + { KRB5_NT_WELLKNOWN, { 2, krbAnonymousPrincipalComponents } }, + "WELLKNOWN:ANONYMOUS" +}; +#endif + +krb5_const_principal +krbAnonymousPrincipal(void) +{ +#ifdef HAVE_HEIMDAL_VERSION + return &krbAnonymousPrincipalData; +#else + return krb5_anonymous_principal(); +#endif +} + +krb5_error_code +krbCryptoLength(krb5_context krbContext, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *key, +#endif + int type, + size_t *length) +{ +#ifdef HAVE_HEIMDAL_VERSION + return krb5_crypto_length(krbContext, krbCrypto, type, length); +#else + unsigned int len; + krb5_error_code code; + + code = krb5_c_crypto_length(krbContext, KRB_KEY_TYPE(key), type, &len); + if (code == 0) + *length = (size_t)len; + + return code; +#endif +} + +krb5_error_code +krbPaddingLength(krb5_context krbContext, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *key, +#endif + size_t dataLength, + size_t *padLength) +{ + krb5_error_code code; +#ifdef HAVE_HEIMDAL_VERSION + size_t headerLength, paddingLength; + + code = krbCryptoLength(krbContext, krbCrypto, + KRB5_CRYPTO_TYPE_HEADER, &headerLength); + if (code != 0) + return code; + + dataLength += headerLength; + + code = krb5_crypto_length(krbContext, krbCrypto, + KRB5_CRYPTO_TYPE_PADDING, &paddingLength); + if (code != 0) + return code; + + if (paddingLength != 0 && (dataLength % paddingLength) != 0) + *padLength = paddingLength - (dataLength % paddingLength); + else + *padLength = 0; + + return 0; +#else + unsigned int pad; + + code = krb5_c_padding_length(krbContext, KRB_KEY_TYPE(key), dataLength, &pad); + if (code == 0) + *padLength = (size_t)pad; + + return code; +#endif /* HAVE_HEIMDAL_VERSION */ +} + +krb5_error_code +krbBlockSize(krb5_context krbContext, +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto, +#else + krb5_keyblock *key, +#endif + size_t *blockSize) +{ +#ifdef HAVE_HEIMDAL_VERSION + return krb5_crypto_getblocksize(krbContext, krbCrypto, blockSize); +#else + return krb5_c_block_size(krbContext, KRB_KEY_TYPE(key), blockSize); +#endif +} + +krb5_error_code +krbEnctypeToString(krb5_context krbContext, + krb5_enctype enctype, + const char *prefix, + gss_buffer_t string) +{ + krb5_error_code code; +#ifdef HAVE_HEIMDAL_VERSION + char *enctypeBuf = NULL; +#else + char enctypeBuf[128]; +#endif + size_t prefixLength, enctypeLength; + +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_enctype_to_string(krbContext, enctype, &enctypeBuf); +#else + code = krb5_enctype_to_name(enctype, 0, enctypeBuf, sizeof(enctypeBuf)); +#endif + if (code != 0) + return code; + + prefixLength = (prefix != NULL) ? strlen(prefix) : 0; + enctypeLength = strlen(enctypeBuf); + + string->value = GSSEAP_MALLOC(prefixLength + enctypeLength + 1); + if (string->value == NULL) { +#ifdef HAVE_HEIMDAL_VERSION + krb5_xfree(enctypeBuf); +#endif + return ENOMEM; + } + + if (prefixLength != 0) + memcpy(string->value, prefix, prefixLength); + memcpy((char *)string->value + prefixLength, enctypeBuf, enctypeLength); + + string->length = prefixLength + enctypeLength; + ((char *)string->value)[string->length] = '\0'; + +#ifdef HAVE_HEIMDAL_VERSION + krb5_xfree(enctypeBuf); +#endif + + return 0; +} diff --git a/util_name.c b/util_name.c index 9bceb3b..b1475f8 100644 --- a/util_name.c +++ b/util_name.c @@ -136,7 +136,7 @@ krbPrincipalToName(OM_uint32 *minor, name->krbPrincipal = *principal; *principal = NULL; - if (name->krbPrincipal->length > 1) { + if (KRB_PRINC_LENGTH(name->krbPrincipal) > 1) { name->flags |= NAME_FLAG_SERVICE; } else { name->flags |= NAME_FLAG_NAI; @@ -201,7 +201,7 @@ importUserName(OM_uint32 *minor, if (nameBuffer == GSS_C_NO_BUFFER) { *minor = krb5_copy_principal(krbContext, - krb5_anonymous_principal(), &krbPrinc); + krbAnonymousPrincipal(), &krbPrinc); if (*minor != 0) return GSS_S_FAILURE; } else { @@ -225,6 +225,30 @@ importUserName(OM_uint32 *minor, return major; } +static OM_uint32 +importAnonymousName(OM_uint32 *minor, + const gss_buffer_t nameBuffer, + gss_name_t *pName) +{ + OM_uint32 major; + krb5_context krbContext; + krb5_principal krbPrinc; + + GSSEAP_KRB_INIT(&krbContext); + + *minor = krb5_copy_principal(krbContext, krbAnonymousPrincipal(), + &krbPrinc); + if (*minor != 0) + return GSS_S_FAILURE; + + major = krbPrincipalToName(minor, &krbPrinc, pName); + if (GSS_ERROR(major)) { + krb5_free_principal(krbContext, krbPrinc); + } + + return major; +} + #define UPDATE_REMAIN(n) do { \ p += (n); \ remain -= (n); \ @@ -361,6 +385,7 @@ gssEapImportName(OM_uint32 *minor, { GSS_EAP_NT_PRINCIPAL_NAME, importUserName }, { GSS_C_NT_HOSTBASED_SERVICE, importServiceName }, { GSS_C_NT_HOSTBASED_SERVICE_X, importServiceName }, + { GSS_C_NT_ANONYMOUS, importAnonymousName }, { GSS_C_NT_EXPORT_NAME, importExportName }, #ifdef HAVE_GSS_C_NT_COMPOSITE_EXPORT { GSS_C_NT_COMPOSITE_EXPORT, importCompositeExportName }, @@ -536,6 +561,7 @@ gssEapDisplayName(OM_uint32 *minor, OM_uint32 major; krb5_context krbContext; char *krbName; + gss_OID name_type; GSSEAP_KRB_INIT(&krbContext); @@ -560,8 +586,16 @@ gssEapDisplayName(OM_uint32 *minor, krb5_free_unparsed_name(krbContext, krbName); + if (KRB_PRINC_TYPE(name->krbPrincipal) == KRB5_NT_WELLKNOWN && + krb5_principal_compare(krbContext, + name->krbPrincipal, krbAnonymousPrincipal())) { + name_type = GSS_C_NT_ANONYMOUS; + } else { + name_type = GSS_EAP_NT_PRINCIPAL_NAME; + } + if (output_name_type != NULL) - *output_name_type = GSS_EAP_NT_PRINCIPAL_NAME; + *output_name_type = name_type; return GSS_S_COMPLETE; } diff --git a/util_reauth.c b/util_reauth.c index 7806671..47be2a3 100644 --- a/util_reauth.c +++ b/util_reauth.c @@ -275,7 +275,7 @@ static int isTicketGrantingServiceP(krb5_context krbContext, krb5_const_principal principal) { - if (krb5_princ_size(krbContext, principal) == 2 && + if (KRB_PRINC_LENGTH(principal) == 2 && krb5_princ_component(krbContext, principal, 0)->length == 6 && memcmp(krb5_princ_component(krbContext, principal, 0)->data, "krbtgt", 6) == 0) diff --git a/wrap_iov.c b/wrap_iov.c index ed9be57..19f263c 100644 --- a/wrap_iov.c +++ b/wrap_iov.c @@ -98,9 +98,12 @@ gssEapWrapOrGetMIC(OM_uint32 *minor, unsigned char *tbuf = NULL; int keyUsage; size_t rrc = 0; - unsigned int gssHeaderLen, gssTrailerLen; + size_t gssHeaderLen, gssTrailerLen; size_t dataLen, assocDataLen; krb5_context krbContext; +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto = NULL; +#endif if (ctx->encryptionType == ENCTYPE_NULL) { *minor = GSSEAP_KEY_UNAVAILABLE; @@ -135,32 +138,37 @@ gssEapWrapOrGetMIC(OM_uint32 *minor, trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, ETYPE_NULL, &krbCrypto); + if (code != 0) + goto cleanup; +#endif + if (toktype == TOK_TYPE_WRAP && conf_req_flag) { - unsigned int krbHeaderLen, krbTrailerLen, krbPadLen; - size_t ec = 0; - size_t confDataLen = dataLen - assocDataLen; + size_t krbHeaderLen, krbTrailerLen, krbPadLen; + size_t ec = 0, confDataLen = dataLen - assocDataLen; - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); if (code != 0) goto cleanup; - code = krb5_c_padding_length(krbContext, ctx->encryptionType, - confDataLen + 16 /* E(Header) */, - &krbPadLen); + code = krbPaddingLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + confDataLen + 16 /* E(Header) */, + &krbPadLen); if (code != 0) goto cleanup; if (krbPadLen == 0 && (ctx->gssFlags & GSS_C_DCE_STYLE)) { /* Windows rejects AEAD tokens with non-zero EC */ - code = krb5_c_block_size(krbContext, ctx->encryptionType, &ec); + code = krbBlockSize(krbContext, KRB_CRYPTO_CONTEXT(ctx), &ec); if (code != 0) goto cleanup; } else ec = krbPadLen; - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - KRB5_CRYPTO_TYPE_TRAILER, &krbTrailerLen); + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + KRB5_CRYPTO_TYPE_TRAILER, &krbTrailerLen); if (code != 0) goto cleanup; @@ -221,8 +229,8 @@ gssEapWrapOrGetMIC(OM_uint32 *minor, code = gssEapEncrypt(krbContext, ((ctx->gssFlags & GSS_C_DCE_STYLE) != 0), - ec, rrc, &ctx->rfc3961Key, - keyUsage, 0, iov, iov_count); + ec, rrc, KRB_CRYPTO_CONTEXT(ctx), + keyUsage, iov, iov_count); if (code != 0) goto cleanup; @@ -235,9 +243,8 @@ gssEapWrapOrGetMIC(OM_uint32 *minor, gssHeaderLen = 16; - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - KRB5_CRYPTO_TYPE_CHECKSUM, - &gssTrailerLen); + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + KRB5_CRYPTO_TYPE_CHECKSUM, &gssTrailerLen); if (code != 0) goto cleanup; @@ -288,8 +295,8 @@ gssEapWrapOrGetMIC(OM_uint32 *minor, } store_uint64_be(ctx->sendSeq, outbuf + 8); - code = gssEapSign(krbContext, ctx->checksumType, - rrc, &ctx->rfc3961Key, keyUsage, + code = gssEapSign(krbContext, ctx->checksumType, rrc, + KRB_CRYPTO_CONTEXT(ctx), keyUsage, iov, iov_count); if (code != 0) goto cleanup; @@ -319,6 +326,10 @@ gssEapWrapOrGetMIC(OM_uint32 *minor, cleanup: if (code != 0) gssEapReleaseIov(iov, iov_count); +#ifdef HAVE_HEIMDAL_VERSION + if (krbCrypto != NULL) + krb5_crypto_destroy(krbContext, krbCrypto); +#endif *minor = code; diff --git a/wrap_iov_length.c b/wrap_iov_length.c index c3372e9..134ecc8 100644 --- a/wrap_iov_length.c +++ b/wrap_iov_length.c @@ -75,11 +75,14 @@ gssEapWrapIovLength(OM_uint32 *minor, gss_iov_buffer_t header, trailer, padding; size_t dataLength, assocDataLength; size_t gssHeaderLen, gssPadLen, gssTrailerLen; - unsigned int krbHeaderLen = 0, krbTrailerLen = 0, krbPadLen = 0; + size_t krbHeaderLen = 0, krbTrailerLen = 0, krbPadLen = 0; krb5_error_code code; krb5_context krbContext; int dce_style; size_t ec; +#ifdef HAVE_HEIMDAL_VERSION + krb5_crypto krbCrypto = NULL; +#endif if (qop_req != GSS_C_QOP_DEFAULT) { *minor = GSSEAP_UNKNOWN_QOP; @@ -120,18 +123,24 @@ gssEapWrapIovLength(OM_uint32 *minor, gssHeaderLen = gssPadLen = gssTrailerLen = 0; - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - conf_req_flag ? +#ifdef HAVE_HEIMDAL_VERSION + code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, ETYPE_NULL, &krbCrypto); + if (code != 0) + return code; +#endif + + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + conf_req_flag ? KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM, - &krbTrailerLen); + &krbTrailerLen); if (code != 0) { *minor = code; return GSS_S_FAILURE; } if (conf_req_flag) { - code = krb5_c_crypto_length(krbContext, ctx->encryptionType, - KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); + code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen); if (code != 0) { *minor = code; return GSS_S_FAILURE; @@ -143,9 +152,9 @@ gssEapWrapIovLength(OM_uint32 *minor, gssHeaderLen += krbHeaderLen; /* Kerb-Header */ gssTrailerLen = 16 /* E(Header) */ + krbTrailerLen; /* Kerb-Trailer */ - code = krb5_c_padding_length(krbContext, ctx->encryptionType, - dataLength - assocDataLength + 16 /* E(Header) */, - &krbPadLen); + code = krbPaddingLength(krbContext, KRB_CRYPTO_CONTEXT(ctx), + dataLength - assocDataLength + 16 /* E(Header) */, + &krbPadLen); if (code != 0) { *minor = code; return GSS_S_FAILURE; @@ -153,7 +162,7 @@ gssEapWrapIovLength(OM_uint32 *minor, if (krbPadLen == 0 && dce_style) { /* Windows rejects AEAD tokens with non-zero EC */ - code = krb5_c_block_size(krbContext, ctx->encryptionType, &ec); + code = krbBlockSize(krbContext, KRB_CRYPTO_CONTEXT(ctx), &ec); if (code != 0) { *minor = code; return GSS_S_FAILURE; -- 2.1.4