xref: /freebsd/crypto/openssl/apps/lib/app_provider.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery  * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*b077aed3SPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*b077aed3SPierre Pronchery  * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery  * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery  */
9*b077aed3SPierre Pronchery 
10*b077aed3SPierre Pronchery #include "apps.h"
11*b077aed3SPierre Pronchery #include <string.h>
12*b077aed3SPierre Pronchery #include <openssl/err.h>
13*b077aed3SPierre Pronchery #include <openssl/provider.h>
14*b077aed3SPierre Pronchery #include <openssl/safestack.h>
15*b077aed3SPierre Pronchery 
16*b077aed3SPierre Pronchery /* Non-zero if any of the provider options have been seen */
17*b077aed3SPierre Pronchery static int provider_option_given = 0;
18*b077aed3SPierre Pronchery 
19*b077aed3SPierre Pronchery DEFINE_STACK_OF(OSSL_PROVIDER)
20*b077aed3SPierre Pronchery 
21*b077aed3SPierre Pronchery /*
22*b077aed3SPierre Pronchery  * See comments in opt_verify for explanation of this.
23*b077aed3SPierre Pronchery  */
24*b077aed3SPierre Pronchery enum prov_range { OPT_PROV_ENUM };
25*b077aed3SPierre Pronchery 
26*b077aed3SPierre Pronchery static STACK_OF(OSSL_PROVIDER) *app_providers = NULL;
27*b077aed3SPierre Pronchery 
provider_free(OSSL_PROVIDER * prov)28*b077aed3SPierre Pronchery static void provider_free(OSSL_PROVIDER *prov)
29*b077aed3SPierre Pronchery {
30*b077aed3SPierre Pronchery     OSSL_PROVIDER_unload(prov);
31*b077aed3SPierre Pronchery }
32*b077aed3SPierre Pronchery 
app_provider_load(OSSL_LIB_CTX * libctx,const char * provider_name)33*b077aed3SPierre Pronchery int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name)
34*b077aed3SPierre Pronchery {
35*b077aed3SPierre Pronchery     OSSL_PROVIDER *prov;
36*b077aed3SPierre Pronchery 
37*b077aed3SPierre Pronchery     prov = OSSL_PROVIDER_load(libctx, provider_name);
38*b077aed3SPierre Pronchery     if (prov == NULL) {
39*b077aed3SPierre Pronchery         opt_printf_stderr("%s: unable to load provider %s\n"
40*b077aed3SPierre Pronchery                           "Hint: use -provider-path option or OPENSSL_MODULES environment variable.\n",
41*b077aed3SPierre Pronchery                           opt_getprog(), provider_name);
42*b077aed3SPierre Pronchery         ERR_print_errors(bio_err);
43*b077aed3SPierre Pronchery         return 0;
44*b077aed3SPierre Pronchery     }
45*b077aed3SPierre Pronchery     if (app_providers == NULL)
46*b077aed3SPierre Pronchery         app_providers = sk_OSSL_PROVIDER_new_null();
47*b077aed3SPierre Pronchery     if (app_providers == NULL
48*b077aed3SPierre Pronchery         || !sk_OSSL_PROVIDER_push(app_providers, prov)) {
49*b077aed3SPierre Pronchery         app_providers_cleanup();
50*b077aed3SPierre Pronchery         return 0;
51*b077aed3SPierre Pronchery     }
52*b077aed3SPierre Pronchery     return 1;
53*b077aed3SPierre Pronchery }
54*b077aed3SPierre Pronchery 
app_providers_cleanup(void)55*b077aed3SPierre Pronchery void app_providers_cleanup(void)
56*b077aed3SPierre Pronchery {
57*b077aed3SPierre Pronchery     sk_OSSL_PROVIDER_pop_free(app_providers, provider_free);
58*b077aed3SPierre Pronchery     app_providers = NULL;
59*b077aed3SPierre Pronchery }
60*b077aed3SPierre Pronchery 
opt_provider_path(const char * path)61*b077aed3SPierre Pronchery static int opt_provider_path(const char *path)
62*b077aed3SPierre Pronchery {
63*b077aed3SPierre Pronchery     if (path != NULL && *path == '\0')
64*b077aed3SPierre Pronchery         path = NULL;
65*b077aed3SPierre Pronchery     return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path);
66*b077aed3SPierre Pronchery }
67*b077aed3SPierre Pronchery 
opt_provider(int opt)68*b077aed3SPierre Pronchery int opt_provider(int opt)
69*b077aed3SPierre Pronchery {
70*b077aed3SPierre Pronchery     const int given = provider_option_given;
71*b077aed3SPierre Pronchery 
72*b077aed3SPierre Pronchery     provider_option_given = 1;
73*b077aed3SPierre Pronchery     switch ((enum prov_range)opt) {
74*b077aed3SPierre Pronchery     case OPT_PROV__FIRST:
75*b077aed3SPierre Pronchery     case OPT_PROV__LAST:
76*b077aed3SPierre Pronchery         return 1;
77*b077aed3SPierre Pronchery     case OPT_PROV_PROVIDER:
78*b077aed3SPierre Pronchery         return app_provider_load(app_get0_libctx(), opt_arg());
79*b077aed3SPierre Pronchery     case OPT_PROV_PROVIDER_PATH:
80*b077aed3SPierre Pronchery         return opt_provider_path(opt_arg());
81*b077aed3SPierre Pronchery     case OPT_PROV_PROPQUERY:
82*b077aed3SPierre Pronchery         return app_set_propq(opt_arg());
83*b077aed3SPierre Pronchery     }
84*b077aed3SPierre Pronchery     /* Should never get here but if we do, undo what we did earlier */
85*b077aed3SPierre Pronchery     provider_option_given = given;
86*b077aed3SPierre Pronchery     return 0;
87*b077aed3SPierre Pronchery }
88*b077aed3SPierre Pronchery 
opt_provider_option_given(void)89*b077aed3SPierre Pronchery int opt_provider_option_given(void)
90*b077aed3SPierre Pronchery {
91*b077aed3SPierre Pronchery     return provider_option_given;
92*b077aed3SPierre Pronchery }
93