@@ -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
196211static 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+
203231static void *
204232inner_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
301355void * 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
372389void evp_method_store_flush (OPENSSL_CTX * libctx )
0 commit comments