Adapt our OSSL_FUNC_keymgmt_match() implementations to the EVP_PKEY_eq() fix
authorRichard Levitte <levitte@openssl.org>
Wed, 29 Sep 2021 09:05:41 +0000 (11:05 +0200)
committerRichard Levitte <levitte@openssl.org>
Mon, 13 Dec 2021 06:52:53 +0000 (07:52 +0100)
The match function (called OSSL_FUNC_keymgmt_match() in our documentation)
in our KEYMGMT implementations were interpretting the selector bits a
bit too strictly, so they get a bit relaxed to make it reasonable to
match diverse key contents.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16765)

providers/implementations/keymgmt/dh_kmgmt.c
providers/implementations/keymgmt/dsa_kmgmt.c
providers/implementations/keymgmt/ec_kmgmt.c
providers/implementations/keymgmt/ecx_kmgmt.c
providers/implementations/keymgmt/rsa_kmgmt.c

index c4cda447bf852789dc578030f6c513348e90fc21..98eb882e3fa0a09928bea626ef0093be0ef93827 100644 (file)
@@ -154,10 +154,30 @@ static int dh_match(const void *keydata1, const void *keydata2, int selection)
     if (!ossl_prov_is_running())
         return 0;
 
-    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
-        ok = ok && BN_cmp(DH_get0_pub_key(dh1), DH_get0_pub_key(dh2)) == 0;
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
-        ok = ok && BN_cmp(DH_get0_priv_key(dh1), DH_get0_priv_key(dh2)) == 0;
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+        int key_checked = 0;
+
+        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+            const BIGNUM *pa = DH_get0_pub_key(dh1);
+            const BIGNUM *pb = DH_get0_pub_key(dh2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        if (!key_checked
+            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+            const BIGNUM *pa = DH_get0_priv_key(dh1);
+            const BIGNUM *pb = DH_get0_priv_key(dh2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        ok = ok && key_checked;
+    }
     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
         FFC_PARAMS *dhparams1 = ossl_dh_get0_params((DH *)dh1);
         FFC_PARAMS *dhparams2 = ossl_dh_get0_params((DH *)dh2);
index 4f05799bb38ebeee3e841ae0dd506982bb9f1bad..1e1b168f7d20052754890bd54f42eb53a3960b02 100644 (file)
@@ -154,12 +154,30 @@ static int dsa_match(const void *keydata1, const void *keydata2, int selection)
     if (!ossl_prov_is_running())
         return 0;
 
-    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
-        ok = ok
-            && BN_cmp(DSA_get0_pub_key(dsa1), DSA_get0_pub_key(dsa2)) == 0;
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
-        ok = ok
-            && BN_cmp(DSA_get0_priv_key(dsa1), DSA_get0_priv_key(dsa2)) == 0;
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+        int key_checked = 0;
+
+        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+            const BIGNUM *pa = DSA_get0_pub_key(dsa1);
+            const BIGNUM *pb = DSA_get0_pub_key(dsa2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        if (!key_checked
+            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+            const BIGNUM *pa = DSA_get0_priv_key(dsa1);
+            const BIGNUM *pb = DSA_get0_priv_key(dsa2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        ok = ok && key_checked;
+    }
     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
         FFC_PARAMS *dsaparams1 = ossl_dsa_get0_params((DSA *)dsa1);
         FFC_PARAMS *dsaparams2 = ossl_dsa_get0_params((DSA *)dsa2);
index eeff1c7c201f75e26a657e6fdeff876e6b8fddfe..dd66489bce2c30c534dfff51c4ace99ff9723d6f 100644 (file)
@@ -337,17 +337,29 @@ static int ec_match(const void *keydata1, const void *keydata2, int selection)
     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
         ok = ok && group_a != NULL && group_b != NULL
             && EC_GROUP_cmp(group_a, group_b, ctx) == 0;
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
-        const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
-        const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+        int key_checked = 0;
 
-        ok = ok && BN_cmp(pa, pb) == 0;
-    }
-    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
-        const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
-        const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
+        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+            const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
+            const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
 
-        ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
+            if (pa != NULL && pb != NULL) {
+                ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
+                key_checked = 1;
+            }
+        }
+        if (!key_checked
+            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+            const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
+            const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        ok = ok && key_checked;
     }
     BN_CTX_free(ctx);
     return ok;
index b088c03b301c99b55a7281a62727b10e27125aad..2be95086924baac20d904593d035349d18c0ba44 100644 (file)
@@ -153,24 +153,39 @@ static int ecx_match(const void *keydata1, const void *keydata2, int selection)
 
     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
         ok = ok && key1->type == key2->type;
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
-        if ((key1->privkey == NULL && key2->privkey != NULL)
-                || (key1->privkey != NULL && key2->privkey == NULL)
-                || key1->type != key2->type)
-            ok = 0;
-        else
-            ok = ok && (key1->privkey == NULL /* implies key2->privkey == NULL */
-                        || CRYPTO_memcmp(key1->privkey, key2->privkey,
-                                         key1->keylen) == 0);
-    }
-    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
-        if (key1->haspubkey != key2->haspubkey
-                || key1->type != key2->type)
-            ok = 0;
-        else
-            ok = ok && (key1->haspubkey == 0 /* implies key2->haspubkey == 0 */
-                        || CRYPTO_memcmp(key1->pubkey, key2->pubkey,
-                                         key1->keylen) == 0);
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+        int key_checked = 0;
+
+        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+            const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
+            const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
+            size_t pal = key1->keylen;
+            size_t pbl = key2->keylen;
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok
+                    && key1->type == key2->type
+                    && pal == pbl
+                    && CRYPTO_memcmp(pa, pb, pal) == 0;
+                key_checked = 1;
+            }
+        }
+        if (!key_checked
+            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+            const unsigned char *pa = key1->privkey;
+            const unsigned char *pb = key2->privkey;
+            size_t pal = key1->keylen;
+            size_t pbl = key2->keylen;
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok
+                    && key1->type == key2->type
+                    && pal == pbl
+                    && CRYPTO_memcmp(pa, pb, pal) == 0;
+                key_checked = 1;
+            }
+        }
+        ok = ok && key_checked;
     }
     return ok;
 }
index 34871629ba6c80849b222f39bb8ca4832305e293..b1c3011f1452d86b520960bfcf2ddd5a2f12c052 100644 (file)
@@ -143,10 +143,30 @@ static int rsa_match(const void *keydata1, const void *keydata2, int selection)
 
     /* There is always an |e| */
     ok = ok && BN_cmp(RSA_get0_e(rsa1), RSA_get0_e(rsa2)) == 0;
-    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
-        ok = ok && BN_cmp(RSA_get0_n(rsa1), RSA_get0_n(rsa2)) == 0;
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
-        ok = ok && BN_cmp(RSA_get0_d(rsa1), RSA_get0_d(rsa2)) == 0;
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+        int key_checked = 0;
+
+        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+            const BIGNUM *pa = RSA_get0_n(rsa1);
+            const BIGNUM *pb = RSA_get0_n(rsa2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        if (!key_checked
+            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+            const BIGNUM *pa = RSA_get0_d(rsa1);
+            const BIGNUM *pb = RSA_get0_d(rsa2);
+
+            if (pa != NULL && pb != NULL) {
+                ok = ok && BN_cmp(pa, pb) == 0;
+                key_checked = 1;
+            }
+        }
+        ok = ok && key_checked;
+    }
     return ok;
 }