summaryrefslogtreecommitdiffstats
path: root/crypto/store
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/store')
-rw-r--r--crypto/store/store_meth.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c
index 166b885806..979f42a16d 100644
--- a/crypto/store/store_meth.c
+++ b/crypto/store/store_meth.c
@@ -92,6 +92,8 @@ struct loader_data_st {
int scheme_id; /* For get_loader_from_store() */
const char *scheme; /* For get_loader_from_store() */
const char *propquery; /* For get_loader_from_store() */
+
+ unsigned int flag_construct_error_occured : 1;
};
/*
@@ -227,7 +229,7 @@ static void *loader_from_dispatch(int scheme_id, const OSSL_ALGORITHM *algodef,
* then call loader_from_dispatch() with that identity number.
*/
static void *construct_loader(const OSSL_ALGORITHM *algodef,
- OSSL_PROVIDER *prov, void *unused)
+ OSSL_PROVIDER *prov, void *data)
{
/*
* This function is only called if get_loader_from_store() returned
@@ -235,6 +237,7 @@ static void *construct_loader(const OSSL_ALGORITHM *algodef,
* namemap entry, this is it. Should the scheme already exist there, we
* know that ossl_namemap_add() will return its corresponding number.
*/
+ struct loader_data_st *methdata = data;
OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
const char *scheme = algodef->algorithm_names;
@@ -244,6 +247,14 @@ static void *construct_loader(const OSSL_ALGORITHM *algodef,
if (id != 0)
method = loader_from_dispatch(id, algodef, prov);
+ /*
+ * Flag to indicate that there was actual construction errors. This
+ * helps inner_evp_generic_fetch() determine what error it should
+ * record on inaccessible algorithms.
+ */
+ if (method == NULL)
+ methdata->flag_construct_error_occured = 1;
+
return method;
}
@@ -261,20 +272,33 @@ static OSSL_STORE_LOADER *inner_loader_fetch(OSSL_LIB_CTX *libctx,
OSSL_METHOD_STORE *store = get_loader_store(libctx);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
void *method = NULL;
+ int unsupported = 0;
- if (store == NULL || namemap == NULL)
+ if (store == NULL || namemap == NULL) {
+ ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
+ }
/*
* If we have been passed neither a scheme_id or a scheme, we have an
* internal programming error.
*/
- if (!ossl_assert(id != 0 || scheme != NULL))
+ if (!ossl_assert(id != 0 || scheme != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR);
return NULL;
+ }
+ /* If we haven't received a name id yet, try to get one for the name */
if (id == 0)
id = ossl_namemap_name2num(namemap, scheme);
+ /*
+ * If we haven't found the name yet, chances are that the algorithm to
+ * be fetched is unsupported.
+ */
+ if (id == 0)
+ unsupported = 1;
+
if (id == 0
|| !ossl_method_store_cache_get(store, id, properties, &method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
@@ -292,6 +316,7 @@ static OSSL_STORE_LOADER *inner_loader_fetch(OSSL_LIB_CTX *libctx,
mcmdata.scheme_id = id;
mcmdata.scheme = scheme;
mcmdata.propquery = properties;
+ mcmdata.flag_construct_error_occured = 0;
if ((method = ossl_method_construct(libctx, OSSL_OP_STORE,
0 /* !force_cache */,
&mcm, &mcmdata)) != NULL) {
@@ -305,6 +330,24 @@ static OSSL_STORE_LOADER *inner_loader_fetch(OSSL_LIB_CTX *libctx,
ossl_method_store_cache_set(store, id, properties, method,
up_ref_loader, free_loader);
}
+
+ /*
+ * If we never were in the constructor, the algorithm to be fetched
+ * is unsupported.
+ */
+ unsupported = !mcmdata.flag_construct_error_occured;
+ }
+
+ if (method == NULL) {
+ int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED;
+
+ if (scheme == NULL)
+ scheme = ossl_namemap_num2name(namemap, id, 0);
+ ERR_raise_data(ERR_LIB_OSSL_STORE, code,
+ "%s, Scheme (%s : %d), Properties (%s)",
+ ossl_lib_ctx_get_descriptor(libctx),
+ scheme = NULL ? "<null>" : scheme, id,
+ properties == NULL ? "<null>" : properties);
}
return method;