Allow to pass a passprase callback at store open
authorSimo Sorce <simo@redhat.com>
Mon, 23 Jan 2023 22:28:21 +0000 (17:28 -0500)
committerDmitry Belyavskiy <beldmit@gmail.com>
Tue, 19 Sep 2023 10:24:07 +0000 (12:24 +0200)
Some PKCS11 modules require authentication early on to be able to
preload objects, which we want to do to avoid costly roundtrips when the
HSM is actually reached over a network (Cloud HSM).

Unfortunately at open time we can't interact with the user becaue the
callbacks are only passed at object load time. later on.

This patch corrects this issue by providing a more feature rich open
call for providers.

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20131)

crypto/store/store_lib.c
crypto/store/store_local.h
crypto/store/store_meth.c
include/openssl/core_dispatch.h

index a68e8e28b62de797fcc08c56fe6c2e66810ee001..d0561f636cfde859e852355d7809a70ef1f30406 100644 (file)
@@ -66,6 +66,7 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq,
                    OSSL_STORE_post_process_info_fn post_process,
                    void *post_process_data)
 {
+    struct ossl_passphrase_data_st pwdata = { 0 };
     const OSSL_STORE_LOADER *loader = NULL;
     OSSL_STORE_LOADER *fetched_loader = NULL;
     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
@@ -102,6 +103,13 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq,
 
     ERR_set_mark();
 
+    if (ui_method != NULL
+        && (!ossl_pw_set_ui_method(&pwdata, ui_method, ui_data)
+            || !ossl_pw_enable_passphrase_caching(&pwdata))) {
+        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB);
+        goto err;
+    }
+
     /*
      * Try each scheme until we find one that could open the URI.
      *
@@ -135,17 +143,28 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq,
             void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider);
 
             no_loader_found = 0;
-            loader_ctx = fetched_loader->p_open(provctx, uri);
+            if (fetched_loader->p_open_ex != NULL) {
+                loader_ctx =
+                    fetched_loader->p_open_ex(provctx, uri, params,
+                                              ossl_pw_passphrase_callback_dec,
+                                              &pwdata);
+            } else {
+                loader_ctx = fetched_loader->p_open(provctx, uri);
+                if (loader_ctx != NULL &&
+                    !loader_set_params(fetched_loader, loader_ctx,
+                                       params, propq)) {
+                    (void)fetched_loader->p_close(loader_ctx);
+                    loader_ctx = NULL;
+                }
+            }
             if (loader_ctx == NULL) {
                 OSSL_STORE_LOADER_free(fetched_loader);
                 fetched_loader = NULL;
-            } else if (!loader_set_params(fetched_loader, loader_ctx,
-                                          params, propq)) {
-                (void)fetched_loader->p_close(loader_ctx);
-                OSSL_STORE_LOADER_free(fetched_loader);
-                fetched_loader = NULL;
             }
             loader = fetched_loader;
+
+            /* Clear any internally cached passphrase */
+            (void)ossl_pw_clear_passphrase_cache(&pwdata);
         }
     }
 
@@ -171,18 +190,13 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq,
         || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
         goto err;
 
-    if (ui_method != NULL
-        && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)
-            || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) {
-        ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB);
-        goto err;
-    }
     ctx->properties = propq_copy;
     ctx->fetched_loader = fetched_loader;
     ctx->loader = loader;
     ctx->loader_ctx = loader_ctx;
     ctx->post_process = post_process;
     ctx->post_process_data = post_process_data;
+    ctx->pwdata = pwdata;
 
     /*
      * If the attempt to open with the 'file' scheme loader failed and the
index 06c8c9b218885442d43538324547e20565cedc9e..6ad79180a091f620707bf904dfa674c7d43ab71b 100644 (file)
@@ -113,6 +113,7 @@ struct ossl_store_loader_st {
     OSSL_FUNC_store_close_fn *p_close;
     OSSL_FUNC_store_export_object_fn *p_export_object;
     OSSL_FUNC_store_delete_fn *p_delete;
+    OSSL_FUNC_store_open_ex_fn *p_open_ex;
 };
 DEFINE_LHASH_OF_EX(OSSL_STORE_LOADER);
 
index 766777c3a0295f7e10f1d128c4f8d7ea70c9b2cc..6ac8fd5f9374b61f47125c65eca0d334dde46cd9 100644 (file)
@@ -223,6 +223,10 @@ static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef,
             if (loader->p_delete == NULL)
                 loader->p_delete = OSSL_FUNC_store_delete(fns);
             break;
+        case OSSL_FUNC_STORE_OPEN_EX:
+            if (loader->p_open_ex == NULL)
+                loader->p_open_ex = OSSL_FUNC_store_open_ex(fns);
+            break;
         }
     }
 
index 9631626ae36bf29c68d616fc805332e21ac55054..73f040285cd5134172b80855a7611ab34db6a169 100644 (file)
@@ -937,6 +937,7 @@ OSSL_CORE_MAKE_FUNC(int, decoder_export_object,
 #define OSSL_FUNC_STORE_CLOSE                       7
 #define OSSL_FUNC_STORE_EXPORT_OBJECT               8
 #define OSSL_FUNC_STORE_DELETE                      9
+#define OSSL_FUNC_STORE_OPEN_EX                     10
 OSSL_CORE_MAKE_FUNC(void *, store_open, (void *provctx, const char *uri))
 OSSL_CORE_MAKE_FUNC(void *, store_attach, (void *provctx, OSSL_CORE_BIO *in))
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, store_settable_ctx_params,
@@ -955,6 +956,9 @@ OSSL_CORE_MAKE_FUNC(int, store_export_object,
 OSSL_CORE_MAKE_FUNC(int, store_delete,
                     (void *provctx, const char *uri, const OSSL_PARAM params[],
                      OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg))
+OSSL_CORE_MAKE_FUNC(void *, store_open_ex,
+                    (void *provctx, const char *uri, const OSSL_PARAM params[],
+                     OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg))
 
 # ifdef __cplusplus
 }