From a54ff473df579dffbf70eec637d54e48370b5bdc Mon Sep 17 00:00:00 2001 From: Shane Lontis Date: Tue, 21 Jan 2020 15:45:40 +1000 Subject: [PATCH] Add DH key validation to default provider Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/10911) --- crypto/dh/build.info | 4 +- providers/implementations/keymgmt/dh_kmgmt.c | 46 +++++++++++++++++++- test/evp_pkey_provided_test.c | 13 +++++- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/crypto/dh/build.info b/crypto/dh/build.info index bb71f4a16b..56c085bb1e 100644 --- a/crypto/dh/build.info +++ b/crypto/dh/build.info @@ -1,9 +1,9 @@ LIBS=../../libcrypto -$COMMON=dh_lib.c dh_key.c dh_group_params.c +$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c SOURCE[../../libcrypto]=$COMMON\ - dh_asn1.c dh_gen.c dh_check.c dh_err.c dh_depr.c \ + dh_asn1.c dh_gen.c dh_err.c dh_depr.c \ dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c SOURCE[../../providers/libfips.a]=$COMMON diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index 90a583e7db..6a6a06cc86 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -16,13 +16,13 @@ #include #include #include +#include #include -#include "internal/param_build.h" -#include "crypto/dh.h" #include "prov/implementations.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" #include "crypto/dh.h" +#include "internal/param_build.h" static OSSL_OP_keymgmt_new_fn dh_newdata; static OSSL_OP_keymgmt_free_fn dh_freedata; @@ -30,6 +30,7 @@ static OSSL_OP_keymgmt_get_params_fn dh_get_params; static OSSL_OP_keymgmt_gettable_params_fn dh_gettable_params; static OSSL_OP_keymgmt_has_fn dh_has; static OSSL_OP_keymgmt_match_fn dh_match; +static OSSL_OP_keymgmt_validate_fn dh_validate; static OSSL_OP_keymgmt_import_fn dh_import; static OSSL_OP_keymgmt_import_types_fn dh_import_types; static OSSL_OP_keymgmt_export_fn dh_export; @@ -316,6 +317,46 @@ static const OSSL_PARAM *dh_gettable_params(void) return dh_params; } +static int dh_validate_public(DH *dh) +{ + const BIGNUM *pub_key = NULL; + + DH_get0_key(dh, &pub_key, NULL); + return DH_check_pub_key_ex(dh, pub_key); +} + +static int dh_validate_private(DH *dh) +{ + int status = 0; + const BIGNUM *priv_key = NULL; + + DH_get0_key(dh, NULL, &priv_key); + return dh_check_priv_key(dh, priv_key, &status);; +} + +static int dh_validate(void *keydata, int selection) +{ + DH *dh = keydata; + int ok = 0; + + if ((selection & DH_POSSIBLE_SELECTIONS) != 0) + ok = 1; + + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) + ok = ok && DH_check_params_ex(dh); + + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + ok = ok && dh_validate_public(dh); + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + ok = ok && dh_validate_private(dh); + + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) + == OSSL_KEYMGMT_SELECT_KEYPAIR) + ok = ok && dh_check_pairwise(dh); + return ok; +} + const OSSL_DISPATCH dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dh_freedata }, @@ -323,6 +364,7 @@ const OSSL_DISPATCH dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dh_gettable_params }, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dh_has }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dh_match }, + { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dh_validate }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dh_import }, { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dh_import_types }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export }, diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c index 6f7f3986e9..c395f185dd 100644 --- a/test/evp_pkey_provided_test.c +++ b/test/evp_pkey_provided_test.c @@ -331,7 +331,7 @@ static int test_fromdata_rsa(void) static int test_fromdata_dh(void) { int ret = 0; - EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL; EVP_PKEY *pk = NULL; /* * 32-bit DH key, extracted from this command, @@ -367,9 +367,19 @@ static int test_fromdata_dh(void) ret = test_print_key_using_pem("DH", pk) && test_print_key_using_serializer("DH", pk); + if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, ""))) + goto err; + + if (!TEST_false(EVP_PKEY_check(key_ctx)) + || !TEST_true(EVP_PKEY_public_check(key_ctx)) + || !TEST_false(EVP_PKEY_private_check(key_ctx)) /* Need a q */ + || !TEST_true(EVP_PKEY_pairwise_check(key_ctx))) + goto err; + err: EVP_PKEY_free(pk); EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(key_ctx); return ret; } @@ -552,7 +562,6 @@ err: #endif /* OPENSSL_NO_EC */ - int setup_tests(void) { if (!test_skip_common_options()) { -- 2.25.1