Ensure that ECX keys pass EVP_PKEY_param_check()
authorMatt Caswell <matt@openssl.org>
Tue, 9 Mar 2021 17:07:48 +0000 (17:07 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 15 Mar 2021 15:51:26 +0000 (15:51 +0000)
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 <pauli@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14485)

providers/implementations/keymgmt/ecx_kmgmt.c
providers/implementations/keymgmt/rsa_kmgmt.c
test/evp_extra_test.c

index 8e47dfb03e2ae6fe5bf4a41894961b33296b3ce6..9b23c2f0ec96afafb11729e58bff1658ee680057 100644 (file)
@@ -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)
index 095c713aac35d88cb604c18dd4588f79d9cac120..425b6c80f29af5f35bc7b9831ff10b7dcd5aa3ff 100644 (file)
@@ -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 */
index acba9819e68dfb94cd07128e8e829dc33bd3283a..9317917303908d243f19be935ec0668ac8a2ab73 100644 (file)
@@ -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
 };