From 2cf8bb46fc3e0e2aaead764d333c6e216f028ef3 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 9 Mar 2021 17:07:48 +0000 Subject: [PATCH] Ensure that ECX keys pass EVP_PKEY_param_check() RSA keys have no parameters and pass EVP_PKEY_param_check(). Previously, ECX keys had no parammeters and failed EVP_PKEY_param_check(). We should be consistent. It makes more sense to always pass, and therefore this commit implements that behaviour. Fixes #14482 Reviewed-by: Paul Dale Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/14485) --- providers/implementations/keymgmt/ecx_kmgmt.c | 10 +++++-- providers/implementations/keymgmt/rsa_kmgmt.c | 13 ++++++++- test/evp_extra_test.c | 28 +++++++++++++++++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index 8e47dfb03e2..9b23c2f0ec9 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -71,8 +71,6 @@ static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types; static OSSL_FUNC_keymgmt_export_fn ecx_export; static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types; -#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR) - struct ecx_gen_ctx { OSSL_LIB_CTX *libctx; char *propq; @@ -727,7 +725,13 @@ static int ecx_validate(const void *keydata, int selection, int type, size_t key assert(keylen == ecx->keylen); - if ((selection & ECX_POSSIBLE_SELECTIONS) != 0) + /* + * ECX keys have no parameters. But if EVP_PKEY_param_check() is called then + * we should return true. + */ + if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR + | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS + | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)) != 0) ok = 1; if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 095c713aac3..425b6c80f29 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -367,7 +367,18 @@ static int rsa_validate(const void *keydata, int selection, int checktype) if (!ossl_prov_is_running()) return 0; - if ((selection & RSA_POSSIBLE_SELECTIONS) != 0) + /* + * Although an RSA key has no domain parameters, validating them should + * return true. + * + * RSA_POSSIBLE_SELECTIONS already includes + * OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS. We explicitly add + * OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS here as well for completeness. In + * practice this makes little difference since EVP_PKEY_param_check() always + * checks the combination of "other" and "domain" parameters anyway. + */ + if ((selection & (RSA_POSSIBLE_SELECTIONS + | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) != 0) ok = 1; /* If the whole key is selected, we do a pairwise validation */ diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index acba9819e68..93179173039 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -380,6 +380,21 @@ static const unsigned char kExampleBadECPubKeyDER[] = { static const unsigned char pExampleECParamDER[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 }; + +static const unsigned char kExampleED25519KeyDER[] = { + 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, + 0x04, 0x22, 0x04, 0x20, 0xba, 0x7b, 0xba, 0x20, 0x1b, 0x02, 0x75, 0x3a, + 0xe8, 0x88, 0xfe, 0x00, 0xcd, 0x8b, 0xc6, 0xf4, 0x5c, 0x47, 0x09, 0x46, + 0x66, 0xe4, 0x72, 0x85, 0x25, 0x26, 0x5e, 0x12, 0x33, 0x48, 0xf6, 0x50 +}; + +static const unsigned char kExampleED25519PubKeyDER[] = { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00, + 0xf5, 0xc5, 0xeb, 0x52, 0x3e, 0x7d, 0x07, 0x86, 0xb2, 0x55, 0x07, 0x45, + 0xef, 0x5b, 0x7c, 0x20, 0xe8, 0x66, 0x28, 0x30, 0x3c, 0x8a, 0x82, 0x40, + 0x97, 0xa3, 0x08, 0xdc, 0x65, 0x80, 0x39, 0x29 +}; + #endif typedef struct APK_DATA_st { @@ -402,14 +417,21 @@ static APK_DATA keydata[] = { }; static APK_DATA keycheckdata[] = { - {kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), "RSA", EVP_PKEY_RSA, 1, 1, 1, 0}, + {kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), "RSA", EVP_PKEY_RSA, 1, 1, 1, + 0}, {kExampleBadRSAKeyDER, sizeof(kExampleBadRSAKeyDER), "RSA", EVP_PKEY_RSA, 0, 1, 1, 0}, #ifndef OPENSSL_NO_EC {kExampleECKeyDER, sizeof(kExampleECKeyDER), "EC", EVP_PKEY_EC, 1, 1, 1, 0}, /* group is also associated in our pub key */ - {kExampleECPubKeyDER, sizeof(kExampleECPubKeyDER), "EC", EVP_PKEY_EC, 0, 1, 1, 1}, - {pExampleECParamDER, sizeof(pExampleECParamDER), "EC", EVP_PKEY_EC, 0, 0, 1, 2} + {kExampleECPubKeyDER, sizeof(kExampleECPubKeyDER), "EC", EVP_PKEY_EC, 0, 1, + 1, 1}, + {pExampleECParamDER, sizeof(pExampleECParamDER), "EC", EVP_PKEY_EC, 0, 0, 1, + 2}, + {kExampleED25519KeyDER, sizeof(kExampleED25519KeyDER), "ED25519", + EVP_PKEY_ED25519, 1, 1, 1, 0}, + {kExampleED25519PubKeyDER, sizeof(kExampleED25519PubKeyDER), "ED25519", + EVP_PKEY_ED25519, 0, 1, 1, 1}, #endif }; -- 2.47.2