Skip to content

Commit ec0ce18

Browse files
committed
EVP: Centralise fetching error reporting
Instead of sometimes, and sometimes not reporting an error in the caller of EVP_XXX_fetch(), where the error may or may not be very accurate, it's now centralised to the inner EVP fetch functionality. It's made in such a way that it can determine if an error occured because the algorithm in question is not there, or if something else went wrong, and will report EVP_R_UNSUPPORTED_ALGORITHM for the former, and EVP_R_FETCH_FAILED for the latter. This helps our own test/evp_test.c when it tries to figure out why an EVP_PKEY it tried to load failed to do so. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from #12857)
1 parent 225c966 commit ec0ce18

4 files changed

Lines changed: 81 additions & 69 deletions

File tree

crypto/evp/digest.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,8 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
213213
#else
214214
EVP_MD *provmd = EVP_MD_fetch(NULL, OBJ_nid2sn(type->type), "");
215215

216-
if (provmd == NULL) {
217-
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
216+
if (provmd == NULL)
218217
return 0;
219-
}
220218
type = provmd;
221219
EVP_MD_free(ctx->fetched_digest);
222220
ctx->fetched_digest = provmd;

crypto/evp/evp_enc.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,8 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
174174
: OBJ_nid2sn(cipher->nid),
175175
"");
176176

177-
if (provciph == NULL) {
178-
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
177+
if (provciph == NULL)
179178
return 0;
180-
}
181179
cipher = provciph;
182180
EVP_CIPHER_free(ctx->fetched_cipher);
183181
ctx->fetched_cipher = provciph;

crypto/evp/evp_fetch.c

Lines changed: 78 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ struct evp_method_data_st {
4747
int name_id; /* For get_evp_method_from_store() */
4848
const char *names; /* For get_evp_method_from_store() */
4949
const char *propquery; /* For get_evp_method_from_store() */
50+
51+
unsigned int flag_construct_error_occured : 1;
52+
5053
void *(*method_from_dispatch)(int name_id, const OSSL_DISPATCH *,
5154
OSSL_PROVIDER *);
5255
int (*refcnt_up_method)(void *method);
@@ -186,11 +189,23 @@ static void *construct_evp_method(const OSSL_ALGORITHM *algodef,
186189
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
187190
const char *names = algodef->algorithm_names;
188191
int name_id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
192+
void *method;
189193

190194
if (name_id == 0)
191195
return NULL;
192-
return methdata->method_from_dispatch(name_id, algodef->implementation,
193-
prov);
196+
197+
method = methdata->method_from_dispatch(name_id, algodef->implementation,
198+
prov);
199+
200+
/*
201+
* Flag to indicate that there was actual construction errors. This
202+
* helps inner_evp_generic_fetch() determine what error it should
203+
* record on inaccessible algorithms.
204+
*/
205+
if (method == NULL)
206+
methdata->flag_construct_error_occured = 1;
207+
208+
return method;
194209
}
195210

196211
static void destruct_evp_method(void *method, void *data)
@@ -200,6 +215,19 @@ static void destruct_evp_method(void *method, void *data)
200215
methdata->destruct_method(method);
201216
}
202217

218+
static const char *libctx_descriptor(OPENSSL_CTX *libctx)
219+
{
220+
#ifdef FIPS_MODULE
221+
return "FIPS internal library context";
222+
#else
223+
if (openssl_ctx_is_global_default(libctx))
224+
return "Global default library context";
225+
if (openssl_ctx_is_default(libctx))
226+
return "Thread-local default library context";
227+
return "Non-default library context";
228+
#endif
229+
}
230+
203231
static void *
204232
inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
205233
int name_id, const char *name,
@@ -214,23 +242,30 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
214242
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
215243
uint32_t meth_id = 0;
216244
void *method = NULL;
245+
int unsupported = 0;
217246

218-
if (store == NULL || namemap == NULL)
247+
if (store == NULL || namemap == NULL) {
248+
ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT);
219249
return NULL;
250+
}
220251

221252
/*
222253
* If there's ever an operation_id == 0 passed, we have an internal
223254
* programming error.
224255
*/
225-
if (!ossl_assert(operation_id > 0))
256+
if (!ossl_assert(operation_id > 0)) {
257+
ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
226258
return NULL;
259+
}
227260

228261
/*
229262
* If we have been passed neither a name_id or a name, we have an
230263
* internal programming error.
231264
*/
232-
if (!ossl_assert(name_id != 0 || name != NULL))
265+
if (!ossl_assert(name_id != 0 || name != NULL)) {
266+
ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
233267
return NULL;
268+
}
234269

235270
/* If we haven't received a name id yet, try to get one for the name */
236271
if (name_id == 0)
@@ -242,9 +277,19 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
242277
* evp_method_id returns 0 if we have too many operations (more than
243278
* about 2^8) or too many names (more than about 2^24). In that case,
244279
* we can't create any new method.
280+
* For all intents and purposes, this is an internal error.
245281
*/
246-
if (name_id != 0 && (meth_id = evp_method_id(name_id, operation_id)) == 0)
282+
if (name_id != 0 && (meth_id = evp_method_id(name_id, operation_id)) == 0) {
283+
ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
247284
return NULL;
285+
}
286+
287+
/*
288+
* If we haven't found the name yet, chances are that the algorithm to
289+
* be fetched is unsupported.
290+
*/
291+
if (name_id == 0)
292+
unsupported = 1;
248293

249294
if (meth_id == 0
250295
|| !ossl_method_store_cache_get(store, meth_id, properties, &method)) {
@@ -267,6 +312,7 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
267312
mcmdata.method_from_dispatch = new_method;
268313
mcmdata.refcnt_up_method = up_ref_method;
269314
mcmdata.destruct_method = free_method;
315+
mcmdata.flag_construct_error_occured = 0;
270316
if ((method = ossl_method_construct(libctx, operation_id,
271317
0 /* !force_cache */,
272318
&mcm, &mcmdata)) != NULL) {
@@ -282,21 +328,29 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
282328
ossl_method_store_cache_set(store, meth_id, properties, method,
283329
up_ref_method, free_method);
284330
}
331+
332+
/*
333+
* If we never were in the constructor, the algorithm to be fetched
334+
* is unsupported.
335+
*/
336+
unsupported = !mcmdata.flag_construct_error_occured;
285337
}
286338

287-
return method;
288-
}
339+
if (method == NULL) {
340+
int code =
341+
unsupported ? EVP_R_UNSUPPORTED_ALGORITHM : EVP_R_FETCH_FAILED;
289342

290-
#ifndef FIPS_MODULE
291-
static const char *libctx_descriptor(OPENSSL_CTX *libctx)
292-
{
293-
if (openssl_ctx_is_global_default(libctx))
294-
return "Global default library context";
295-
if (openssl_ctx_is_default(libctx))
296-
return "Thread-local default library context";
297-
return "Non-default library context";
343+
if (name == NULL)
344+
name = ossl_namemap_num2name(namemap, name_id, 0);
345+
ERR_raise_data(ERR_LIB_EVP, code,
346+
"%s, Algorithm (%s : %d), Properties (%s)",
347+
libctx_descriptor(libctx),
348+
name = NULL ? "<null>" : name, name_id,
349+
properties == NULL ? "<null>" : properties);
350+
}
351+
352+
return method;
298353
}
299-
#endif
300354

301355
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
302356
const char *name, const char *properties,
@@ -306,24 +360,9 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
306360
int (*up_ref_method)(void *),
307361
void (*free_method)(void *))
308362
{
309-
void *ret = inner_evp_generic_fetch(libctx,
310-
operation_id, 0, name, properties,
311-
new_method, up_ref_method, free_method);
312-
313-
if (ret == NULL) {
314-
int code = EVP_R_FETCH_FAILED;
315-
316-
#ifdef FIPS_MODULE
317-
ERR_raise(ERR_LIB_EVP, code);
318-
#else
319-
ERR_raise_data(ERR_LIB_EVP, code,
320-
"%s, Algorithm (%s), Properties (%s)",
321-
libctx_descriptor(libctx),
322-
name = NULL ? "<null>" : name,
323-
properties == NULL ? "<null>" : properties);
324-
#endif
325-
}
326-
return ret;
363+
return inner_evp_generic_fetch(libctx,
364+
operation_id, 0, name, properties,
365+
new_method, up_ref_method, free_method);
327366
}
328367

329368
/*
@@ -341,32 +380,10 @@ void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id,
341380
int (*up_ref_method)(void *),
342381
void (*free_method)(void *))
343382
{
344-
void *ret = inner_evp_generic_fetch(libctx,
345-
operation_id, name_id, NULL,
346-
properties, new_method, up_ref_method,
347-
free_method);
348-
349-
if (ret == NULL) {
350-
int code = EVP_R_FETCH_FAILED;
351-
352-
#ifdef FIPS_MODULE
353-
ERR_raise(ERR_LIB_EVP, code);
354-
#else
355-
{
356-
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
357-
const char *name = (namemap == NULL)
358-
? NULL
359-
: ossl_namemap_num2name(namemap, name_id, 0);
360-
361-
ERR_raise_data(ERR_LIB_EVP, code,
362-
"%s, Algorithm (%s), Properties (%s)",
363-
libctx_descriptor(libctx),
364-
name = NULL ? "<null>" : name,
365-
properties == NULL ? "<null>" : properties);
366-
}
367-
#endif
368-
}
369-
return ret;
383+
return inner_evp_generic_fetch(libctx,
384+
operation_id, name_id, NULL,
385+
properties, new_method, up_ref_method,
386+
free_method);
370387
}
371388

372389
void evp_method_store_flush(OPENSSL_CTX *libctx)

test/evp_test.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3254,8 +3254,7 @@ static int key_unsupported(void)
32543254
long err = ERR_peek_last_error();
32553255

32563256
if (ERR_GET_LIB(err) == ERR_LIB_EVP
3257-
&& (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM
3258-
|| ERR_GET_REASON(err) == EVP_R_FETCH_FAILED)) {
3257+
&& (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM)) {
32593258
ERR_clear_error();
32603259
return 1;
32613260
}

0 commit comments

Comments
 (0)