1 | /*
|
---|
2 | * Copyright 2020-2021 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 "apps.h"
|
---|
11 | #include <string.h>
|
---|
12 | #include <openssl/err.h>
|
---|
13 | #include <openssl/provider.h>
|
---|
14 | #include <openssl/safestack.h>
|
---|
15 |
|
---|
16 | /* Non-zero if any of the provider options have been seen */
|
---|
17 | static int provider_option_given = 0;
|
---|
18 |
|
---|
19 | DEFINE_STACK_OF(OSSL_PROVIDER)
|
---|
20 |
|
---|
21 | /*
|
---|
22 | * See comments in opt_verify for explanation of this.
|
---|
23 | */
|
---|
24 | enum prov_range { OPT_PROV_ENUM };
|
---|
25 |
|
---|
26 | static STACK_OF(OSSL_PROVIDER) *app_providers = NULL;
|
---|
27 |
|
---|
28 | static void provider_free(OSSL_PROVIDER *prov)
|
---|
29 | {
|
---|
30 | OSSL_PROVIDER_unload(prov);
|
---|
31 | }
|
---|
32 |
|
---|
33 | int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name)
|
---|
34 | {
|
---|
35 | OSSL_PROVIDER *prov;
|
---|
36 |
|
---|
37 | prov = OSSL_PROVIDER_load(libctx, provider_name);
|
---|
38 | if (prov == NULL) {
|
---|
39 | opt_printf_stderr("%s: unable to load provider %s\n"
|
---|
40 | "Hint: use -provider-path option or OPENSSL_MODULES environment variable.\n",
|
---|
41 | opt_getprog(), provider_name);
|
---|
42 | ERR_print_errors(bio_err);
|
---|
43 | return 0;
|
---|
44 | }
|
---|
45 | if (app_providers == NULL)
|
---|
46 | app_providers = sk_OSSL_PROVIDER_new_null();
|
---|
47 | if (app_providers == NULL
|
---|
48 | || !sk_OSSL_PROVIDER_push(app_providers, prov)) {
|
---|
49 | app_providers_cleanup();
|
---|
50 | return 0;
|
---|
51 | }
|
---|
52 | return 1;
|
---|
53 | }
|
---|
54 |
|
---|
55 | void app_providers_cleanup(void)
|
---|
56 | {
|
---|
57 | sk_OSSL_PROVIDER_pop_free(app_providers, provider_free);
|
---|
58 | app_providers = NULL;
|
---|
59 | }
|
---|
60 |
|
---|
61 | static int opt_provider_path(const char *path)
|
---|
62 | {
|
---|
63 | if (path != NULL && *path == '\0')
|
---|
64 | path = NULL;
|
---|
65 | return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path);
|
---|
66 | }
|
---|
67 |
|
---|
68 | int opt_provider(int opt)
|
---|
69 | {
|
---|
70 | const int given = provider_option_given;
|
---|
71 |
|
---|
72 | provider_option_given = 1;
|
---|
73 | switch ((enum prov_range)opt) {
|
---|
74 | case OPT_PROV__FIRST:
|
---|
75 | case OPT_PROV__LAST:
|
---|
76 | return 1;
|
---|
77 | case OPT_PROV_PROVIDER:
|
---|
78 | return app_provider_load(app_get0_libctx(), opt_arg());
|
---|
79 | case OPT_PROV_PROVIDER_PATH:
|
---|
80 | return opt_provider_path(opt_arg());
|
---|
81 | case OPT_PROV_PROPQUERY:
|
---|
82 | return app_set_propq(opt_arg());
|
---|
83 | }
|
---|
84 | /* Should never get here but if we do, undo what we did earlier */
|
---|
85 | provider_option_given = given;
|
---|
86 | return 0;
|
---|
87 | }
|
---|
88 |
|
---|
89 | int opt_provider_option_given(void)
|
---|
90 | {
|
---|
91 | return provider_option_given;
|
---|
92 | }
|
---|