Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/lib/app_provider.c
34878 views
1
/*
2
* Copyright 2020-2025 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 <ctype.h>
12
#include <string.h>
13
#include <openssl/err.h>
14
#include <openssl/provider.h>
15
#include <openssl/safestack.h>
16
17
/* Non-zero if any of the provider options have been seen */
18
static int provider_option_given = 0;
19
20
DEFINE_STACK_OF(OSSL_PROVIDER)
21
22
/*
23
* See comments in opt_verify for explanation of this.
24
*/
25
enum prov_range { OPT_PROV_ENUM };
26
27
static STACK_OF(OSSL_PROVIDER) *app_providers = NULL;
28
29
static void provider_free(OSSL_PROVIDER *prov)
30
{
31
OSSL_PROVIDER_unload(prov);
32
}
33
34
int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name)
35
{
36
OSSL_PROVIDER *prov;
37
38
prov = OSSL_PROVIDER_load(libctx, provider_name);
39
if (prov == NULL) {
40
opt_printf_stderr("%s: unable to load provider %s\n"
41
"Hint: use -provider-path option or OPENSSL_MODULES environment variable.\n",
42
opt_getprog(), provider_name);
43
ERR_print_errors(bio_err);
44
return 0;
45
}
46
if (app_providers == NULL)
47
app_providers = sk_OSSL_PROVIDER_new_null();
48
if (app_providers == NULL
49
|| !sk_OSSL_PROVIDER_push(app_providers, prov)) {
50
app_providers_cleanup();
51
return 0;
52
}
53
return 1;
54
}
55
56
void app_providers_cleanup(void)
57
{
58
sk_OSSL_PROVIDER_pop_free(app_providers, provider_free);
59
app_providers = NULL;
60
}
61
62
static int opt_provider_path(const char *path)
63
{
64
if (path != NULL && *path == '\0')
65
path = NULL;
66
return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path);
67
}
68
69
struct prov_param_st {
70
char *name;
71
char *key;
72
char *val;
73
int found;
74
};
75
76
static int set_prov_param(OSSL_PROVIDER *prov, void *vp)
77
{
78
struct prov_param_st *p = (struct prov_param_st *)vp;
79
80
if (p->name != NULL && strcmp(OSSL_PROVIDER_get0_name(prov), p->name) != 0)
81
return 1;
82
p->found = 1;
83
return OSSL_PROVIDER_add_conf_parameter(prov, p->key, p->val);
84
}
85
86
static int opt_provider_param(const char *arg)
87
{
88
struct prov_param_st p;
89
char *copy, *tmp;
90
int ret = 0;
91
92
if ((copy = OPENSSL_strdup(arg)) == NULL
93
|| (p.val = strchr(copy, '=')) == NULL) {
94
opt_printf_stderr("%s: malformed '-provparam' option value: '%s'\n",
95
opt_getprog(), arg);
96
goto end;
97
}
98
99
/* Drop whitespace on both sides of the '=' sign */
100
*(tmp = p.val++) = '\0';
101
while (tmp > copy && isspace(_UC(*--tmp)))
102
*tmp = '\0';
103
while (isspace(_UC(*p.val)))
104
++p.val;
105
106
/*
107
* Split the key on ':', to get the optional provider, empty or missing
108
* means all.
109
*/
110
if ((p.key = strchr(copy, ':')) != NULL) {
111
*p.key++ = '\0';
112
p.name = *copy != '\0' ? copy : NULL;
113
} else {
114
p.name = NULL;
115
p.key = copy;
116
}
117
118
/* The key must not be empty */
119
if (*p.key == '\0') {
120
opt_printf_stderr("%s: malformed '-provparam' option value: '%s'\n",
121
opt_getprog(), arg);
122
goto end;
123
}
124
125
p.found = 0;
126
ret = OSSL_PROVIDER_do_all(app_get0_libctx(), set_prov_param, (void *)&p);
127
if (ret == 0) {
128
opt_printf_stderr("%s: Error setting provider '%s' parameter '%s'\n",
129
opt_getprog(), p.name, p.key);
130
} else if (p.found == 0) {
131
opt_printf_stderr("%s: No provider named '%s' is loaded\n",
132
opt_getprog(), p.name);
133
ret = 0;
134
}
135
136
end:
137
OPENSSL_free(copy);
138
return ret;
139
}
140
141
int opt_provider(int opt)
142
{
143
const int given = provider_option_given;
144
145
provider_option_given = 1;
146
switch ((enum prov_range)opt) {
147
case OPT_PROV__FIRST:
148
case OPT_PROV__LAST:
149
return 1;
150
case OPT_PROV_PROVIDER:
151
return app_provider_load(app_get0_libctx(), opt_arg());
152
case OPT_PROV_PROVIDER_PATH:
153
return opt_provider_path(opt_arg());
154
case OPT_PROV_PARAM:
155
return opt_provider_param(opt_arg());
156
case OPT_PROV_PROPQUERY:
157
return app_set_propq(opt_arg());
158
}
159
/* Should never get here but if we do, undo what we did earlier */
160
provider_option_given = given;
161
return 0;
162
}
163
164
int opt_provider_option_given(void)
165
{
166
return provider_option_given;
167
}
168
169