You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
8.1 KiB
217 lines
8.1 KiB
From 906d3441b846ed09882490b6128db6fedf39e63b Mon Sep 17 00:00:00 2001 |
|
From: Greg Hudson <ghudson@mit.edu> |
|
Date: Tue, 30 May 2023 01:21:48 -0400 |
|
Subject: [PATCH] Enable PKINIT if at least one group is available |
|
|
|
OpenSSL may no longer allow decoding of non-well-known Diffie-Hellman |
|
group parameters as EVP_PKEY objects in FIPS mode. However, OpenSSL |
|
does not know about MODP group 2 (1024-bit), which is considered as a |
|
custom group. As a consequence, the PKINIT kdcpreauth module fails to |
|
load in FIPS mode. |
|
|
|
Allow initialization of PKINIT plugin if at least one of the MODP |
|
well-known group parameters successfully decodes. |
|
|
|
[ghudson@mit.edu: minor commit message and code edits] |
|
|
|
ticket: 9096 (new) |
|
--- |
|
src/plugins/preauth/pkinit/pkinit_clnt.c | 2 +- |
|
src/plugins/preauth/pkinit/pkinit_crypto.h | 3 +- |
|
.../preauth/pkinit/pkinit_crypto_openssl.c | 76 +++++++++++-------- |
|
src/plugins/preauth/pkinit/pkinit_srv.c | 2 +- |
|
src/plugins/preauth/pkinit/pkinit_trace.h | 3 + |
|
5 files changed, 51 insertions(+), 35 deletions(-) |
|
|
|
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c |
|
index 725d5bc438..ea9ba454df 100644 |
|
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c |
|
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c |
|
@@ -1378,7 +1378,7 @@ pkinit_client_plugin_init(krb5_context context, |
|
if (retval) |
|
goto errout; |
|
|
|
- retval = pkinit_init_plg_crypto(&ctx->cryptoctx); |
|
+ retval = pkinit_init_plg_crypto(context, &ctx->cryptoctx); |
|
if (retval) |
|
goto errout; |
|
|
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h |
|
index 9fa315d7a0..8bdbea8e95 100644 |
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h |
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h |
|
@@ -103,7 +103,8 @@ typedef struct _pkinit_cert_matching_data { |
|
/* |
|
* Functions to initialize and cleanup crypto contexts |
|
*/ |
|
-krb5_error_code pkinit_init_plg_crypto(pkinit_plg_crypto_context *); |
|
+krb5_error_code pkinit_init_plg_crypto(krb5_context, |
|
+ pkinit_plg_crypto_context *); |
|
void pkinit_fini_plg_crypto(pkinit_plg_crypto_context); |
|
|
|
krb5_error_code pkinit_init_req_crypto(pkinit_req_crypto_context *); |
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
|
index 263ef7845e..d646073d55 100644 |
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
|
@@ -47,7 +47,8 @@ |
|
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ); |
|
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ); |
|
|
|
-static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context ); |
|
+static krb5_error_code pkinit_init_dh_params(krb5_context, |
|
+ pkinit_plg_crypto_context); |
|
static void pkinit_fini_dh_params(pkinit_plg_crypto_context ); |
|
|
|
static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx); |
|
@@ -951,7 +952,8 @@ oerr_cert(krb5_context context, krb5_error_code code, X509_STORE_CTX *certctx, |
|
} |
|
|
|
krb5_error_code |
|
-pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) |
|
+pkinit_init_plg_crypto(krb5_context context, |
|
+ pkinit_plg_crypto_context *cryptoctx) |
|
{ |
|
krb5_error_code retval = ENOMEM; |
|
pkinit_plg_crypto_context ctx = NULL; |
|
@@ -969,7 +971,7 @@ pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) |
|
if (retval) |
|
goto out; |
|
|
|
- retval = pkinit_init_dh_params(ctx); |
|
+ retval = pkinit_init_dh_params(context, ctx); |
|
if (retval) |
|
goto out; |
|
|
|
@@ -1278,30 +1280,36 @@ pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx) |
|
ASN1_OBJECT_free(ctx->id_kp_serverAuth); |
|
} |
|
|
|
-static krb5_error_code |
|
-pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) |
|
+static int |
|
+try_import_group(krb5_context context, const krb5_data *params, |
|
+ const char *name, EVP_PKEY **pkey_out) |
|
{ |
|
- krb5_error_code retval = ENOMEM; |
|
- |
|
- plgctx->dh_1024 = decode_dh_params(&oakley_1024); |
|
- if (plgctx->dh_1024 == NULL) |
|
- goto cleanup; |
|
- |
|
- plgctx->dh_2048 = decode_dh_params(&oakley_2048); |
|
- if (plgctx->dh_2048 == NULL) |
|
- goto cleanup; |
|
+ *pkey_out = decode_dh_params(params); |
|
+ if (*pkey_out == NULL) |
|
+ TRACE_PKINIT_DH_GROUP_UNAVAILABLE(context, name); |
|
+ return (*pkey_out != NULL) ? 1 : 0; |
|
+} |
|
|
|
- plgctx->dh_4096 = decode_dh_params(&oakley_4096); |
|
- if (plgctx->dh_4096 == NULL) |
|
- goto cleanup; |
|
+static krb5_error_code |
|
+pkinit_init_dh_params(krb5_context context, pkinit_plg_crypto_context plgctx) |
|
+{ |
|
+ int n = 0; |
|
|
|
- retval = 0; |
|
+ n += try_import_group(context, &oakley_1024, "MODP 2 (1024-bit)", |
|
+ &plgctx->dh_1024); |
|
+ n += try_import_group(context, &oakley_2048, "MODP 14 (2048-bit)", |
|
+ &plgctx->dh_2048); |
|
+ n += try_import_group(context, &oakley_4096, "MODP 16 (4096-bit)", |
|
+ &plgctx->dh_4096); |
|
|
|
-cleanup: |
|
- if (retval) |
|
+ if (n == 0) { |
|
pkinit_fini_dh_params(plgctx); |
|
+ k5_setmsg(context, ENOMEM, |
|
+ _("PKINIT cannot initialize any key exchange groups")); |
|
+ return ENOMEM; |
|
+ } |
|
|
|
- return retval; |
|
+ return 0; |
|
} |
|
|
|
static void |
|
@@ -2910,11 +2918,11 @@ client_create_dh(krb5_context context, |
|
|
|
if (cryptoctx->received_params != NULL) |
|
params = cryptoctx->received_params; |
|
- else if (dh_size == 1024) |
|
+ else if (plg_cryptoctx->dh_1024 != NULL && dh_size == 1024) |
|
params = plg_cryptoctx->dh_1024; |
|
- else if (dh_size == 2048) |
|
+ else if (plg_cryptoctx->dh_2048 != NULL && dh_size == 2048) |
|
params = plg_cryptoctx->dh_2048; |
|
- else if (dh_size == 4096) |
|
+ else if (plg_cryptoctx->dh_4096 != NULL && dh_size == 4096) |
|
params = plg_cryptoctx->dh_4096; |
|
else |
|
goto cleanup; |
|
@@ -3210,19 +3218,23 @@ pkinit_create_td_dh_parameters(krb5_context context, |
|
krb5_algorithm_identifier alg_4096 = { dh_oid, oakley_4096 }; |
|
krb5_algorithm_identifier *alglist[4]; |
|
|
|
- if (opts->dh_min_bits > 4096) { |
|
- ret = KRB5KRB_ERR_GENERIC; |
|
- goto cleanup; |
|
- } |
|
- |
|
i = 0; |
|
- if (opts->dh_min_bits <= 2048) |
|
+ if (plg_cryptoctx->dh_2048 != NULL && opts->dh_min_bits <= 2048) |
|
alglist[i++] = &alg_2048; |
|
- alglist[i++] = &alg_4096; |
|
- if (opts->dh_min_bits <= 1024) |
|
+ if (plg_cryptoctx->dh_4096 != NULL && opts->dh_min_bits <= 4096) |
|
+ alglist[i++] = &alg_4096; |
|
+ if (plg_cryptoctx->dh_1024 != NULL && opts->dh_min_bits <= 1024) |
|
alglist[i++] = &alg_1024; |
|
alglist[i] = NULL; |
|
|
|
+ if (i == 0) { |
|
+ ret = KRB5KRB_ERR_GENERIC; |
|
+ k5_setmsg(context, ret, |
|
+ _("OpenSSL has no supported key exchange groups for " |
|
+ "pkinit_dh_min_bits=%d"), opts->dh_min_bits); |
|
+ goto cleanup; |
|
+ } |
|
+ |
|
ret = k5int_encode_krb5_td_dh_parameters(alglist, &der_alglist); |
|
if (ret) |
|
goto cleanup; |
|
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c |
|
index 1b3bf6d4d0..768a4e559f 100644 |
|
--- a/src/plugins/preauth/pkinit/pkinit_srv.c |
|
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c |
|
@@ -1222,7 +1222,7 @@ pkinit_server_plugin_init_realm(krb5_context context, const char *realmname, |
|
goto errout; |
|
plgctx->realmname_len = strlen(plgctx->realmname); |
|
|
|
- retval = pkinit_init_plg_crypto(&plgctx->cryptoctx); |
|
+ retval = pkinit_init_plg_crypto(context, &plgctx->cryptoctx); |
|
if (retval) |
|
goto errout; |
|
|
|
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h |
|
index 259e95c6c2..5ee39c085c 100644 |
|
--- a/src/plugins/preauth/pkinit/pkinit_trace.h |
|
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h |
|
@@ -90,6 +90,9 @@ |
|
#define TRACE_PKINIT_CLIENT_TRYAGAIN(c) \ |
|
TRACE(c, "PKINIT client trying again with KDC-provided parameters") |
|
|
|
+#define TRACE_PKINIT_DH_GROUP_UNAVAILABLE(c, name) \ |
|
+ TRACE(c, "PKINIT key exchange group {str} unsupported", name) |
|
+ |
|
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \ |
|
TRACE(c, "PKINIT OpenSSL error: {str}", msg) |
|
|
|
-- |
|
2.41.0 |
|
|
|
|