aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/preauth
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/preauth')
-rw-r--r--src/plugins/preauth/pkinit/pkinit_clnt.c35
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto.h30
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_openssl.c57
-rw-r--r--src/plugins/preauth/pkinit/pkinit_kdf_test.c36
-rw-r--r--src/plugins/preauth/pkinit/pkinit_srv.c31
-rw-r--r--src/plugins/preauth/pkinit/pkinit_trace.h13
6 files changed, 70 insertions, 132 deletions
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index b08022a..0f76a62 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -621,34 +621,13 @@ pkinit_as_rep_parse(krb5_context context,
goto cleanup;
}
- /* If we have a KDF algorithm ID, call the algorithm agility KDF. */
- if (kdc_reply->u.dh_Info.kdfID) {
- secret.length = client_key_len;
- secret.data = (char *)client_key;
-
- retval = pkinit_alg_agility_kdf(context, &secret,
- kdc_reply->u.dh_Info.kdfID,
- request->client, request->server,
- etype, encoded_request,
- (krb5_data *)as_rep, key_block);
- if (retval) {
- pkiDebug("failed to create key pkinit_alg_agility_kdf %s\n",
- error_message(retval));
- goto cleanup;
- }
- TRACE_PKINIT_CLIENT_KDF_ALG(context, kdc_reply->u.dh_Info.kdfID,
- key_block);
-
- } else {
- /* Otherwise, use the older octetstring2key function. */
- retval = pkinit_octetstring2key(context, etype, client_key,
- client_key_len, key_block);
- if (retval) {
- pkiDebug("failed to create key pkinit_octetstring2key %s\n",
- error_message(retval));
- goto cleanup;
- }
- TRACE_PKINIT_CLIENT_KDF_OS2K(context, key_block);
+ secret = make_data(client_key, client_key_len);
+ retval = pkinit_kdf(context, &secret, kdc_reply->u.dh_Info.kdfID,
+ request->client, request->server, etype,
+ encoded_request, as_rep, key_block);
+ if (retval) {
+ pkiDebug("pkinit_kdf failed: %s\n", error_message(retval));
+ goto cleanup;
}
retval = 0;
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
index 900dba7..8e4a813 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
@@ -245,22 +245,6 @@ krb5_error_code crypto_check_cert_eku
receives non-zero if an acceptable EKU was found */
/*
- * this functions takes in generated DH secret key and converts
- * it in to a kerberos session key. it takes into the account the
- * enc type and then follows the procedure specified in the RFC p 22.
- */
-krb5_error_code pkinit_octetstring2key
- (krb5_context context, /* IN */
- krb5_enctype etype, /* IN
- specifies the enc type */
- unsigned char *key, /* IN
- contains the DH secret key */
- unsigned int key_len, /* IN
- contains length of key */
- krb5_keyblock * krb5key); /* OUT
- receives kerberos session key */
-
-/*
* this function implements clients first part of the DH protocol.
* client selects its DH parameters and pub key
*/
@@ -552,15 +536,11 @@ krb5_error_code pkinit_identity_set_prompter
void *prompter_data); /* IN */
krb5_error_code
-pkinit_alg_agility_kdf(krb5_context context,
- krb5_data *secret,
- krb5_data *alg_oid,
- krb5_const_principal party_u_info,
- krb5_const_principal party_v_info,
- krb5_enctype enctype,
- krb5_data *as_req,
- krb5_data *pk_as_rep,
- krb5_keyblock *key_block);
+pkinit_kdf(krb5_context context, krb5_data *secret, const krb5_data *alg_oid,
+ krb5_const_principal party_u_info,
+ krb5_const_principal party_v_info, krb5_enctype enctype,
+ const krb5_data *as_req, const krb5_data *pk_as_rep,
+ krb5_keyblock *key_block);
extern const krb5_data sha1_id;
extern const krb5_data sha256_id;
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index cc5befc..7c26899 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -2599,12 +2599,9 @@ cleanup:
return retval;
}
-krb5_error_code
-pkinit_octetstring2key(krb5_context context,
- krb5_enctype etype,
- unsigned char *key,
- unsigned int dh_key_len,
- krb5_keyblock *key_block)
+static krb5_error_code
+octetstring2key(krb5_context context, krb5_enctype etype,
+ const krb5_data *secret, krb5_keyblock *key_block)
{
krb5_error_code retval;
unsigned char *buf = NULL;
@@ -2614,7 +2611,7 @@ pkinit_octetstring2key(krb5_context context,
krb5_data random_data;
EVP_MD_CTX *sha1_ctx = NULL;
- buf = k5alloc(dh_key_len, &retval);
+ buf = k5alloc(secret->length, &retval);
if (buf == NULL)
goto cleanup;
@@ -2629,20 +2626,20 @@ pkinit_octetstring2key(krb5_context context,
do {
if (!EVP_DigestInit(sha1_ctx, EVP_sha1()) ||
!EVP_DigestUpdate(sha1_ctx, &counter, 1) ||
- !EVP_DigestUpdate(sha1_ctx, key, dh_key_len) ||
+ !EVP_DigestUpdate(sha1_ctx, secret->data, secret->length) ||
!EVP_DigestFinal(sha1_ctx, md, NULL)) {
retval = KRB5_CRYPTO_INTERNAL;
goto cleanup;
}
- if (dh_key_len - offset < sizeof(md))
- memcpy(buf + offset, md, dh_key_len - offset);
+ if (secret->length - offset < sizeof(md))
+ memcpy(buf + offset, md, secret->length - offset);
else
memcpy(buf + offset, md, sizeof(md));
offset += sizeof(md);
counter++;
- } while (offset < dh_key_len);
+ } while (offset < secret->length);
key_block->magic = 0;
key_block->enctype = etype;
@@ -2660,6 +2657,10 @@ pkinit_octetstring2key(krb5_context context,
random_data.data = (char *)buf;
retval = krb5_c_random_to_key(context, etype, &random_data, key_block);
+ if (retval)
+ goto cleanup;
+
+ TRACE_PKINIT_KDF_OS2K(context, key_block);
cleanup:
EVP_MD_CTX_free(sha1_ctx);
@@ -2691,8 +2692,8 @@ algid_to_md(const krb5_data *alg_id)
#define sskdf openssl_sskdf
static krb5_error_code
-openssl_sskdf(krb5_context context, const EVP_MD *md, krb5_data *key,
- krb5_data *info, size_t len, krb5_data *out)
+openssl_sskdf(krb5_context context, const EVP_MD *md, const krb5_data *secret,
+ const krb5_data *info, size_t len, krb5_data *out)
{
krb5_error_code ret;
EVP_KDF *kdf = NULL;
@@ -2719,7 +2720,7 @@ openssl_sskdf(krb5_context context, const EVP_MD *md, krb5_data *key,
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
(char *)EVP_MD_get0_name(md), 0);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
- key->data, key->length);
+ secret->data, secret->length);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
info->data, info->length);
*p = OSSL_PARAM_construct_end();
@@ -2741,8 +2742,8 @@ cleanup:
#define sskdf builtin_sskdf
static krb5_error_code
-builtin_sskdf(krb5_context context, const EVP_MD *md, krb5_data *key,
- krb5_data *info, size_t len, krb5_data *out)
+builtin_sskdf(krb5_context context, const EVP_MD *md, const krb5_data *secret,
+ const krb5_data *info, size_t len, krb5_data *out)
{
krb5_error_code ret;
uint32_t counter = 1, reps;
@@ -2783,7 +2784,7 @@ builtin_sskdf(krb5_context context, const EVP_MD *md, krb5_data *key,
/* - Compute Hashi = H(counter || Z || OtherInfo). */
if (!EVP_DigestInit(ctx, md) ||
!EVP_DigestUpdate(ctx, be_counter, 4) ||
- !EVP_DigestUpdate(ctx, key->data, key->length) ||
+ !EVP_DigestUpdate(ctx, secret->data, secret->length) ||
!EVP_DigestUpdate(ctx, info->data, info->length) ||
!EVP_DigestFinal(ctx, outptr, &s)) {
ret = oerr(context, KRB5_CRYPTO_INTERNAL,
@@ -2805,13 +2806,14 @@ cleanup:
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
-/* id-pkinit-kdf family, as specified by RFC 8636. */
+/* id-pkinit-kdf family, as specified by RFC 8636. If alg_oid is null,
+ * octet2string(), as specified by RFC 4556. */
krb5_error_code
-pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
- krb5_data *alg_oid, krb5_const_principal party_u_info,
- krb5_const_principal party_v_info,
- krb5_enctype enctype, krb5_data *as_req,
- krb5_data *pk_as_rep, krb5_keyblock *key_block)
+pkinit_kdf(krb5_context context, krb5_data *secret, const krb5_data *alg_oid,
+ krb5_const_principal party_u_info,
+ krb5_const_principal party_v_info, krb5_enctype enctype,
+ const krb5_data *as_req, const krb5_data *pk_as_rep,
+ krb5_keyblock *key_block)
{
krb5_error_code ret;
size_t rand_len = 0, key_len = 0;
@@ -2823,6 +2825,9 @@ pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
krb5_algorithm_identifier alg_id;
char *hash_name = NULL;
+ if (alg_oid == NULL)
+ return octetstring2key(context, enctype, secret, key_block);
+
ret = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
if (ret)
goto cleanup;
@@ -2840,7 +2845,7 @@ pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
if (party_u_info &&
krb5_principal_compare_any_realm(context, party_u_info,
krb5_anonymous_principal())) {
- party_u_info = (krb5_principal)krb5_anonymous_principal();
+ party_u_info = krb5_anonymous_principal();
}
md = algid_to_md(alg_oid);
@@ -2875,6 +2880,10 @@ pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
goto cleanup;
ret = krb5_c_random_to_key(context, enctype, &random_data, key_block);
+ if (ret)
+ goto cleanup;
+
+ TRACE_PKINIT_KDF_ALG(context, alg_oid, key_block);
cleanup:
if (ret)
diff --git a/src/plugins/preauth/pkinit/pkinit_kdf_test.c b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
index 7f38e84..0a8a69b 100644
--- a/src/plugins/preauth/pkinit/pkinit_kdf_test.c
+++ b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
@@ -24,12 +24,8 @@
* or implied warranty.
*/
-/*
- * pkinit_kdf_test.c -- Test to verify the correctness of the function
- * pkinit_alg_agility_kdf() in pkinit_crypto_openssl, which implements
- * the Key Derivation Function from the PKInit Algorithm Agility
- * document, currently draft-ietf-krb-wg-pkinit-alg-agility-04.txt.
- */
+/* Verify the correctness of pkinit_kdf() in pkinit_crypto_openssl, which
+ * implements the key derivation function from RFC 8636. */
#include "k5-platform.h"
#include "pkinit.h"
@@ -72,7 +68,6 @@ krb5_octet key3_hex[] =
int
main(int argc, char **argv)
{
- /* arguments for calls to pkinit_alg_agility_kdf() */
krb5_context context = 0;
krb5_data secret;
krb5_algorithm_identifier alg_id;
@@ -131,12 +126,9 @@ main(int argc, char **argv)
enctype = enctype_aes;
- /* call pkinit_alg_agility_kdf() with test vector values*/
- if (0 != (retval = pkinit_alg_agility_kdf(context, &secret,
- &alg_id.algorithm,
- u_principal, v_principal,
- enctype, &as_req, &pk_as_rep,
- &key_block))) {
+ retval = pkinit_kdf(context, &secret, &alg_id.algorithm, u_principal,
+ v_principal, enctype, &as_req, &pk_as_rep, &key_block);
+ if (retval) {
printf("ERROR in pkinit_kdf_test: kdf call failed, retval = %d\n",
retval);
goto cleanup;
@@ -162,12 +154,9 @@ main(int argc, char **argv)
enctype = enctype_aes;
- /* call pkinit_alg_agility_kdf() with test vector values*/
- if (0 != (retval = pkinit_alg_agility_kdf(context, &secret,
- &alg_id.algorithm,
- u_principal, v_principal,
- enctype, &as_req, &pk_as_rep,
- &key_block))) {
+ retval = pkinit_kdf(context, &secret, &alg_id.algorithm, u_principal,
+ v_principal, enctype, &as_req, &pk_as_rep, &key_block);
+ if (retval) {
printf("ERROR in pkinit_kdf_test: kdf call failed, retval = %d\n",
retval);
goto cleanup;
@@ -193,12 +182,9 @@ main(int argc, char **argv)
enctype = enctype_des3;
- /* call pkinit_alg_agility_kdf() with test vector values*/
- if (0 != (retval = pkinit_alg_agility_kdf(context, &secret,
- &alg_id.algorithm,
- u_principal, v_principal,
- enctype, &as_req, &pk_as_rep,
- &key_block))) {
+ retval = pkinit_kdf(context, &secret, &alg_id.algorithm, u_principal,
+ v_principal, enctype, &as_req, &pk_as_rep, &key_block);
+ if (retval) {
printf("ERROR in pkinit_kdf_test: kdf call failed, retval = %d\n",
retval);
goto cleanup;
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index e22bcb1..c7880e3 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -896,30 +896,13 @@ pkinit_server_return_padata(krb5_context context,
"/tmp/kdc_as_rep");
#endif
- /* If mutually supported KDFs were found, use the algorithm agility KDF. */
- if (rep->u.dh_Info.kdfID) {
- secret.data = (char *)server_key;
- secret.length = server_key_len;
-
- retval = pkinit_alg_agility_kdf(context, &secret, rep->u.dh_Info.kdfID,
- request->client, request->server,
- enctype, req_pkt, out_data,
- &reply_key);
- if (retval) {
- pkiDebug("pkinit_alg_agility_kdf failed: %s\n",
- error_message(retval));
- goto cleanup;
- }
-
- /* Otherwise, use the older octetstring2key() function */
- } else {
- retval = pkinit_octetstring2key(context, enctype, server_key,
- server_key_len, &reply_key);
- if (retval) {
- pkiDebug("pkinit_octetstring2key failed: %s\n",
- error_message(retval));
- goto cleanup;
- }
+ secret = make_data(server_key, server_key_len);
+ retval = pkinit_kdf(context, &secret, rep->u.dh_Info.kdfID,
+ request->client, request->server, enctype, req_pkt,
+ out_data, &reply_key);
+ if (retval) {
+ pkiDebug("pkinit_kdf failed: %s\n", error_message(retval));
+ goto cleanup;
}
retval = cb->replace_reply_key(context, rock, &reply_key, FALSE);
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index 1c1ceb5..ab23b68 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -43,12 +43,6 @@
TRACE(c, "PKINIT client skipping EKU check due to configuration")
#define TRACE_PKINIT_CLIENT_FRESHNESS_TOKEN(c) \
TRACE(c, "PKINIT client received freshness token from KDC")
-#define TRACE_PKINIT_CLIENT_KDF_ALG(c, kdf, keyblock) \
- TRACE(c, "PKINIT client used KDF {hexdata} to compute reply key " \
- "{keyblock}", kdf, keyblock)
-#define TRACE_PKINIT_CLIENT_KDF_OS2K(c, keyblock) \
- TRACE(c, "PKINIT client used octetstring2key to compute reply key " \
- "{keyblock}", keyblock)
#define TRACE_PKINIT_CLIENT_NO_IDENTITY(c) \
TRACE(c, "PKINIT client has no configured identity; giving up")
#define TRACE_PKINIT_CLIENT_REP_CHECKSUM_FAIL(c, expected, received) \
@@ -95,6 +89,13 @@
TRACE(c, "PKINIT client key has group {str}, need at least {str}", \
desc, mindesc)
+#define TRACE_PKINIT_KDF_ALG(c, kdf, keyblock) \
+ TRACE(c, "PKINIT used KDF {hexdata} to compute reply key {keyblock}", \
+ kdf, keyblock)
+#define TRACE_PKINIT_KDF_OS2K(c, keyblock) \
+ TRACE(c, "PKINIT used octetstring2key to compute reply key {keyblock}", \
+ keyblock)
+
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
TRACE(c, "PKINIT OpenSSL error: {str}", msg)