*pKrbContext = krbContext;
cleanup:
+#ifdef HAVE_HEIMDAL_VERSION
+ krb5_xfree(defaultRealm);
+#else
+ krb5_free_default_realm(krbContext, defaultRealm);
+#endif
+
if (code != 0 && krbContext != NULL)
krb5_free_context(krbContext);
- if (defaultRealm != NULL)
- GSSEAP_FREE(defaultRealm);
-
return code;
}
struct gss_eap_thread_local_data *tld;
*minor = 0;
+ *context = NULL;
tld = gssEapGetThreadLocalData();
if (tld != NULL) {
- *context = tld->krbContext;
- if (*context == NULL) {
- *minor = initKrbContext(context);
- if (*minor == 0)
- tld->krbContext = *context;
+ if (tld->krbContext == NULL) {
+ *minor = initKrbContext(&tld->krbContext);
+ if (*minor != 0)
+ tld->krbContext = NULL;
}
+ *context = tld->krbContext;
+ } else {
+ *minor = GSSEAP_GET_LAST_ERROR();
}
- return *minor == 0 ? GSS_S_COMPLETE : GSS_S_FAILURE;
+
+ GSSEAP_ASSERT(*context != NULL || *minor != 0);
+
+ return (*minor == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
/*
* Tn = pseudo-random(KMSK, n || "rfc4121-gss-eap")
* L = output key size
* K = truncate(L, T1 || T2 || .. || Tn)
+ *
+ * The output must be freed by krb5_free_keyblock_contents(),
+ * not GSSEAP_FREE().
*/
OM_uint32
gssEapDeriveRfc3961Key(OM_uint32 *minor,
krb5_keyblock *pKey)
{
krb5_context krbContext;
-#ifndef HAVE_HEIMDAL_VERSION
+#ifdef HAVE_HEIMDAL_VERSION
+ krb5_crypto krbCrypto = NULL;
+#else
krb5_data data;
#endif
- krb5_data ns, t, prfOut;
+ krb5_data ns, t, derivedKeyData;
krb5_keyblock kd;
krb5_error_code code;
size_t randomLength, keyLength, prfLength;
unsigned char constant[4 + sizeof("rfc4121-gss-eap") - 1], *p;
ssize_t i, remain;
- GSSEAP_ASSERT(encryptionType != ENCTYPE_NULL);
-
- memset(pKey, 0, sizeof(*pKey));
-
GSSEAP_KRB_INIT(&krbContext);
+ GSSEAP_ASSERT(encryptionType != ENCTYPE_NULL);
+ KRB_KEY_INIT(pKey);
KRB_KEY_INIT(&kd);
KRB_KEY_TYPE(&kd) = encryptionType;
- t.data = NULL;
- t.length = 0;
+ KRB_DATA_INIT(&ns);
+ KRB_DATA_INIT(&t);
+ KRB_DATA_INIT(&derivedKeyData);
+
+#ifdef HAVE_HEIMDAL_VERSION
+ code = krb5_enctype_keybits(krbContext, encryptionType, &randomLength);
+ if (code != 0)
+ goto cleanup;
- prfOut.data = NULL;
- prfOut.length = 0;
+ randomLength = (randomLength + 7) / 8; /* from mit_glue.c */
+ code = krb5_enctype_keysize(krbContext, encryptionType, &keyLength);
+ if (code != 0)
+ goto cleanup;
+#else
code = krb5_c_keylengths(krbContext, encryptionType,
&randomLength, &keyLength);
if (code != 0)
goto cleanup;
+#endif /* HAVE_HEIMDAL_VERSION */
- KRB_KEY_DATA(&kd) = GSSEAP_MALLOC(keyLength);
- if (KRB_KEY_DATA(&kd) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
- KRB_KEY_LENGTH(&kd) = keyLength;
+ /* Convert EAP MSK into a Kerberos key */
- /* Convert MSK into a Kerberos key */
#ifdef HAVE_HEIMDAL_VERSION
code = krb5_random_to_key(krbContext, encryptionType, inputKey,
MIN(inputKeyLength, randomLength), &kd);
data.length = MIN(inputKeyLength, randomLength);
data.data = (char *)inputKey;
+ KRB_KEY_DATA(&kd) = KRB_MALLOC(keyLength);
+ if (KRB_KEY_DATA(&kd) == NULL) {
+ code = ENOMEM;
+ goto cleanup;
+ }
+ KRB_KEY_LENGTH(&kd) = keyLength;
+
code = krb5_c_random_to_key(krbContext, encryptionType, &data, &kd);
-#endif
+#endif /* HAVE_HEIMDAL_VERSION */
if (code != 0)
goto cleanup;
ns.data = (char *)constant;
/* Plug derivation constant and key into PRF */
+#ifdef HAVE_HEIMDAL_VERSION
+ code = krb5_crypto_prf_length(krbContext, encryptionType, &prfLength);
+#else
code = krb5_c_prf_length(krbContext, encryptionType, &prfLength);
+#endif
if (code != 0)
goto cleanup;
+#ifdef HAVE_HEIMDAL_VERSION
+ code = krb5_crypto_init(krbContext, &kd, 0, &krbCrypto);
+ if (code != 0)
+ goto cleanup;
+#else
t.length = prfLength;
t.data = GSSEAP_MALLOC(t.length);
if (t.data == NULL) {
code = ENOMEM;
goto cleanup;
}
+#endif
- prfOut.length = randomLength;
- prfOut.data = GSSEAP_MALLOC(prfOut.length);
- if (prfOut.data == NULL) {
+ derivedKeyData.length = randomLength;
+ derivedKeyData.data = GSSEAP_MALLOC(derivedKeyData.length);
+ if (derivedKeyData.data == NULL) {
code = ENOMEM;
goto cleanup;
}
- for (i = 0, p = (unsigned char *)prfOut.data, remain = randomLength;
+ for (i = 0, p = (unsigned char *)derivedKeyData.data, remain = randomLength;
remain > 0;
p += t.length, remain -= t.length, i++)
{
store_uint32_be(i, ns.data);
+#ifdef HAVE_HEIMDAL_VERSION
+ code = krb5_crypto_prf(krbContext, krbCrypto, &ns, &t);
+#else
code = krb5_c_prf(krbContext, &kd, &ns, &t);
+#endif
if (code != 0)
goto cleanup;
/* Finally, convert PRF output into a new key which we will return */
#ifdef HAVE_HEIMDAL_VERSION
+ krb5_free_keyblock_contents(krbContext, &kd);
+ KRB_KEY_INIT(&kd);
+
code = krb5_random_to_key(krbContext, encryptionType,
- prfOut.data, prfOut.length, &kd);
+ derivedKeyData.data, derivedKeyData.length, &kd);
#else
- code = krb5_c_random_to_key(krbContext, encryptionType, &prfOut, &kd);
+ code = krb5_c_random_to_key(krbContext, encryptionType,
+ &derivedKeyData, &kd);
#endif
if (code != 0)
goto cleanup;
*pKey = kd;
- KRB_KEY_DATA(&kd) = NULL;
cleanup:
- if (KRB_KEY_DATA(&kd) != NULL) {
- memset(KRB_KEY_DATA(&kd), 0, KRB_KEY_LENGTH(&kd));
- GSSEAP_FREE(KRB_KEY_DATA(&kd));
- }
+ if (code != 0)
+ krb5_free_keyblock_contents(krbContext, &kd);
+#ifdef HAVE_HEIMDAL_VERSION
+ krb5_crypto_destroy(krbContext, krbCrypto);
+ krb5_data_free(&t);
+#else
if (t.data != NULL) {
memset(t.data, 0, t.length);
GSSEAP_FREE(t.data);
}
- if (prfOut.data != NULL) {
- memset(prfOut.data, 0, prfOut.length);
- GSSEAP_FREE(prfOut.data);
+#endif
+ if (derivedKeyData.data != NULL) {
+ memset(derivedKeyData.data, 0, derivedKeyData.length);
+ GSSEAP_FREE(derivedKeyData.data);
}
+
*minor = code;
+
return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
krb5_cksumtype *cksumtype)
{
krb5_context krbContext;
-#ifndef HAVE_KRB5INT_C_MANDATORY_CKSUMTYPE
+#if !defined(HAVE_KRB5INT_C_MANDATORY_CKSUMTYPE) && !defined(HAVE_HEIMDAL_VERSION)
krb5_data data;
krb5_checksum cksum;
#endif
+#ifdef HAVE_HEIMDAL_VERSION
+ krb5_crypto krbCrypto = NULL;
+#endif
GSSEAP_KRB_INIT(&krbContext);
cksumtype);
if (*minor != 0)
return GSS_S_FAILURE;
+#elif defined(HAVE_HEIMDAL_VERSION)
+ *minor = krb5_crypto_init(krbContext, key, 0, &krbCrypto);
+ if (*minor != 0)
+ return GSS_S_FAILURE;
+
+ *minor = krb5_crypto_get_checksum_type(krbContext, krbCrypto, cksumtype);
+
+ krb5_crypto_destroy(krbContext, krbCrypto);
+
+ if (*minor != 0)
+ return GSS_S_FAILURE;
#else
- data.length = 0;
- data.data = NULL;
+ KRB_DATA_INIT(&data);
memset(&cksum, 0, sizeof(cksum));
if (*minor != 0)
return GSS_S_FAILURE;
-#ifdef HAVE_HEIMDAL_VERSION
- *cksumtype = cksum.cksumtype;
-#else
- *cksumtype = cksum.checksum_type;
-#endif
+ *cksumtype = KRB_CHECKSUM_TYPE(&cksum);
- krb5_free_checksum_contents(krbContext, &cksum);
+ KRB_CHECKSUM_FREE(krbContext, &cksum);
#endif /* HAVE_KRB5INT_C_MANDATORY_CKSUMTYPE */
- if (!krb5_c_is_keyed_cksum(*cksumtype)) {
+#ifdef HAVE_HEIMDAL_VERSION
+ if (!krb5_checksum_is_keyed(krbContext, *cksumtype))
+#else
+ if (!krb5_c_is_keyed_cksum(*cksumtype))
+#endif
+ {
*minor = (OM_uint32)KRB5KRB_AP_ERR_INAPP_CKSUM;
return GSS_S_FAILURE;
}
#ifdef HAVE_HEIMDAL_VERSION
krb5_crypto krbCrypto,
#else
- krb5_keyblock *key,
+ const krb5_keyblock *key,
#endif
int type,
size_t *length)
#ifdef HAVE_HEIMDAL_VERSION
krb5_crypto krbCrypto,
#else
- krb5_keyblock *key,
+ const krb5_keyblock *key,
#endif
size_t dataLength,
size_t *padLength)
#ifdef HAVE_HEIMDAL_VERSION
krb5_crypto krbCrypto,
#else
- krb5_keyblock *key,
+ const krb5_keyblock *key,
#endif
size_t *blockSize)
{
return 0;
}
+#ifdef GSSEAP_ENABLE_REAUTH
krb5_error_code
krbMakeAuthDataKdcIssued(krb5_context context,
const krb5_keyblock *key,
if (code != 0)
goto cleanup;
- GSSEAP_FREE(buf);
+ free(buf); /* match ASN1_MALLOC_ENCODE */
buf = NULL;
ASN1_MALLOC_ENCODE(AD_KDCIssued, buf, buf_size, &kdcIssued, &len, code);
cleanup:
if (buf != NULL)
- GSSEAP_FREE(buf);
+ free(buf); /* match ASN1_MALLOC_ENCODE */
if (crypto != NULL)
krb5_crypto_destroy(context, crypto);
free_Checksum(&kdcIssued.ad_checksum);
return code;
#endif /* HAVE_HEIMDAL_VERSION */
}
+#endif /* GSSEAP_ENABLE_REAUTH */