Blame SOURCES/0092-provider-improvements.patch

1ac26c
From 98642df4ba886818900ab7e6b23703544e6addd4 Mon Sep 17 00:00:00 2001
1ac26c
From: Simo Sorce <simo@redhat.com>
1ac26c
Date: Thu, 10 Nov 2022 10:46:32 -0500
1ac26c
Subject: [PATCH 1/3] Propagate selection all the way on key export
1ac26c
1ac26c
EVP_PKEY_eq() is used to check, among other things, if a certificate
1ac26c
public key corresponds to a private key. When the private key belongs to
1ac26c
a provider that does not allow to export private keys this currently
1ac26c
fails as the internal functions used to import/export keys ignored the
1ac26c
selection given (which specifies that only the public key needs to be
1ac26c
considered) and instead tries to export everything.
1ac26c
1ac26c
This patch allows to propagate the selection all the way down including
1ac26c
adding it in the cache so that a following operation actually looking
1ac26c
for other selection parameters does not mistakenly pick up an export
1ac26c
containing only partial information.
1ac26c
1ac26c
Signed-off-by: Simo Sorce <simo@redhat.com>
1ac26c
1ac26c
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
1ac26c
Reviewed-by: Tomas Mraz <tomas@openssl.org>
1ac26c
(Merged from https://github.com/openssl/openssl/pull/19648)
1ac26c
1ac26c
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
1ac26c
index b06730dc7a..2d0238ee27 100644
1ac26c
--- a/crypto/evp/keymgmt_lib.c
1ac26c
+++ b/crypto/evp/keymgmt_lib.c
1ac26c
@@ -93,7 +93,8 @@ int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection,
1ac26c
                               export_cb, export_cbarg);
1ac26c
 }
1ac26c
 
1ac26c
-void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
1ac26c
+void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
1ac26c
+                                          int selection)
1ac26c
 {
1ac26c
     struct evp_keymgmt_util_try_import_data_st import_data;
1ac26c
     OP_CACHE_ELEM *op;
1ac26c
@@ -127,7 +128,7 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
1ac26c
      */
1ac26c
     if (pk->dirty_cnt == pk->dirty_cnt_copy) {
1ac26c
         /* If this key is already exported to |keymgmt|, no more to do */
1ac26c
-        op = evp_keymgmt_util_find_operation_cache(pk, keymgmt);
1ac26c
+        op = evp_keymgmt_util_find_operation_cache(pk, keymgmt, selection);
1ac26c
         if (op != NULL && op->keymgmt != NULL) {
1ac26c
             void *ret = op->keydata;
1ac26c
 
1ac26c
@@ -157,13 +158,13 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
1ac26c
     /* Setup for the export callback */
1ac26c
     import_data.keydata = NULL;  /* evp_keymgmt_util_try_import will create it */
1ac26c
     import_data.keymgmt = keymgmt;
1ac26c
-    import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
1ac26c
+    import_data.selection = selection;
1ac26c
 
1ac26c
     /*
1ac26c
      * The export function calls the callback (evp_keymgmt_util_try_import),
1ac26c
      * which does the import for us.  If successful, we're done.
1ac26c
      */
1ac26c
-    if (!evp_keymgmt_util_export(pk, OSSL_KEYMGMT_SELECT_ALL,
1ac26c
+    if (!evp_keymgmt_util_export(pk, selection,
1ac26c
                                  &evp_keymgmt_util_try_import, &import_data))
1ac26c
         /* If there was an error, bail out */
1ac26c
         return NULL;
1ac26c
@@ -173,7 +174,7 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
1ac26c
         return NULL;
1ac26c
     }
1ac26c
     /* Check to make sure some other thread didn't get there first */
1ac26c
-    op = evp_keymgmt_util_find_operation_cache(pk, keymgmt);
1ac26c
+    op = evp_keymgmt_util_find_operation_cache(pk, keymgmt, selection);
1ac26c
     if (op != NULL && op->keydata != NULL) {
1ac26c
         void *ret = op->keydata;
1ac26c
 
1ac26c
@@ -196,7 +197,8 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
1ac26c
         evp_keymgmt_util_clear_operation_cache(pk, 0);
1ac26c
 
1ac26c
     /* Add the new export to the operation cache */
1ac26c
-    if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata)) {
1ac26c
+    if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata,
1ac26c
+                                        selection)) {
1ac26c
         CRYPTO_THREAD_unlock(pk->lock);
1ac26c
         evp_keymgmt_freedata(keymgmt, import_data.keydata);
1ac26c
         return NULL;
1ac26c
@@ -232,7 +234,8 @@ int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking)
1ac26c
 }
1ac26c
 
1ac26c
 OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk,
1ac26c
-                                                     EVP_KEYMGMT *keymgmt)
1ac26c
+                                                     EVP_KEYMGMT *keymgmt,
1ac26c
+                                                     int selection)
1ac26c
 {
1ac26c
     int i, end = sk_OP_CACHE_ELEM_num(pk->operation_cache);
1ac26c
     OP_CACHE_ELEM *p;
1ac26c
@@ -243,14 +246,14 @@ OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk,
1ac26c
      */
1ac26c
     for (i = 0; i < end; i++) {
1ac26c
         p = sk_OP_CACHE_ELEM_value(pk->operation_cache, i);
1ac26c
-        if (keymgmt == p->keymgmt)
1ac26c
+        if (keymgmt == p->keymgmt && (p->selection & selection) == selection)
1ac26c
             return p;
1ac26c
     }
1ac26c
     return NULL;
1ac26c
 }
1ac26c
 
1ac26c
-int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk,
1ac26c
-                                   EVP_KEYMGMT *keymgmt, void *keydata)
1ac26c
+int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
1ac26c
+                                   void *keydata, int selection)
1ac26c
 {
1ac26c
     OP_CACHE_ELEM *p = NULL;
1ac26c
 
1ac26c
@@ -266,6 +269,7 @@ int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk,
1ac26c
             return 0;
1ac26c
         p->keydata = keydata;
1ac26c
         p->keymgmt = keymgmt;
1ac26c
+        p->selection = selection;
1ac26c
 
1ac26c
         if (!EVP_KEYMGMT_up_ref(keymgmt)) {
1ac26c
             OPENSSL_free(p);
1ac26c
@@ -391,7 +395,8 @@ int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
1ac26c
             ok = 1;
1ac26c
             if (keydata1 != NULL) {
1ac26c
                 tmp_keydata =
1ac26c
-                    evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
1ac26c
+                    evp_keymgmt_util_export_to_provider(pk1, keymgmt2,
1ac26c
+                                                        selection);
1ac26c
                 ok = (tmp_keydata != NULL);
1ac26c
             }
1ac26c
             if (ok) {
1ac26c
@@ -411,7 +416,8 @@ int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
1ac26c
             ok = 1;
1ac26c
             if (keydata2 != NULL) {
1ac26c
                 tmp_keydata =
1ac26c
-                    evp_keymgmt_util_export_to_provider(pk2, keymgmt1);
1ac26c
+                    evp_keymgmt_util_export_to_provider(pk2, keymgmt1,
1ac26c
+                                                        selection);
1ac26c
                 ok = (tmp_keydata != NULL);
1ac26c
             }
1ac26c
             if (ok) {
1ac26c
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
1ac26c
index 70d17ec37e..905e9c9ce4 100644
1ac26c
--- a/crypto/evp/p_lib.c
1ac26c
+++ b/crypto/evp/p_lib.c
1ac26c
@@ -1822,6 +1822,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
1ac26c
 {
1ac26c
     EVP_KEYMGMT *allocated_keymgmt = NULL;
1ac26c
     EVP_KEYMGMT *tmp_keymgmt = NULL;
1ac26c
+    int selection = OSSL_KEYMGMT_SELECT_ALL;
1ac26c
     void *keydata = NULL;
1ac26c
     int check;
1ac26c
 
1ac26c
@@ -1883,7 +1884,8 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
1ac26c
         if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) {
1ac26c
             if (!CRYPTO_THREAD_read_lock(pk->lock))
1ac26c
                 goto end;
1ac26c
-            op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt);
1ac26c
+            op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt,
1ac26c
+                                                       selection);
1ac26c
 
1ac26c
             /*
1ac26c
              * If |tmp_keymgmt| is present in the operation cache, it means
1ac26c
@@ -1938,7 +1940,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
1ac26c
         EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */
1ac26c
 
1ac26c
         /* Check to make sure some other thread didn't get there first */
1ac26c
-        op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt);
1ac26c
+        op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt, selection);
1ac26c
         if (op != NULL && op->keymgmt != NULL) {
1ac26c
             void *tmp_keydata = op->keydata;
1ac26c
 
1ac26c
@@ -1949,7 +1951,8 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
1ac26c
         }
1ac26c
 
1ac26c
         /* Add the new export to the operation cache */
1ac26c
-        if (!evp_keymgmt_util_cache_keydata(pk, tmp_keymgmt, keydata)) {
1ac26c
+        if (!evp_keymgmt_util_cache_keydata(pk, tmp_keymgmt, keydata,
1ac26c
+                                            selection)) {
1ac26c
             CRYPTO_THREAD_unlock(pk->lock);
1ac26c
             evp_keymgmt_freedata(tmp_keymgmt, keydata);
1ac26c
             keydata = NULL;
1ac26c
@@ -1964,7 +1967,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
1ac26c
     }
1ac26c
 #endif  /* FIPS_MODULE */
1ac26c
 
1ac26c
-    keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
1ac26c
+    keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt, selection);
1ac26c
 
1ac26c
  end:
1ac26c
     /*
1ac26c
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
1ac26c
index f601b72807..dbbdcccbda 100644
1ac26c
--- a/include/crypto/evp.h
1ac26c
+++ b/include/crypto/evp.h
1ac26c
@@ -589,6 +589,7 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
1ac26c
 typedef struct {
1ac26c
     EVP_KEYMGMT *keymgmt;
1ac26c
     void *keydata;
1ac26c
+    int selection;
1ac26c
 } OP_CACHE_ELEM;
1ac26c
 
1ac26c
 DEFINE_STACK_OF(OP_CACHE_ELEM)
1ac26c
@@ -778,12 +779,14 @@ EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata);
1ac26c
 
1ac26c
 int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection,
1ac26c
                             OSSL_CALLBACK *export_cb, void *export_cbarg);
1ac26c
-void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
1ac26c
+void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
1ac26c
+                                          int selection);
1ac26c
 OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk,
1ac26c
-                                                     EVP_KEYMGMT *keymgmt);
1ac26c
+                                                     EVP_KEYMGMT *keymgmt,
1ac26c
+                                                     int selection);
1ac26c
 int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking);
1ac26c
-int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk,
1ac26c
-                                   EVP_KEYMGMT *keymgmt, void *keydata);
1ac26c
+int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
1ac26c
+                                   void *keydata, int selection);
1ac26c
 void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk);
1ac26c
 void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
1ac26c
                                 int selection, const OSSL_PARAM params[]);
1ac26c
-- 
1ac26c
2.38.1
1ac26c
1ac26c
From 504427eb5f32108dd64ff7858012863fe47b369b Mon Sep 17 00:00:00 2001
1ac26c
From: Simo Sorce <simo@redhat.com>
1ac26c
Date: Thu, 10 Nov 2022 16:58:28 -0500
1ac26c
Subject: [PATCH 2/3] Update documentation for keymgmt export utils
1ac26c
1ac26c
Change function prototypes and explain how to use the selection
1ac26c
argument.
1ac26c
1ac26c
Signed-off-by: Simo Sorce <simo@redhat.com>
1ac26c
1ac26c
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
1ac26c
Reviewed-by: Tomas Mraz <tomas@openssl.org>
1ac26c
(Merged from https://github.com/openssl/openssl/pull/19648)
1ac26c
1ac26c
diff --git a/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod b/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod
1ac26c
index 1fee9f6ff9..7099e44964 100644
1ac26c
--- a/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod
1ac26c
+++ b/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod
1ac26c
@@ -20,12 +20,14 @@ OP_CACHE_ELEM
1ac26c
 
1ac26c
  int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection,
1ac26c
                              OSSL_CALLBACK *export_cb, void *export_cbarg);
1ac26c
- void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
1ac26c
+ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
1ac26c
+                                           int selection);
1ac26c
  OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk,
1ac26c
-                                                      EVP_KEYMGMT *keymgmt);
1ac26c
+                                                      EVP_KEYMGMT *keymgmt,
1ac26c
+                                                      int selection);
1ac26c
  int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking);
1ac26c
- int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk,
1ac26c
-                                    EVP_KEYMGMT *keymgmt, void *keydata);
1ac26c
+ int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
1ac26c
+                                    void *keydata, int selection);
1ac26c
  void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk);
1ac26c
  void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
1ac26c
                                  int selection, const OSSL_PARAM params[]);
1ac26c
@@ -65,6 +67,11 @@ evp_keymgmt_util_fromdata() can be used to add key object data to a
1ac26c
 given key I<target> via a B<EVP_KEYMGMT> interface.  This is used as a
1ac26c
 helper for L<EVP_PKEY_fromdata(3)>.
1ac26c
 
1ac26c
+In all functions that take a I<selection> argument, the selection is used to
1ac26c
+constraint the information requested on export. It is also used in the cache
1ac26c
+so that key data is guaranteed to contain all the information requested in
1ac26c
+the selection.
1ac26c
+
1ac26c
 =head1 RETURN VALUES
1ac26c
 
1ac26c
 evp_keymgmt_export_to_provider() and evp_keymgmt_util_fromdata()
1ac26c
-- 
1ac26c
2.38.1
1ac26c
1ac26c
From e5202fbd461cb6c067874987998e91c6093e5267 Mon Sep 17 00:00:00 2001
1ac26c
From: Simo Sorce <simo@redhat.com>
1ac26c
Date: Fri, 11 Nov 2022 12:18:26 -0500
1ac26c
Subject: [PATCH 3/3] Add test for EVP_PKEY_eq
1ac26c
1ac26c
This tests that the comparison work even if a provider can only return
1ac26c
a public key.
1ac26c
1ac26c
Signed-off-by: Simo Sorce <simo@redhat.com>
1ac26c
1ac26c
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
1ac26c
Reviewed-by: Tomas Mraz <tomas@openssl.org>
1ac26c
(Merged from https://github.com/openssl/openssl/pull/19648)
1ac26c
1ac26c
diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c
1ac26c
index d556551bb6..5e92e72d4b 100644
1ac26c
--- a/test/fake_rsaprov.c
1ac26c
+++ b/test/fake_rsaprov.c
1ac26c
@@ -22,24 +22,34 @@ static OSSL_FUNC_keymgmt_has_fn fake_rsa_keymgmt_has;
1ac26c
 static OSSL_FUNC_keymgmt_query_operation_name_fn fake_rsa_keymgmt_query;
1ac26c
 static OSSL_FUNC_keymgmt_import_fn fake_rsa_keymgmt_import;
1ac26c
 static OSSL_FUNC_keymgmt_import_types_fn fake_rsa_keymgmt_imptypes;
1ac26c
+static OSSL_FUNC_keymgmt_export_fn fake_rsa_keymgmt_export;
1ac26c
+static OSSL_FUNC_keymgmt_export_types_fn fake_rsa_keymgmt_exptypes;
1ac26c
 static OSSL_FUNC_keymgmt_load_fn fake_rsa_keymgmt_load;
1ac26c
 
1ac26c
 static int has_selection;
1ac26c
 static int imptypes_selection;
1ac26c
+static int exptypes_selection;
1ac26c
 static int query_id;
1ac26c
 
1ac26c
+struct fake_rsa_keydata {
1ac26c
+    int selection;
1ac26c
+    int status;
1ac26c
+};
1ac26c
+
1ac26c
 static void *fake_rsa_keymgmt_new(void *provctx)
1ac26c
 {
1ac26c
-    unsigned char *keydata = OPENSSL_zalloc(1);
1ac26c
+    struct fake_rsa_keydata *key;
1ac26c
 
1ac26c
-    TEST_ptr(keydata);
1ac26c
+    if (!TEST_ptr(key = OPENSSL_zalloc(sizeof(struct fake_rsa_keydata))))
1ac26c
+        return NULL;
1ac26c
 
1ac26c
     /* clear test globals */
1ac26c
     has_selection = 0;
1ac26c
     imptypes_selection = 0;
1ac26c
+    exptypes_selection = 0;
1ac26c
     query_id = 0;
1ac26c
 
1ac26c
-    return keydata;
1ac26c
+    return key;
1ac26c
 }
1ac26c
 
1ac26c
 static void fake_rsa_keymgmt_free(void *keydata)
1ac26c
@@ -67,14 +77,104 @@ static const char *fake_rsa_keymgmt_query(int id)
1ac26c
 static int fake_rsa_keymgmt_import(void *keydata, int selection,
1ac26c
                                    const OSSL_PARAM *p)
1ac26c
 {
1ac26c
-    unsigned char *fake_rsa_key = keydata;
1ac26c
+    struct fake_rsa_keydata *fake_rsa_key = keydata;
1ac26c
 
1ac26c
     /* key was imported */
1ac26c
-    *fake_rsa_key = 1;
1ac26c
+    fake_rsa_key->status = 1;
1ac26c
 
1ac26c
     return 1;
1ac26c
 }
1ac26c
 
1ac26c
+static unsigned char fake_rsa_n[] =
1ac26c
+   "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
1ac26c
+   "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
1ac26c
+   "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
1ac26c
+   "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
1ac26c
+   "\xF5";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_e[] = "\x11";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_d[] =
1ac26c
+    "\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
1ac26c
+    "\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
1ac26c
+    "\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
1ac26c
+    "\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_p[] =
1ac26c
+    "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
1ac26c
+    "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
1ac26c
+    "\x0D";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_q[] =
1ac26c
+    "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
1ac26c
+    "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
1ac26c
+    "\x89";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_dmp1[] =
1ac26c
+    "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
1ac26c
+    "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_dmq1[] =
1ac26c
+    "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
1ac26c
+    "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
1ac26c
+    "\x51";
1ac26c
+
1ac26c
+static unsigned char fake_rsa_iqmp[] =
1ac26c
+    "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
1ac26c
+    "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
1ac26c
+
1ac26c
+OSSL_PARAM *fake_rsa_key_params(int priv)
1ac26c
+{
1ac26c
+    if (priv) {
1ac26c
+        OSSL_PARAM params[] = {
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, fake_rsa_n,
1ac26c
+                          sizeof(fake_rsa_n) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, fake_rsa_e,
1ac26c
+                          sizeof(fake_rsa_e) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D, fake_rsa_d,
1ac26c
+                          sizeof(fake_rsa_d) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, fake_rsa_p,
1ac26c
+                          sizeof(fake_rsa_p) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, fake_rsa_q,
1ac26c
+                          sizeof(fake_rsa_q) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, fake_rsa_dmp1,
1ac26c
+                          sizeof(fake_rsa_dmp1) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, fake_rsa_dmq1,
1ac26c
+                          sizeof(fake_rsa_dmq1) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, fake_rsa_iqmp,
1ac26c
+                          sizeof(fake_rsa_iqmp) -1),
1ac26c
+            OSSL_PARAM_END
1ac26c
+        };
1ac26c
+        return OSSL_PARAM_dup(params);
1ac26c
+    } else {
1ac26c
+        OSSL_PARAM params[] = {
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, fake_rsa_n,
1ac26c
+                          sizeof(fake_rsa_n) -1),
1ac26c
+            OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, fake_rsa_e,
1ac26c
+                          sizeof(fake_rsa_e) -1),
1ac26c
+            OSSL_PARAM_END
1ac26c
+        };
1ac26c
+        return OSSL_PARAM_dup(params);
1ac26c
+    }
1ac26c
+}
1ac26c
+
1ac26c
+static int fake_rsa_keymgmt_export(void *keydata, int selection,
1ac26c
+                                   OSSL_CALLBACK *param_callback, void *cbarg)
1ac26c
+{
1ac26c
+    OSSL_PARAM *params = NULL;
1ac26c
+    int ret;
1ac26c
+
1ac26c
+    if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
1ac26c
+        return 0;
1ac26c
+
1ac26c
+    if (!TEST_ptr(params = fake_rsa_key_params(0)))
1ac26c
+        return 0;
1ac26c
+
1ac26c
+    ret = param_callback(params, cbarg);
1ac26c
+    OSSL_PARAM_free(params);
1ac26c
+    return ret;
1ac26c
+}
1ac26c
+
1ac26c
 static const OSSL_PARAM fake_rsa_import_key_types[] = {
1ac26c
     OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0),
1ac26c
     OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0),
1ac26c
@@ -95,19 +195,33 @@ static const OSSL_PARAM *fake_rsa_keymgmt_imptypes(int selection)
1ac26c
     return fake_rsa_import_key_types;
1ac26c
 }
1ac26c
 
1ac26c
+static const OSSL_PARAM fake_rsa_export_key_types[] = {
1ac26c
+    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0),
1ac26c
+    OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0),
1ac26c
+    OSSL_PARAM_END
1ac26c
+};
1ac26c
+
1ac26c
+static const OSSL_PARAM *fake_rsa_keymgmt_exptypes(int selection)
1ac26c
+{
1ac26c
+    /* record global for checking */
1ac26c
+    exptypes_selection = selection;
1ac26c
+
1ac26c
+    return fake_rsa_export_key_types;
1ac26c
+}
1ac26c
+
1ac26c
 static void *fake_rsa_keymgmt_load(const void *reference, size_t reference_sz)
1ac26c
 {
1ac26c
-    unsigned char *key = NULL;
1ac26c
+    struct fake_rsa_keydata *key = NULL;
1ac26c
 
1ac26c
-    if (reference_sz != sizeof(key))
1ac26c
+    if (reference_sz != sizeof(*key))
1ac26c
         return NULL;
1ac26c
 
1ac26c
-    key = *(unsigned char **)reference;
1ac26c
-    if (*key != 1)
1ac26c
+    key = *(struct fake_rsa_keydata **)reference;
1ac26c
+    if (key->status != 1)
1ac26c
         return NULL;
1ac26c
 
1ac26c
     /* detach the reference */
1ac26c
-    *(unsigned char **)reference = NULL;
1ac26c
+    *(struct fake_rsa_keydata  **)reference = NULL;
1ac26c
 
1ac26c
     return key;
1ac26c
 }
1ac26c
@@ -129,7 +243,7 @@ static void *fake_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1ac26c
 {
1ac26c
     unsigned char *gctx = genctx;
1ac26c
     static const unsigned char inited[] = { 1 };
1ac26c
-    unsigned char *keydata;
1ac26c
+    struct fake_rsa_keydata *keydata;
1ac26c
 
1ac26c
     if (!TEST_ptr(gctx)
1ac26c
         || !TEST_mem_eq(gctx, sizeof(*gctx), inited, sizeof(inited)))
1ac26c
@@ -138,7 +252,7 @@ static void *fake_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1ac26c
     if (!TEST_ptr(keydata = fake_rsa_keymgmt_new(NULL)))
1ac26c
         return NULL;
1ac26c
 
1ac26c
-    *keydata = 2;
1ac26c
+    keydata->status = 2;
1ac26c
     return keydata;
1ac26c
 }
1ac26c
 
1ac26c
@@ -156,6 +270,9 @@ static const OSSL_DISPATCH fake_rsa_keymgmt_funcs[] = {
1ac26c
     { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))fake_rsa_keymgmt_import },
1ac26c
     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
1ac26c
         (void (*)(void))fake_rsa_keymgmt_imptypes },
1ac26c
+    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))fake_rsa_keymgmt_export },
1ac26c
+    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
1ac26c
+        (void (*)(void))fake_rsa_keymgmt_exptypes },
1ac26c
     { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))fake_rsa_keymgmt_load },
1ac26c
     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))fake_rsa_gen_init },
1ac26c
     { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))fake_rsa_gen },
1ac26c
@@ -191,14 +308,14 @@ static int fake_rsa_sig_sign_init(void *ctx, void *provkey,
1ac26c
                                   const OSSL_PARAM params[])
1ac26c
 {
1ac26c
     unsigned char *sigctx = ctx;
1ac26c
-    unsigned char *keydata = provkey;
1ac26c
+    struct fake_rsa_keydata *keydata = provkey;
1ac26c
 
1ac26c
     /* we must have a ctx */
1ac26c
     if (!TEST_ptr(sigctx))
1ac26c
         return 0;
1ac26c
 
1ac26c
     /* we must have some initialized key */
1ac26c
-    if (!TEST_ptr(keydata) || !TEST_int_gt(keydata[0], 0))
1ac26c
+    if (!TEST_ptr(keydata) || !TEST_int_gt(keydata->status, 0))
1ac26c
         return 0;
1ac26c
 
1ac26c
     /* record that sign init was called */
1ac26c
@@ -289,7 +406,7 @@ static int fake_rsa_st_load(void *loaderctx,
1ac26c
     unsigned char *storectx = loaderctx;
1ac26c
     OSSL_PARAM params[4];
1ac26c
     int object_type = OSSL_OBJECT_PKEY;
1ac26c
-    void *key = NULL;
1ac26c
+    struct fake_rsa_keydata *key = NULL;
1ac26c
     int rv = 0;
1ac26c
 
1ac26c
     switch (*storectx) {
1ac26c
@@ -307,7 +424,7 @@ static int fake_rsa_st_load(void *loaderctx,
1ac26c
         /* The address of the key becomes the octet string */
1ac26c
         params[2] =
1ac26c
             OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
1ac26c
-                                              &key, sizeof(key));
1ac26c
+                                              &key, sizeof(*key));
1ac26c
         params[3] = OSSL_PARAM_construct_end();
1ac26c
         rv = object_cb(params, object_cbarg);
1ac26c
         *storectx = 1;
1ac26c
diff --git a/test/fake_rsaprov.h b/test/fake_rsaprov.h
1ac26c
index 57de1ecf8d..190c46a285 100644
1ac26c
--- a/test/fake_rsaprov.h
1ac26c
+++ b/test/fake_rsaprov.h
1ac26c
@@ -12,3 +12,4 @@
1ac26c
 /* Fake RSA provider implementation */
1ac26c
 OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx);
1ac26c
 void fake_rsa_finish(OSSL_PROVIDER *p);
1ac26c
+OSSL_PARAM *fake_rsa_key_params(int priv);
1ac26c
diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c
1ac26c
index 5c398398f4..3b190baa5e 100644
1ac26c
--- a/test/provider_pkey_test.c
1ac26c
+++ b/test/provider_pkey_test.c
1ac26c
@@ -176,6 +176,67 @@ end:
1ac26c
     return ret;
1ac26c
 }
1ac26c
 
1ac26c
+static int test_pkey_eq(void)
1ac26c
+{
1ac26c
+    OSSL_PROVIDER *deflt = NULL;
1ac26c
+    OSSL_PROVIDER *fake_rsa = NULL;
1ac26c
+    EVP_PKEY *pkey_fake = NULL;
1ac26c
+    EVP_PKEY *pkey_dflt = NULL;
1ac26c
+    EVP_PKEY_CTX *ctx = NULL;
1ac26c
+    OSSL_PARAM *params = NULL;
1ac26c
+    int ret = 0;
1ac26c
+
1ac26c
+    if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx)))
1ac26c
+        return 0;
1ac26c
+
1ac26c
+    if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default")))
1ac26c
+        goto end;
1ac26c
+
1ac26c
+    /* Construct a public key for fake-rsa */
1ac26c
+    if (!TEST_ptr(params = fake_rsa_key_params(0))
1ac26c
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA",
1ac26c
+                                                      "provider=fake-rsa"))
1ac26c
+        || !TEST_true(EVP_PKEY_fromdata_init(ctx))
1ac26c
+        || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY,
1ac26c
+                                        params))
1ac26c
+        || !TEST_ptr(pkey_fake))
1ac26c
+        goto end;
1ac26c
+
1ac26c
+    EVP_PKEY_CTX_free(ctx);
1ac26c
+    ctx = NULL;
1ac26c
+    OSSL_PARAM_free(params);
1ac26c
+    params = NULL;
1ac26c
+
1ac26c
+    /* Construct a public key for default */
1ac26c
+    if (!TEST_ptr(params = fake_rsa_key_params(0))
1ac26c
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA",
1ac26c
+                                                      "provider=default"))
1ac26c
+        || !TEST_true(EVP_PKEY_fromdata_init(ctx))
1ac26c
+        || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_dflt, EVP_PKEY_PUBLIC_KEY,
1ac26c
+                                        params))
1ac26c
+        || !TEST_ptr(pkey_dflt))
1ac26c
+        goto end;
1ac26c
+
1ac26c
+    EVP_PKEY_CTX_free(ctx);
1ac26c
+    ctx = NULL;
1ac26c
+    OSSL_PARAM_free(params);
1ac26c
+    params = NULL;
1ac26c
+
1ac26c
+    /* now test for equality */
1ac26c
+    if (!TEST_int_eq(EVP_PKEY_eq(pkey_fake, pkey_dflt), 1))
1ac26c
+        goto end;
1ac26c
+
1ac26c
+    ret = 1;
1ac26c
+end:
1ac26c
+    fake_rsa_finish(fake_rsa);
1ac26c
+    OSSL_PROVIDER_unload(deflt);
1ac26c
+    EVP_PKEY_CTX_free(ctx);
1ac26c
+    EVP_PKEY_free(pkey_fake);
1ac26c
+    EVP_PKEY_free(pkey_dflt);
1ac26c
+    OSSL_PARAM_free(params);
1ac26c
+    return ret;
1ac26c
+}
1ac26c
+
1ac26c
 static int test_pkey_store(int idx)
1ac26c
 {
1ac26c
     OSSL_PROVIDER *deflt = NULL;
1ac26c
@@ -235,6 +296,7 @@ int setup_tests(void)
1ac26c
 
1ac26c
     ADD_TEST(test_pkey_sig);
1ac26c
     ADD_TEST(test_alternative_keygen_init);
1ac26c
+    ADD_TEST(test_pkey_eq);
1ac26c
     ADD_ALL_TESTS(test_pkey_store, 2);
1ac26c
 
1ac26c
     return 1;
1ac26c
-- 
1ac26c
2.38.1
1ac26c
1ac26c
From 2fea56832780248af2aba2e4433ece2d18428515 Mon Sep 17 00:00:00 2001
1ac26c
From: Simo Sorce <simo@redhat.com>
1ac26c
Date: Mon, 14 Nov 2022 10:25:15 -0500
1ac26c
Subject: [PATCH] Drop explicit check for engines in opt_legacy_okay
1ac26c
1ac26c
The providers indication should always indicate that this is not a
1ac26c
legacy request.
1ac26c
This makes a check for engines redundant as the default return is that
1ac26c
legacy is ok if there are no explicit providers.
1ac26c
1ac26c
Fixes #19662
1ac26c
1ac26c
Signed-off-by: Simo Sorce <simo@redhat.com>
1ac26c
1ac26c
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
1ac26c
Reviewed-by: Paul Dale <pauli@openssl.org>
1ac26c
Reviewed-by: Tomas Mraz <tomas@openssl.org>
1ac26c
(Merged from https://github.com/openssl/openssl/pull/19671)
1ac26c
---
1ac26c
 apps/lib/apps.c                    |  8 --------
1ac26c
 test/recipes/20-test_legacy_okay.t | 23 +++++++++++++++++++++++
1ac26c
 2 files changed, 23 insertions(+), 8 deletions(-)
1ac26c
 create mode 100755 test/recipes/20-test_legacy_okay.t
1ac26c
1ac26c
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
1ac26c
index 3d52e030ab7e258f9cd983b2d9755d954cb3aee5..bbe0d009efb35fcf1a902c86cbddc61e657e57f1 100644
1ac26c
--- a/apps/lib/apps.c
1ac26c
+++ b/apps/lib/apps.c
1ac26c
@@ -3405,14 +3405,6 @@ int opt_legacy_okay(void)
1ac26c
 {
1ac26c
     int provider_options = opt_provider_option_given();
1ac26c
     int libctx = app_get0_libctx() != NULL || app_get0_propq() != NULL;
1ac26c
-#ifndef OPENSSL_NO_ENGINE
1ac26c
-    ENGINE *e = ENGINE_get_first();
1ac26c
-
1ac26c
-    if (e != NULL) {
1ac26c
-        ENGINE_free(e);
1ac26c
-        return 1;
1ac26c
-    }
1ac26c
-#endif
1ac26c
     /*
1ac26c
      * Having a provider option specified or a custom library context or
1ac26c
      * property query, is a sure sign we're not using legacy.
1ac26c
diff --git a/test/recipes/20-test_legacy_okay.t b/test/recipes/20-test_legacy_okay.t
1ac26c
new file mode 100755
1ac26c
index 0000000000000000000000000000000000000000..183499f3fd93f97e8a4a30681a9f383d2f6e0c56
1ac26c
--- /dev/null
1ac26c
+++ b/test/recipes/20-test_legacy_okay.t
1ac26c
@@ -0,0 +1,23 @@
1ac26c
+#! /usr/bin/env perl
1ac26c
+# Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
1ac26c
+#
1ac26c
+# Licensed under the Apache License 2.0 (the "License").  You may not use
1ac26c
+# this file except in compliance with the License.  You can obtain a copy
1ac26c
+# in the file LICENSE in the source distribution or at
1ac26c
+# https://www.openssl.org/source/license.html
1ac26c
+
1ac26c
+use strict;
1ac26c
+use warnings;
1ac26c
+
1ac26c
+use OpenSSL::Test;
1ac26c
+
1ac26c
+setup("test_legacy");
1ac26c
+
1ac26c
+plan tests => 3;
1ac26c
+
1ac26c
+ok(run(app(['openssl', 'rand', '-out', 'rand.txt', '256'])), "Generate random file");
1ac26c
+
1ac26c
+ok(run(app(['openssl', 'dgst', '-sha256', 'rand.txt'])), "Generate a digest");
1ac26c
+
1ac26c
+ok(!run(app(['openssl', 'dgst', '-sha256', '-propquery', 'foo=1',
1ac26c
+             'rand.txt'])), "Fail to generate a digest");
1ac26c
-- 
1ac26c
2.38.1
1ac26c