]>
Commit | Line | Data |
---|---|---|
021a6552 | 1 | /* |
33388b44 | 2 | * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. |
021a6552 RL |
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 | /* | |
11 | * This is a very simple provider that does absolutely nothing except respond | |
12 | * to provider global parameter requests. It does this by simply echoing back | |
13 | * a parameter request it makes to the loading library. | |
14 | */ | |
15 | ||
16 | #include <string.h> | |
17 | #include <stdio.h> | |
18 | ||
19 | /* | |
20 | * When built as an object file to link the application with, we get the | |
21 | * init function name through the macro PROVIDER_INIT_FUNCTION_NAME. If | |
22 | * not defined, we use the standard init function name for the shared | |
23 | * object form. | |
24 | */ | |
25 | #ifdef PROVIDER_INIT_FUNCTION_NAME | |
26 | # define OSSL_provider_init PROVIDER_INIT_FUNCTION_NAME | |
27 | #endif | |
28 | ||
81c15ed0 | 29 | #include "e_os.h" |
021a6552 | 30 | #include <openssl/core.h> |
23c48d94 | 31 | #include <openssl/core_dispatch.h> |
81c15ed0 MC |
32 | #include <openssl/err.h> |
33 | ||
34 | typedef struct p_test_ctx { | |
35 | char *thisfile; | |
36 | char *thisfunc; | |
37 | const OSSL_CORE_HANDLE *handle; | |
38 | } P_TEST_CTX; | |
021a6552 | 39 | |
363b1e5d DMSP |
40 | static OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL; |
41 | static OSSL_FUNC_core_get_params_fn *c_get_params = NULL; | |
81c15ed0 MC |
42 | static OSSL_FUNC_core_new_error_fn *c_new_error; |
43 | static OSSL_FUNC_core_set_error_debug_fn *c_set_error_debug; | |
44 | static OSSL_FUNC_core_vset_error_fn *c_vset_error; | |
021a6552 RL |
45 | |
46 | /* Tell the core what params we provide and what type they are */ | |
26175013 RL |
47 | static const OSSL_PARAM p_param_types[] = { |
48 | { "greeting", OSSL_PARAM_UTF8_STRING, NULL, 0, 0 }, | |
49 | { NULL, 0, NULL, 0, 0 } | |
021a6552 RL |
50 | }; |
51 | ||
a39eb840 | 52 | /* This is a trick to ensure we define the provider functions correctly */ |
363b1e5d DMSP |
53 | static OSSL_FUNC_provider_gettable_params_fn p_gettable_params; |
54 | static OSSL_FUNC_provider_get_params_fn p_get_params; | |
55 | static OSSL_FUNC_provider_get_reason_strings_fn p_get_reason_strings; | |
81c15ed0 | 56 | static OSSL_FUNC_provider_teardown_fn p_teardown; |
a39eb840 | 57 | |
dca97d00 | 58 | static const OSSL_PARAM *p_gettable_params(void *_) |
021a6552 RL |
59 | { |
60 | return p_param_types; | |
61 | } | |
62 | ||
81c15ed0 | 63 | static int p_get_params(void *provctx, OSSL_PARAM params[]) |
021a6552 | 64 | { |
81c15ed0 MC |
65 | P_TEST_CTX *ctx = (P_TEST_CTX *)provctx; |
66 | const OSSL_CORE_HANDLE *hand = ctx->handle; | |
4e7991b4 | 67 | OSSL_PARAM *p = params; |
021a6552 RL |
68 | int ok = 1; |
69 | ||
70 | for (; ok && p->key != NULL; p++) { | |
71 | if (strcmp(p->key, "greeting") == 0) { | |
1ccf4973 RL |
72 | static char *opensslv; |
73 | static char *provname; | |
74 | static char *greeting; | |
4e7991b4 | 75 | static OSSL_PARAM counter_request[] = { |
6d872a83 | 76 | /* Known libcrypto provided parameters */ |
e2146e12 | 77 | { "openssl-version", OSSL_PARAM_UTF8_PTR, |
4e7991b4 | 78 | &opensslv, sizeof(&opensslv), 0 }, |
e2146e12 | 79 | { "provider-name", OSSL_PARAM_UTF8_PTR, |
4e7991b4 | 80 | &provname, sizeof(&provname), 0}, |
6d872a83 RL |
81 | |
82 | /* This might be present, if there's such a configuration */ | |
83 | { "greeting", OSSL_PARAM_UTF8_PTR, | |
4e7991b4 | 84 | &greeting, sizeof(&greeting), 0 }, |
6d872a83 | 85 | |
4e7991b4 | 86 | { NULL, 0, NULL, 0, 0 } |
021a6552 RL |
87 | }; |
88 | char buf[256]; | |
89 | size_t buf_l; | |
90 | ||
1ccf4973 RL |
91 | opensslv = provname = greeting = NULL; |
92 | ||
d40b42ab | 93 | if (c_get_params(hand, counter_request)) { |
6d872a83 RL |
94 | if (greeting) { |
95 | strcpy(buf, greeting); | |
96 | } else { | |
97 | const char *versionp = *(void **)counter_request[0].data; | |
98 | const char *namep = *(void **)counter_request[1].data; | |
99 | ||
100 | sprintf(buf, "Hello OpenSSL %.20s, greetings from %s!", | |
101 | versionp, namep); | |
102 | } | |
021a6552 RL |
103 | } else { |
104 | sprintf(buf, "Howdy stranger..."); | |
105 | } | |
106 | ||
4e7991b4 | 107 | p->return_size = buf_l = strlen(buf) + 1; |
8c4412ed | 108 | if (p->data_size >= buf_l) |
f663ddc7 | 109 | strcpy(p->data, buf); |
021a6552 RL |
110 | else |
111 | ok = 0; | |
112 | } | |
113 | } | |
114 | return ok; | |
115 | } | |
116 | ||
81c15ed0 MC |
117 | static void p_set_error(int lib, int reason, const char *file, int line, |
118 | const char *func) | |
119 | { | |
120 | c_new_error(NULL); | |
121 | c_set_error_debug(NULL, file, line, func); | |
122 | c_vset_error(NULL, ERR_PACK(lib, 0, reason), NULL, NULL); | |
123 | } | |
124 | ||
551543e5 NT |
125 | static const OSSL_ITEM *p_get_reason_strings(void *_) |
126 | { | |
127 | static const OSSL_ITEM reason_strings[] = { | |
128 | {1, "dummy reason string"}, | |
129 | {0, NULL} | |
130 | }; | |
131 | ||
132 | return reason_strings; | |
133 | } | |
134 | ||
021a6552 | 135 | static const OSSL_DISPATCH p_test_table[] = { |
dca97d00 | 136 | { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))p_gettable_params }, |
021a6552 | 137 | { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))p_get_params }, |
551543e5 NT |
138 | { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, |
139 | (void (*)(void))p_get_reason_strings}, | |
81c15ed0 | 140 | { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown }, |
021a6552 RL |
141 | { 0, NULL } |
142 | }; | |
143 | ||
d40b42ab | 144 | int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, |
021a6552 | 145 | const OSSL_DISPATCH *in, |
a39eb840 RL |
146 | const OSSL_DISPATCH **out, |
147 | void **provctx) | |
021a6552 | 148 | { |
81c15ed0 MC |
149 | P_TEST_CTX *ctx; |
150 | ||
021a6552 RL |
151 | for (; in->function_id != 0; in++) { |
152 | switch (in->function_id) { | |
dca97d00 | 153 | case OSSL_FUNC_CORE_GETTABLE_PARAMS: |
363b1e5d | 154 | c_gettable_params = OSSL_FUNC_core_gettable_params(in); |
021a6552 RL |
155 | break; |
156 | case OSSL_FUNC_CORE_GET_PARAMS: | |
363b1e5d | 157 | c_get_params = OSSL_FUNC_core_get_params(in); |
021a6552 | 158 | break; |
81c15ed0 MC |
159 | case OSSL_FUNC_CORE_NEW_ERROR: |
160 | c_new_error = OSSL_FUNC_core_new_error(in); | |
161 | break; | |
162 | case OSSL_FUNC_CORE_SET_ERROR_DEBUG: | |
163 | c_set_error_debug = OSSL_FUNC_core_set_error_debug(in); | |
164 | break; | |
165 | case OSSL_FUNC_CORE_VSET_ERROR: | |
166 | c_vset_error = OSSL_FUNC_core_vset_error(in); | |
167 | break; | |
021a6552 RL |
168 | default: |
169 | /* Just ignore anything we don't understand */ | |
170 | break; | |
171 | } | |
172 | } | |
173 | ||
81c15ed0 MC |
174 | /* |
175 | * We want to test that libcrypto doesn't use the file and func pointers | |
176 | * that we provide to it via c_set_error_debug beyond the time that they | |
177 | * are valid for. Therefore we dynamically allocate these strings now and | |
178 | * free them again when the provider is torn down. If anything tries to | |
179 | * use those strings after that point there will be a use-after-free and | |
180 | * asan will complain (and hence the tests will fail). | |
181 | * This file isn't linked against libcrypto, so we use malloc and strdup | |
182 | * instead of OPENSSL_malloc and OPENSSL_strdup | |
183 | */ | |
184 | ctx = malloc(sizeof(*ctx)); | |
185 | if (ctx == NULL) | |
186 | return 0; | |
187 | ctx->thisfile = strdup(OPENSSL_FILE); | |
188 | ctx->thisfunc = strdup(OPENSSL_FUNC); | |
189 | ctx->handle = handle; | |
190 | ||
191 | /* | |
192 | * Set a spurious error to check error handling works correctly. This will | |
193 | * be ignored | |
194 | */ | |
195 | p_set_error(ERR_LIB_PROV, 1, ctx->thisfile, OPENSSL_LINE, ctx->thisfunc); | |
196 | ||
197 | *provctx = (void *)ctx; | |
021a6552 RL |
198 | *out = p_test_table; |
199 | return 1; | |
200 | } | |
81c15ed0 MC |
201 | |
202 | static void p_teardown(void *provctx) | |
203 | { | |
204 | P_TEST_CTX *ctx = (P_TEST_CTX *)provctx; | |
205 | ||
206 | free(ctx->thisfile); | |
207 | free(ctx->thisfunc); | |
208 | free(ctx); | |
209 | } |