1 | /* |
2 | * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at |
7 | * https://www.openssl.org/source/license.html |
8 | */ |
9 | |
10 | #include <openssl/core.h> |
11 | #include <openssl/core_numbers.h> |
12 | #include <openssl/core_names.h> |
13 | #include <openssl/params.h> |
14 | #include <openssl/opensslv.h> |
15 | #include "crypto/cryptlib.h" |
16 | #include "internal/nelem.h" |
17 | #include "internal/thread_once.h" |
18 | #include "internal/provider.h" |
19 | #include "internal/refcount.h" |
20 | #include "provider_local.h" |
21 | |
22 | static OSSL_PROVIDER *provider_new(const char *name, |
23 | OSSL_provider_init_fn *init_function); |
24 | |
25 | /*- |
26 | * Provider Object structure |
27 | * ========================= |
28 | */ |
29 | |
30 | typedef struct { |
31 | char *name; |
32 | char *value; |
33 | } INFOPAIR; |
34 | DEFINE_STACK_OF(INFOPAIR) |
35 | |
36 | struct provider_store_st; /* Forward declaration */ |
37 | |
38 | struct ossl_provider_st { |
39 | /* Flag bits */ |
40 | unsigned int flag_initialized:1; |
41 | unsigned int flag_fallback:1; |
42 | |
43 | /* OpenSSL library side data */ |
44 | CRYPTO_REF_COUNT refcnt; |
45 | CRYPTO_RWLOCK *refcnt_lock; /* For the ref counter */ |
46 | char *name; |
47 | char *path; |
48 | DSO *module; |
49 | OSSL_provider_init_fn *init_function; |
50 | STACK_OF(INFOPAIR) *parameters; |
51 | OPENSSL_CTX *libctx; /* The library context this instance is in */ |
52 | struct provider_store_st *store; /* The store this instance belongs to */ |
53 | #ifndef FIPS_MODE |
54 | /* |
55 | * In the FIPS module inner provider, this isn't needed, since the |
56 | * error upcalls are always direct calls to the outer provider. |
57 | */ |
58 | int error_lib; /* ERR library number, one for each provider */ |
59 | # ifndef OPENSSL_NO_ERR |
60 | ERR_STRING_DATA *error_strings; /* Copy of what the provider gives us */ |
61 | # endif |
62 | #endif |
63 | |
64 | /* Provider side functions */ |
65 | OSSL_provider_teardown_fn *teardown; |
66 | OSSL_provider_gettable_params_fn *gettable_params; |
67 | OSSL_provider_get_params_fn *get_params; |
68 | OSSL_provider_query_operation_fn *query_operation; |
69 | |
70 | /* Provider side data */ |
71 | void *provctx; |
72 | }; |
73 | DEFINE_STACK_OF(OSSL_PROVIDER) |
74 | |
75 | static int ossl_provider_cmp(const OSSL_PROVIDER * const *a, |
76 | const OSSL_PROVIDER * const *b) |
77 | { |
78 | return strcmp((*a)->name, (*b)->name); |
79 | } |
80 | |
81 | /*- |
82 | * Provider Object store |
83 | * ===================== |
84 | * |
85 | * The Provider Object store is a library context object, and therefore needs |
86 | * an index. |
87 | */ |
88 | |
89 | struct provider_store_st { |
90 | STACK_OF(OSSL_PROVIDER) *providers; |
91 | CRYPTO_RWLOCK *lock; |
92 | unsigned int use_fallbacks:1; |
93 | }; |
94 | |
95 | static void provider_store_free(void *vstore) |
96 | { |
97 | struct provider_store_st *store = vstore; |
98 | |
99 | if (store == NULL) |
100 | return; |
101 | sk_OSSL_PROVIDER_pop_free(store->providers, ossl_provider_free); |
102 | CRYPTO_THREAD_lock_free(store->lock); |
103 | OPENSSL_free(store); |
104 | } |
105 | |
106 | static void *provider_store_new(OPENSSL_CTX *ctx) |
107 | { |
108 | struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store)); |
109 | const struct predefined_providers_st *p = NULL; |
110 | |
111 | if (store == NULL |
112 | || (store->providers = sk_OSSL_PROVIDER_new(ossl_provider_cmp)) == NULL |
113 | || (store->lock = CRYPTO_THREAD_lock_new()) == NULL) { |
114 | provider_store_free(store); |
115 | return NULL; |
116 | } |
117 | store->use_fallbacks = 1; |
118 | |
119 | for (p = predefined_providers; p->name != NULL; p++) { |
120 | OSSL_PROVIDER *prov = NULL; |
121 | |
122 | /* |
123 | * We use the internal constructor directly here, |
124 | * otherwise we get a call loop |
125 | */ |
126 | prov = provider_new(p->name, p->init); |
127 | |
128 | if (prov == NULL |
129 | || sk_OSSL_PROVIDER_push(store->providers, prov) == 0) { |
130 | ossl_provider_free(prov); |
131 | provider_store_free(store); |
132 | CRYPTOerr(CRYPTO_F_PROVIDER_STORE_NEW, ERR_R_INTERNAL_ERROR); |
133 | return NULL; |
134 | } |
135 | prov->libctx = ctx; |
136 | prov->store = store; |
137 | #ifndef FIPS_MODE |
138 | prov->error_lib = ERR_get_next_error_library(); |
139 | #endif |
140 | if(p->is_fallback) |
141 | ossl_provider_set_fallback(prov); |
142 | } |
143 | |
144 | return store; |
145 | } |
146 | |
147 | static const OPENSSL_CTX_METHOD provider_store_method = { |
148 | provider_store_new, |
149 | provider_store_free, |
150 | }; |
151 | |
152 | static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx) |
153 | { |
154 | struct provider_store_st *store = NULL; |
155 | |
156 | store = openssl_ctx_get_data(libctx, OPENSSL_CTX_PROVIDER_STORE_INDEX, |
157 | &provider_store_method); |
158 | if (store == NULL) |
159 | CRYPTOerr(CRYPTO_F_GET_PROVIDER_STORE, ERR_R_INTERNAL_ERROR); |
160 | return store; |
161 | } |
162 | |
163 | OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name, |
164 | int noconfig) |
165 | { |
166 | struct provider_store_st *store = NULL; |
167 | OSSL_PROVIDER *prov = NULL; |
168 | |
169 | if ((store = get_provider_store(libctx)) != NULL) { |
170 | OSSL_PROVIDER tmpl = { 0, }; |
171 | int i; |
172 | |
173 | #ifndef FIPS_MODE |
174 | /* |
175 | * Make sure any providers are loaded from config before we try to find |
176 | * them. |
177 | */ |
178 | if (!noconfig) |
179 | OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); |
180 | #endif |
181 | |
182 | tmpl.name = (char *)name; |
183 | CRYPTO_THREAD_write_lock(store->lock); |
184 | if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) == -1 |
185 | || (prov = sk_OSSL_PROVIDER_value(store->providers, i)) == NULL |
186 | || !ossl_provider_up_ref(prov)) |
187 | prov = NULL; |
188 | CRYPTO_THREAD_unlock(store->lock); |
189 | } |
190 | |
191 | return prov; |
192 | } |
193 | |
194 | /*- |
195 | * Provider Object methods |
196 | * ======================= |
197 | */ |
198 | |
199 | static OSSL_PROVIDER *provider_new(const char *name, |
200 | OSSL_provider_init_fn *init_function) |
201 | { |
202 | OSSL_PROVIDER *prov = NULL; |
203 | |
204 | if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL |
205 | #ifndef HAVE_ATOMICS |
206 | || (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL |
207 | #endif |
208 | || !ossl_provider_up_ref(prov) /* +1 One reference to be returned */ |
209 | || (prov->name = OPENSSL_strdup(name)) == NULL) { |
210 | ossl_provider_free(prov); |
211 | CRYPTOerr(CRYPTO_F_PROVIDER_NEW, ERR_R_MALLOC_FAILURE); |
212 | return NULL; |
213 | } |
214 | |
215 | prov->init_function = init_function; |
216 | return prov; |
217 | } |
218 | |
219 | int ossl_provider_up_ref(OSSL_PROVIDER *prov) |
220 | { |
221 | int ref = 0; |
222 | |
223 | if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) |
224 | return 0; |
225 | return ref; |
226 | } |
227 | |
228 | OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, |
229 | OSSL_provider_init_fn *init_function, |
230 | int noconfig) |
231 | { |
232 | struct provider_store_st *store = NULL; |
233 | OSSL_PROVIDER *prov = NULL; |
234 | |
235 | if ((store = get_provider_store(libctx)) == NULL) |
236 | return NULL; |
237 | |
238 | if ((prov = ossl_provider_find(libctx, name, |
239 | noconfig)) != NULL) { /* refcount +1 */ |
240 | ossl_provider_free(prov); /* refcount -1 */ |
241 | ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_ALREADY_EXISTS, NULL, |
242 | "name=%s" , name); |
243 | return NULL; |
244 | } |
245 | |
246 | /* provider_new() generates an error, so no need here */ |
247 | if ((prov = provider_new(name, init_function)) == NULL) |
248 | return NULL; |
249 | |
250 | CRYPTO_THREAD_write_lock(store->lock); |
251 | if (!ossl_provider_up_ref(prov)) { /* +1 One reference for the store */ |
252 | ossl_provider_free(prov); /* -1 Reference that was to be returned */ |
253 | prov = NULL; |
254 | } else if (sk_OSSL_PROVIDER_push(store->providers, prov) == 0) { |
255 | ossl_provider_free(prov); /* -1 Store reference */ |
256 | ossl_provider_free(prov); /* -1 Reference that was to be returned */ |
257 | prov = NULL; |
258 | } else { |
259 | prov->libctx = libctx; |
260 | prov->store = store; |
261 | #ifndef FIPS_MODE |
262 | prov->error_lib = ERR_get_next_error_library(); |
263 | #endif |
264 | } |
265 | CRYPTO_THREAD_unlock(store->lock); |
266 | |
267 | if (prov == NULL) |
268 | CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_NEW, ERR_R_MALLOC_FAILURE); |
269 | |
270 | /* |
271 | * At this point, the provider is only partially "loaded". To be |
272 | * fully "loaded", ossl_provider_activate() must also be called. |
273 | */ |
274 | |
275 | return prov; |
276 | } |
277 | |
278 | static void free_infopair(INFOPAIR *pair) |
279 | { |
280 | OPENSSL_free(pair->name); |
281 | OPENSSL_free(pair->value); |
282 | OPENSSL_free(pair); |
283 | } |
284 | |
285 | void ossl_provider_free(OSSL_PROVIDER *prov) |
286 | { |
287 | if (prov != NULL) { |
288 | int ref = 0; |
289 | |
290 | CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); |
291 | |
292 | /* |
293 | * When the refcount drops below two, the store is the only |
294 | * possible reference, or it has already been taken away from |
295 | * the store (this may happen if a provider was activated |
296 | * because it's a fallback, but isn't currently used) |
297 | * When that happens, the provider is inactivated. |
298 | */ |
299 | if (ref < 2 && prov->flag_initialized) { |
300 | #ifndef FIPS_MODE |
301 | ossl_init_thread_deregister(prov); |
302 | #endif |
303 | if (prov->teardown != NULL) |
304 | prov->teardown(prov->provctx); |
305 | #ifndef OPENSSL_NO_ERR |
306 | # ifndef FIPS_MODE |
307 | if (prov->error_strings != NULL) { |
308 | ERR_unload_strings(prov->error_lib, prov->error_strings); |
309 | OPENSSL_free(prov->error_strings); |
310 | prov->error_strings = NULL; |
311 | } |
312 | # endif |
313 | #endif |
314 | prov->flag_initialized = 0; |
315 | } |
316 | |
317 | /* |
318 | * When the refcount drops to zero, it has been taken out of |
319 | * the store. All we have to do here is clean it out. |
320 | */ |
321 | if (ref == 0) { |
322 | #ifndef FIPS_MODE |
323 | DSO_free(prov->module); |
324 | #endif |
325 | OPENSSL_free(prov->name); |
326 | OPENSSL_free(prov->path); |
327 | sk_INFOPAIR_pop_free(prov->parameters, free_infopair); |
328 | #ifndef HAVE_ATOMICS |
329 | CRYPTO_THREAD_lock_free(prov->refcnt_lock); |
330 | #endif |
331 | OPENSSL_free(prov); |
332 | } |
333 | } |
334 | } |
335 | |
336 | /* Setters */ |
337 | int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path) |
338 | { |
339 | OPENSSL_free(prov->path); |
340 | if (module_path == NULL) |
341 | return 1; |
342 | if ((prov->path = OPENSSL_strdup(module_path)) != NULL) |
343 | return 1; |
344 | CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH, ERR_R_MALLOC_FAILURE); |
345 | return 0; |
346 | } |
347 | |
348 | int ossl_provider_add_parameter(OSSL_PROVIDER *prov, |
349 | const char *name, const char *value) |
350 | { |
351 | INFOPAIR *pair = NULL; |
352 | |
353 | if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL |
354 | && (prov->parameters != NULL |
355 | || (prov->parameters = sk_INFOPAIR_new_null()) != NULL) |
356 | && (pair->name = OPENSSL_strdup(name)) != NULL |
357 | && (pair->value = OPENSSL_strdup(value)) != NULL |
358 | && sk_INFOPAIR_push(prov->parameters, pair) > 0) |
359 | return 1; |
360 | |
361 | if (pair != NULL) { |
362 | OPENSSL_free(pair->name); |
363 | OPENSSL_free(pair->value); |
364 | OPENSSL_free(pair); |
365 | } |
366 | CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, ERR_R_MALLOC_FAILURE); |
367 | return 0; |
368 | } |
369 | |
370 | /* |
371 | * Provider activation. |
372 | * |
373 | * What "activation" means depends on the provider form; for built in |
374 | * providers (in the library or the application alike), the provider |
375 | * can already be considered to be loaded, all that's needed is to |
376 | * initialize it. However, for dynamically loadable provider modules, |
377 | * we must first load that module. |
378 | * |
379 | * Built in modules are distinguished from dynamically loaded modules |
380 | * with an already assigned init function. |
381 | */ |
382 | static const OSSL_DISPATCH *core_dispatch; /* Define further down */ |
383 | |
384 | /* |
385 | * Internal version that doesn't affect the store flags, and thereby avoid |
386 | * locking. Direct callers must remember to set the store flags when |
387 | * appropriate. |
388 | */ |
389 | static int provider_activate(OSSL_PROVIDER *prov) |
390 | { |
391 | const OSSL_DISPATCH *provider_dispatch = NULL; |
392 | #ifndef OPENSSL_NO_ERR |
393 | # ifndef FIPS_MODE |
394 | OSSL_provider_get_reason_strings_fn *p_get_reason_strings = NULL; |
395 | # endif |
396 | #endif |
397 | |
398 | if (prov->flag_initialized) |
399 | return 1; |
400 | |
401 | /* |
402 | * If the init function isn't set, it indicates that this provider is |
403 | * a loadable module. |
404 | */ |
405 | if (prov->init_function == NULL) { |
406 | #ifdef FIPS_MODE |
407 | return 0; |
408 | #else |
409 | if (prov->module == NULL) { |
410 | char *allocated_path = NULL; |
411 | const char *module_path = NULL; |
412 | char *merged_path = NULL; |
413 | const char *load_dir = ossl_safe_getenv("OPENSSL_MODULES" ); |
414 | |
415 | if ((prov->module = DSO_new()) == NULL) { |
416 | /* DSO_new() generates an error already */ |
417 | return 0; |
418 | } |
419 | |
420 | if (load_dir == NULL) |
421 | load_dir = MODULESDIR; |
422 | |
423 | DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS, |
424 | DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL); |
425 | |
426 | module_path = prov->path; |
427 | if (module_path == NULL) |
428 | module_path = allocated_path = |
429 | DSO_convert_filename(prov->module, prov->name); |
430 | if (module_path != NULL) |
431 | merged_path = DSO_merge(prov->module, module_path, load_dir); |
432 | |
433 | if (merged_path == NULL |
434 | || (DSO_load(prov->module, merged_path, NULL, 0)) == NULL) { |
435 | DSO_free(prov->module); |
436 | prov->module = NULL; |
437 | } |
438 | |
439 | OPENSSL_free(merged_path); |
440 | OPENSSL_free(allocated_path); |
441 | } |
442 | |
443 | if (prov->module != NULL) |
444 | prov->init_function = (OSSL_provider_init_fn *) |
445 | DSO_bind_func(prov->module, "OSSL_provider_init" ); |
446 | #endif |
447 | } |
448 | |
449 | /* Call the initialise function for the provider. */ |
450 | if (prov->init_function == NULL |
451 | || !prov->init_function(prov, core_dispatch, &provider_dispatch, |
452 | &prov->provctx)) { |
453 | ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, NULL, |
454 | "name=%s" , prov->name); |
455 | #ifndef FIPS_MODE |
456 | DSO_free(prov->module); |
457 | prov->module = NULL; |
458 | #endif |
459 | return 0; |
460 | } |
461 | |
462 | for (; provider_dispatch->function_id != 0; provider_dispatch++) { |
463 | switch (provider_dispatch->function_id) { |
464 | case OSSL_FUNC_PROVIDER_TEARDOWN: |
465 | prov->teardown = |
466 | OSSL_get_provider_teardown(provider_dispatch); |
467 | break; |
468 | case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS: |
469 | prov->gettable_params = |
470 | OSSL_get_provider_gettable_params(provider_dispatch); |
471 | break; |
472 | case OSSL_FUNC_PROVIDER_GET_PARAMS: |
473 | prov->get_params = |
474 | OSSL_get_provider_get_params(provider_dispatch); |
475 | break; |
476 | case OSSL_FUNC_PROVIDER_QUERY_OPERATION: |
477 | prov->query_operation = |
478 | OSSL_get_provider_query_operation(provider_dispatch); |
479 | break; |
480 | #ifndef OPENSSL_NO_ERR |
481 | # ifndef FIPS_MODE |
482 | case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS: |
483 | p_get_reason_strings = |
484 | OSSL_get_provider_get_reason_strings(provider_dispatch); |
485 | break; |
486 | # endif |
487 | #endif |
488 | } |
489 | } |
490 | |
491 | #ifndef OPENSSL_NO_ERR |
492 | # ifndef FIPS_MODE |
493 | if (p_get_reason_strings != NULL) { |
494 | const OSSL_ITEM *reasonstrings = p_get_reason_strings(prov->provctx); |
495 | size_t cnt, cnt2; |
496 | |
497 | /* |
498 | * ERR_load_strings() handles ERR_STRING_DATA rather than OSSL_ITEM, |
499 | * although they are essentially the same type. |
500 | * Furthermore, ERR_load_strings() patches the array's error number |
501 | * with the error library number, so we need to make a copy of that |
502 | * array either way. |
503 | */ |
504 | cnt = 1; /* One for the terminating item */ |
505 | while (reasonstrings[cnt].id != 0) { |
506 | if (ERR_GET_LIB(reasonstrings[cnt].id) != 0) |
507 | return 0; |
508 | cnt++; |
509 | } |
510 | |
511 | /* Allocate one extra item for the "library" name */ |
512 | prov->error_strings = |
513 | OPENSSL_zalloc(sizeof(ERR_STRING_DATA) * (cnt + 1)); |
514 | if (prov->error_strings == NULL) |
515 | return 0; |
516 | |
517 | /* |
518 | * Set the "library" name. |
519 | */ |
520 | prov->error_strings[0].error = ERR_PACK(prov->error_lib, 0, 0); |
521 | prov->error_strings[0].string = prov->name; |
522 | /* |
523 | * Copy reasonstrings item 0..cnt-1 to prov->error_trings positions |
524 | * 1..cnt. |
525 | */ |
526 | for (cnt2 = 1; cnt2 <= cnt; cnt2++) { |
527 | prov->error_strings[cnt2].error = (int)reasonstrings[cnt2-1].id; |
528 | prov->error_strings[cnt2].string = reasonstrings[cnt2-1].ptr; |
529 | } |
530 | |
531 | ERR_load_strings(prov->error_lib, prov->error_strings); |
532 | } |
533 | # endif |
534 | #endif |
535 | |
536 | /* With this flag set, this provider has become fully "loaded". */ |
537 | prov->flag_initialized = 1; |
538 | |
539 | return 1; |
540 | } |
541 | |
542 | int ossl_provider_activate(OSSL_PROVIDER *prov) |
543 | { |
544 | if (provider_activate(prov)) { |
545 | CRYPTO_THREAD_write_lock(prov->store->lock); |
546 | prov->store->use_fallbacks = 0; |
547 | CRYPTO_THREAD_unlock(prov->store->lock); |
548 | return 1; |
549 | } |
550 | |
551 | return 0; |
552 | } |
553 | |
554 | void *ossl_provider_ctx(const OSSL_PROVIDER *prov) |
555 | { |
556 | return prov->provctx; |
557 | } |
558 | |
559 | |
560 | static int provider_forall_loaded(struct provider_store_st *store, |
561 | int *found_activated, |
562 | int (*cb)(OSSL_PROVIDER *provider, |
563 | void *cbdata), |
564 | void *cbdata) |
565 | { |
566 | int i; |
567 | int ret = 1; |
568 | int num_provs; |
569 | |
570 | num_provs = sk_OSSL_PROVIDER_num(store->providers); |
571 | |
572 | if (found_activated != NULL) |
573 | *found_activated = 0; |
574 | for (i = 0; i < num_provs; i++) { |
575 | OSSL_PROVIDER *prov = |
576 | sk_OSSL_PROVIDER_value(store->providers, i); |
577 | |
578 | if (prov->flag_initialized) { |
579 | if (found_activated != NULL) |
580 | *found_activated = 1; |
581 | if (!(ret = cb(prov, cbdata))) |
582 | break; |
583 | } |
584 | } |
585 | |
586 | return ret; |
587 | } |
588 | |
589 | /* |
590 | * This function only does something once when store->use_fallbacks == 1, |
591 | * and then sets store->use_fallbacks = 0, so the second call and so on is |
592 | * effectively a no-op. |
593 | */ |
594 | static void provider_activate_fallbacks(struct provider_store_st *store) |
595 | { |
596 | if (store->use_fallbacks) { |
597 | int num_provs = sk_OSSL_PROVIDER_num(store->providers); |
598 | int activated_fallback_count = 0; |
599 | int i; |
600 | |
601 | for (i = 0; i < num_provs; i++) { |
602 | OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i); |
603 | |
604 | /* |
605 | * Note that we don't care if the activation succeeds or not. |
606 | * If it doesn't succeed, then any attempt to use any of the |
607 | * fallback providers will fail anyway. |
608 | */ |
609 | if (prov->flag_fallback) { |
610 | activated_fallback_count++; |
611 | provider_activate(prov); |
612 | } |
613 | } |
614 | |
615 | /* |
616 | * We assume that all fallbacks have been added to the store before |
617 | * any fallback is activated. |
618 | * TODO: We may have to reconsider this, IF we find ourselves adding |
619 | * fallbacks after any previous fallback has been activated. |
620 | */ |
621 | if (activated_fallback_count > 0) |
622 | store->use_fallbacks = 0; |
623 | } |
624 | } |
625 | |
626 | int ossl_provider_forall_loaded(OPENSSL_CTX *ctx, |
627 | int (*cb)(OSSL_PROVIDER *provider, |
628 | void *cbdata), |
629 | void *cbdata) |
630 | { |
631 | int ret = 1; |
632 | struct provider_store_st *store = get_provider_store(ctx); |
633 | |
634 | #ifndef FIPS_MODE |
635 | /* |
636 | * Make sure any providers are loaded from config before we try to use |
637 | * them. |
638 | */ |
639 | OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); |
640 | #endif |
641 | |
642 | if (store != NULL) { |
643 | CRYPTO_THREAD_read_lock(store->lock); |
644 | |
645 | provider_activate_fallbacks(store); |
646 | |
647 | /* |
648 | * Now, we sweep through all providers |
649 | */ |
650 | ret = provider_forall_loaded(store, NULL, cb, cbdata); |
651 | |
652 | CRYPTO_THREAD_unlock(store->lock); |
653 | } |
654 | |
655 | return ret; |
656 | } |
657 | |
658 | int ossl_provider_available(OSSL_PROVIDER *prov) |
659 | { |
660 | if (prov != NULL) { |
661 | CRYPTO_THREAD_read_lock(prov->store->lock); |
662 | provider_activate_fallbacks(prov->store); |
663 | CRYPTO_THREAD_unlock(prov->store->lock); |
664 | |
665 | return prov->flag_initialized; |
666 | } |
667 | return 0; |
668 | } |
669 | |
670 | /* Setters of Provider Object data */ |
671 | int ossl_provider_set_fallback(OSSL_PROVIDER *prov) |
672 | { |
673 | if (prov == NULL) |
674 | return 0; |
675 | |
676 | prov->flag_fallback = 1; |
677 | return 1; |
678 | } |
679 | |
680 | /* Getters of Provider Object data */ |
681 | const char *ossl_provider_name(const OSSL_PROVIDER *prov) |
682 | { |
683 | return prov->name; |
684 | } |
685 | |
686 | const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov) |
687 | { |
688 | return prov->module; |
689 | } |
690 | |
691 | const char *ossl_provider_module_name(const OSSL_PROVIDER *prov) |
692 | { |
693 | #ifdef FIPS_MODE |
694 | return NULL; |
695 | #else |
696 | return DSO_get_filename(prov->module); |
697 | #endif |
698 | } |
699 | |
700 | const char *ossl_provider_module_path(const OSSL_PROVIDER *prov) |
701 | { |
702 | #ifdef FIPS_MODE |
703 | return NULL; |
704 | #else |
705 | /* FIXME: Ensure it's a full path */ |
706 | return DSO_get_filename(prov->module); |
707 | #endif |
708 | } |
709 | |
710 | OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov) |
711 | { |
712 | /* TODO(3.0) just: return prov->libctx; */ |
713 | return prov != NULL ? prov->libctx : NULL; |
714 | } |
715 | |
716 | /* Wrappers around calls to the provider */ |
717 | void ossl_provider_teardown(const OSSL_PROVIDER *prov) |
718 | { |
719 | if (prov->teardown != NULL) |
720 | prov->teardown(prov->provctx); |
721 | } |
722 | |
723 | const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov) |
724 | { |
725 | return prov->gettable_params == NULL |
726 | ? NULL : prov->gettable_params(prov->provctx); |
727 | } |
728 | |
729 | int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) |
730 | { |
731 | return prov->get_params == NULL |
732 | ? 0 : prov->get_params(prov->provctx, params); |
733 | } |
734 | |
735 | |
736 | const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, |
737 | int operation_id, |
738 | int *no_cache) |
739 | { |
740 | return prov->query_operation(prov->provctx, operation_id, no_cache); |
741 | } |
742 | |
743 | /*- |
744 | * Core functions for the provider |
745 | * =============================== |
746 | * |
747 | * This is the set of functions that the core makes available to the provider |
748 | */ |
749 | |
750 | /* |
751 | * This returns a list of Provider Object parameters with their types, for |
752 | * discovery. We do not expect that many providers will use this, but one |
753 | * never knows. |
754 | */ |
755 | static const OSSL_PARAM param_types[] = { |
756 | OSSL_PARAM_DEFN("openssl-version" , OSSL_PARAM_UTF8_PTR, NULL, 0), |
757 | OSSL_PARAM_DEFN("provider-name" , OSSL_PARAM_UTF8_PTR, NULL, 0), |
758 | OSSL_PARAM_END |
759 | }; |
760 | |
761 | /* |
762 | * Forward declare all the functions that are provided aa dispatch. |
763 | * This ensures that the compiler will complain if they aren't defined |
764 | * with the correct signature. |
765 | */ |
766 | static OSSL_core_gettable_params_fn core_gettable_params; |
767 | static OSSL_core_get_params_fn core_get_params; |
768 | static OSSL_core_thread_start_fn core_thread_start; |
769 | static OSSL_core_get_library_context_fn core_get_libctx; |
770 | #ifndef FIPS_MODE |
771 | static OSSL_core_new_error_fn core_new_error; |
772 | static OSSL_core_set_error_debug_fn core_set_error_debug; |
773 | static OSSL_core_vset_error_fn core_vset_error; |
774 | #endif |
775 | |
776 | static const OSSL_PARAM *core_gettable_params(const OSSL_PROVIDER *prov) |
777 | { |
778 | return param_types; |
779 | } |
780 | |
781 | static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) |
782 | { |
783 | int i; |
784 | OSSL_PARAM *p; |
785 | |
786 | if ((p = OSSL_PARAM_locate(params, "openssl-version" )) != NULL) |
787 | OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR); |
788 | if ((p = OSSL_PARAM_locate(params, "provider-name" )) != NULL) |
789 | OSSL_PARAM_set_utf8_ptr(p, prov->name); |
790 | |
791 | #ifndef FIPS_MODE |
792 | if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_MODULE_FILENAME)) != NULL) |
793 | OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov)); |
794 | #endif |
795 | |
796 | if (prov->parameters == NULL) |
797 | return 1; |
798 | |
799 | for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) { |
800 | INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i); |
801 | |
802 | if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL) |
803 | OSSL_PARAM_set_utf8_ptr(p, pair->value); |
804 | } |
805 | return 1; |
806 | } |
807 | |
808 | static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov) |
809 | { |
810 | return ossl_provider_library_context(prov); |
811 | } |
812 | |
813 | static int core_thread_start(const OSSL_PROVIDER *prov, |
814 | OSSL_thread_stop_handler_fn handfn) |
815 | { |
816 | return ossl_init_thread_start(prov, prov->provctx, handfn); |
817 | } |
818 | |
819 | /* |
820 | * The FIPS module inner provider doesn't implement these. They aren't |
821 | * needed there, since the FIPS module upcalls are always the outer provider |
822 | * ones. |
823 | */ |
824 | #ifndef FIPS_MODE |
825 | /* |
826 | * TODO(3.0) These error functions should use |prov| to select the proper |
827 | * library context to report in the correct error stack, at least if error |
828 | * stacks become tied to the library context. |
829 | * We cannot currently do that since there's no support for it in the |
830 | * ERR subsystem. |
831 | */ |
832 | static void core_new_error(const OSSL_PROVIDER *prov) |
833 | { |
834 | ERR_new(); |
835 | } |
836 | |
837 | static void core_set_error_debug(const OSSL_PROVIDER *prov, |
838 | const char *file, int line, const char *func) |
839 | { |
840 | ERR_set_debug(file, line, func); |
841 | } |
842 | |
843 | static void core_vset_error(const OSSL_PROVIDER *prov, |
844 | uint32_t reason, const char *fmt, va_list args) |
845 | { |
846 | /* |
847 | * If the uppermost 8 bits are non-zero, it's an OpenSSL library |
848 | * error and will be treated as such. Otherwise, it's a new style |
849 | * provider error and will be treated as such. |
850 | */ |
851 | if (ERR_GET_LIB(reason) != 0) { |
852 | ERR_vset_error(ERR_GET_LIB(reason), ERR_GET_REASON(reason), fmt, args); |
853 | } else { |
854 | ERR_vset_error(prov->error_lib, (int)reason, fmt, args); |
855 | } |
856 | } |
857 | #endif |
858 | |
859 | /* |
860 | * Functions provided by the core. Blank line separates "families" of related |
861 | * functions. |
862 | */ |
863 | static const OSSL_DISPATCH core_dispatch_[] = { |
864 | { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, |
865 | { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, |
866 | { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx }, |
867 | { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start }, |
868 | #ifndef FIPS_MODE |
869 | { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error }, |
870 | { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug }, |
871 | { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error }, |
872 | { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))BIO_new_file }, |
873 | { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf }, |
874 | { OSSL_FUNC_BIO_READ_EX, (void (*)(void))BIO_read_ex }, |
875 | { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free }, |
876 | { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf }, |
877 | #endif |
878 | |
879 | { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, |
880 | { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, |
881 | { OSSL_FUNC_CRYPTO_FREE, (void (*)(void))CRYPTO_free }, |
882 | { OSSL_FUNC_CRYPTO_CLEAR_FREE, (void (*)(void))CRYPTO_clear_free }, |
883 | { OSSL_FUNC_CRYPTO_REALLOC, (void (*)(void))CRYPTO_realloc }, |
884 | { OSSL_FUNC_CRYPTO_CLEAR_REALLOC, (void (*)(void))CRYPTO_clear_realloc }, |
885 | { OSSL_FUNC_CRYPTO_SECURE_MALLOC, (void (*)(void))CRYPTO_secure_malloc }, |
886 | { OSSL_FUNC_CRYPTO_SECURE_ZALLOC, (void (*)(void))CRYPTO_secure_zalloc }, |
887 | { OSSL_FUNC_CRYPTO_SECURE_FREE, (void (*)(void))CRYPTO_secure_free }, |
888 | { OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE, |
889 | (void (*)(void))CRYPTO_secure_clear_free }, |
890 | { OSSL_FUNC_CRYPTO_SECURE_ALLOCATED, |
891 | (void (*)(void))CRYPTO_secure_allocated }, |
892 | { OSSL_FUNC_OPENSSL_CLEANSE, (void (*)(void))OPENSSL_cleanse }, |
893 | |
894 | { 0, NULL } |
895 | }; |
896 | static const OSSL_DISPATCH *core_dispatch = core_dispatch_; |
897 | |