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