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