return 1;
}
+
+const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx)
+{
+#ifdef FIPS_MODULE
+ return "FIPS internal library context";
+#else
+ if (ossl_lib_ctx_is_global_default(libctx))
+ return "Global default library context";
+ if (ossl_lib_ctx_is_default(libctx))
+ return "Thread-local default library context";
+ return "Non-default library context";
+#endif
+}
int id; /* For get_decoder_from_store() */
const char *names; /* For get_decoder_from_store() */
const char *propquery; /* For get_decoder_from_store() */
+
+ unsigned int flag_construct_error_occured : 1;
};
/*
* then call ossl_decoder_from_dispatch() with that identity number.
*/
static void *construct_decoder(const OSSL_ALGORITHM *algodef,
- OSSL_PROVIDER *prov, void *unused)
+ OSSL_PROVIDER *prov, void *data)
{
/*
* This function is only called if get_decoder_from_store() returned
* namemap entry, this is it. Should the name already exist there, we
* know that ossl_namemap_add() will return its corresponding number.
*/
+ struct decoder_data_st *methdata = data;
OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
const char *names = algodef->algorithm_names;
if (id != 0)
method = ossl_decoder_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;
}
OSSL_METHOD_STORE *store = get_decoder_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_DECODER, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
+ }
/*
* If we have been passed neither a name_id or a name, we have an
* internal programming error.
*/
- if (!ossl_assert(id != 0 || name != NULL))
+ if (!ossl_assert(id != 0 || name != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR);
return NULL;
+ }
if (id == 0)
id = ossl_namemap_name2num(namemap, name);
+ /*
+ * 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 = {
mcmdata.id = id;
mcmdata.names = name;
mcmdata.propquery = properties;
+ mcmdata.flag_construct_error_occured = 0;
if ((method = ossl_method_construct(libctx, OSSL_OP_DECODER,
0 /* !force_cache */,
&mcm, &mcmdata)) != NULL) {
ossl_method_store_cache_set(store, id, properties, method,
up_ref_decoder, free_decoder);
}
+
+ /*
+ * 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 (name == NULL)
+ name = ossl_namemap_num2name(namemap, id, 0);
+ ERR_raise_data(ERR_LIB_OSSL_DECODER, code,
+ "%s, Name (%s : %d), Properties (%s)",
+ ossl_lib_ctx_get_descriptor(libctx),
+ name = NULL ? "<null>" : name, id,
+ properties == NULL ? "<null>" : properties);
}
return method;
int id; /* For get_encoder_from_store() */
const char *names; /* For get_encoder_from_store() */
const char *propquery; /* For get_encoder_from_store() */
+
+ unsigned int flag_construct_error_occured : 1;
};
/*
* then call encoder_from_dispatch() with that identity number.
*/
static void *construct_encoder(const OSSL_ALGORITHM *algodef,
- OSSL_PROVIDER *prov, void *unused)
+ OSSL_PROVIDER *prov, void *data)
{
/*
* This function is only called if get_encoder_from_store() returned
* namemap entry, this is it. Should the name already exist there, we
* know that ossl_namemap_add() will return its corresponding number.
*/
+ struct encoder_data_st *methdata = data;
OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
const char *names = algodef->algorithm_names;
if (id != 0)
method = encoder_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;
}
OSSL_METHOD_STORE *store = get_encoder_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_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
+ }
/*
* If we have been passed neither a name_id or a name, we have an
* internal programming error.
*/
- if (!ossl_assert(id != 0 || name != NULL))
+ if (!ossl_assert(id != 0 || name != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR);
return NULL;
+ }
if (id == 0)
id = ossl_namemap_name2num(namemap, name);
+ /*
+ * 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 = {
mcmdata.id = id;
mcmdata.names = name;
mcmdata.propquery = properties;
+ mcmdata.flag_construct_error_occured = 0;
if ((method = ossl_method_construct(libctx, OSSL_OP_ENCODER,
0 /* !force_cache */,
&mcm, &mcmdata)) != NULL) {
ossl_method_store_cache_set(store, id, properties, method,
up_ref_encoder, free_encoder);
}
+
+ /*
+ * 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 (name == NULL)
+ name = ossl_namemap_num2name(namemap, id, 0);
+ ERR_raise_data(ERR_LIB_OSSL_ENCODER, code,
+ "%s, Name (%s : %d), Properties (%s)",
+ ossl_lib_ctx_get_descriptor(libctx),
+ name = NULL ? "<null>" : name, id,
+ properties == NULL ? "<null>" : properties);
}
return method;
{ERR_R_INVALID_PROVIDER_FUNCTIONS, "invalid provider functions"},
{ERR_R_INTERRUPTED_OR_CANCELLED, "interrupted or cancelled"},
+ /*
+ * Something is unsupported, exactly what is expressed with additional data
+ */
+ {ERR_R_UNSUPPORTED, "unsupported"},
+ /*
+ * A fetch failed for other reasons than the name to be fetched being
+ * unsupported.
+ */
+ {ERR_R_FETCH_FAILED, "fetch failed"},
{0, NULL},
};
#endif
EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key
EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key
EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key
-EVP_R_FETCH_FAILED:202:fetch failed
EVP_R_FINAL_ERROR:188:final error
EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported
EVP_R_GENERATE_ERROR:214:generate error
"expecting a poly1305 key"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY),
"expecting a siphash key"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FETCH_FAILED), "fetch failed"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FINAL_ERROR), "final error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED),
"fips mode not supported"},
methdata->destruct_method(method);
}
-static const char *libctx_descriptor(OSSL_LIB_CTX *libctx)
-{
-#ifdef FIPS_MODULE
- return "FIPS internal library context";
-#else
- if (ossl_lib_ctx_is_global_default(libctx))
- return "Global default library context";
- if (ossl_lib_ctx_is_default(libctx))
- return "Thread-local default library context";
- return "Non-default library context";
-#endif
-}
-
static void *
inner_evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
int name_id, const char *name,
int unsupported = 0;
if (store == NULL || namemap == NULL) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT);
+ ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
* programming error.
*/
if (!ossl_assert(operation_id > 0)) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
return NULL;
}
* internal programming error.
*/
if (!ossl_assert(name_id != 0 || name != NULL)) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
return NULL;
}
* For all intents and purposes, this is an internal error.
*/
if (name_id != 0 && (meth_id = evp_method_id(name_id, operation_id)) == 0) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
return NULL;
}
}
if (method == NULL) {
- int code =
- unsupported ? EVP_R_UNSUPPORTED_ALGORITHM : EVP_R_FETCH_FAILED;
+ int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED;
if (name == NULL)
name = ossl_namemap_num2name(namemap, name_id, 0);
ERR_raise_data(ERR_LIB_EVP, code,
"%s, Algorithm (%s : %d), Properties (%s)",
- libctx_descriptor(libctx),
+ ossl_lib_ctx_get_descriptor(libctx),
name = NULL ? "<null>" : name, name_id,
properties == NULL ? "<null>" : properties);
}
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;
};
/*
* 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
* 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;
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;
}
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 = {
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) {
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;
int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx,
ossl_lib_ctx_run_once_fn run_once_fn);
int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn);
+const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx);
OSSL_LIB_CTX *crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad);
int crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
# define ERR_R_INTERRUPTED_OR_CANCELLED (265|ERR_RFLAG_COMMON)
# define ERR_R_NESTED_ASN1_ERROR (266|ERR_RFLAG_COMMON)
# define ERR_R_MISSING_ASN1_EOS (267|ERR_RFLAG_COMMON)
+# define ERR_R_UNSUPPORTED (268|ERR_RFLAG_COMMON)
+# define ERR_R_FETCH_FAILED (269|ERR_RFLAG_COMMON)
typedef struct ERR_string_data_st {
unsigned long error;
# define EVP_R_EXPECTING_A_EC_KEY 142
# define EVP_R_EXPECTING_A_POLY1305_KEY 164
# define EVP_R_EXPECTING_A_SIPHASH_KEY 175
-# define EVP_R_FETCH_FAILED 202
# define EVP_R_FINAL_ERROR 188
# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167
# define EVP_R_GENERATE_ERROR 214