summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/evp/evp_local.h3
-rw-r--r--crypto/store/store_result.c22
-rw-r--r--include/crypto/evp.h3
3 files changed, 23 insertions, 5 deletions
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index d9e1ca997e..74a94bc45d 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -298,9 +298,6 @@ void evp_generic_do_all(OSSL_LIB_CTX *libctx, int operation_id,
/* Internal fetchers for method types that are to be combined with others */
EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OSSL_LIB_CTX *ctx, int name_id,
const char *properties);
-EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
- const char *name,
- const char *properties);
EVP_SIGNATURE *evp_signature_fetch_from_prov(OSSL_PROVIDER *prov,
const char *name,
const char *properties);
diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c
index 6f83da4beb..96d3119907 100644
--- a/crypto/store/store_result.c
+++ b/crypto/store/store_result.c
@@ -191,13 +191,15 @@ static EVP_PKEY *try_key_ref(struct extracted_param_data_st *data,
EVP_PKEY *pk = NULL;
EVP_KEYMGMT *keymgmt = NULL;
void *keydata = NULL;
+ int try_fallback = 2;
/* If we have an object reference, we must have a data type */
if (data->data_type == NULL)
return 0;
keymgmt = EVP_KEYMGMT_fetch(libctx, data->data_type, propq);
- if (keymgmt != NULL) {
+ ERR_set_mark();
+ while (keymgmt != NULL && keydata == NULL && try_fallback-- > 0) {
/*
* There are two possible cases
*
@@ -207,6 +209,8 @@ static EVP_PKEY *try_key_ref(struct extracted_param_data_st *data,
* do the export/import dance.
*/
if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) {
+ /* no point trying fallback here */
+ try_fallback = 0;
keydata = evp_keymgmt_load(keymgmt, data->ref, data->ref_size);
} else {
struct evp_keymgmt_util_try_import_data_st import_data;
@@ -230,9 +234,23 @@ static EVP_PKEY *try_key_ref(struct extracted_param_data_st *data,
keydata = import_data.keydata;
}
+
+ if (keydata == NULL && try_fallback > 0) {
+ EVP_KEYMGMT_free(keymgmt);
+ keymgmt = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)provider,
+ data->data_type, propq);
+ if (keymgmt != NULL) {
+ ERR_pop_to_mark();
+ ERR_set_mark();
+ }
+ }
}
- if (keydata != NULL)
+ if (keydata != NULL) {
+ ERR_pop_to_mark();
pk = evp_keymgmt_util_make_pkey(keymgmt, keydata);
+ } else {
+ ERR_clear_last_mark();
+ }
EVP_KEYMGMT_free(keymgmt);
return pk;
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 9db5d89430..eeac4ee9f1 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -838,6 +838,9 @@ const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
int selection);
void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt,
const void *keydata_from, int selection);
+EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
+ const char *name,
+ const char *properties);
/* Pulling defines out of C source files */