diff options
author | tb <> | 2023-07-28 09:53:55 +0000 |
---|---|---|
committer | tb <> | 2023-07-28 09:53:55 +0000 |
commit | d4949db8e78438e8bb53c9c1297b068ac0df7827 (patch) | |
tree | 307457e0cf8fc786fb4c80edc29a92d5677d406e /src/lib/libcrypto/engine/eng_ctrl.c | |
parent | 681b4eb7a5896143c26eac201c041f6f22357b18 (diff) | |
download | openbsd-d4949db8e78438e8bb53c9c1297b068ac0df7827.tar.gz openbsd-d4949db8e78438e8bb53c9c1297b068ac0df7827.tar.bz2 openbsd-d4949db8e78438e8bb53c9c1297b068ac0df7827.zip |
Set OPENSSL_NO_ENGINE, remove engine code
ENGINE was special. It's horrible code even by the low standards of this
library. Some ports may now try to use the stubs which will fail, but
the fallout from this should be minimal. Of course there are various
language bindings that expose the ENGINE API. OpenSSL 3 disabling ENGINE
by default will likely help fixing this at some point.
ok jsing
Diffstat (limited to 'src/lib/libcrypto/engine/eng_ctrl.c')
-rw-r--r-- | src/lib/libcrypto/engine/eng_ctrl.c | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c deleted file mode 100644 index 1a3c25fbae..0000000000 --- a/src/lib/libcrypto/engine/eng_ctrl.c +++ /dev/null | |||
@@ -1,379 +0,0 @@ | |||
1 | /* $OpenBSD: eng_ctrl.c,v 1.11 2017/01/29 17:49:23 beck Exp $ */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * licensing@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include <string.h> | ||
57 | |||
58 | #include <openssl/err.h> | ||
59 | |||
60 | #include "eng_int.h" | ||
61 | |||
62 | /* When querying a ENGINE-specific control command's 'description', this string | ||
63 | * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */ | ||
64 | static const char *int_no_description = ""; | ||
65 | |||
66 | /* These internal functions handle 'CMD'-related control commands when the | ||
67 | * ENGINE in question has asked us to take care of it (ie. the ENGINE did not | ||
68 | * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */ | ||
69 | |||
70 | static int | ||
71 | int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) | ||
72 | { | ||
73 | if ((defn->cmd_num == 0) || (defn->cmd_name == NULL)) | ||
74 | return 1; | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) | ||
80 | { | ||
81 | int idx = 0; | ||
82 | while (!int_ctrl_cmd_is_null(defn) && | ||
83 | (strcmp(defn->cmd_name, s) != 0)) { | ||
84 | idx++; | ||
85 | defn++; | ||
86 | } | ||
87 | if (int_ctrl_cmd_is_null(defn)) | ||
88 | /* The given name wasn't found */ | ||
89 | return -1; | ||
90 | return idx; | ||
91 | } | ||
92 | |||
93 | static int | ||
94 | int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) | ||
95 | { | ||
96 | int idx = 0; | ||
97 | /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So | ||
98 | * our searches don't need to take any longer than necessary. */ | ||
99 | while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) { | ||
100 | idx++; | ||
101 | defn++; | ||
102 | } | ||
103 | if (defn->cmd_num == num) | ||
104 | return idx; | ||
105 | /* The given cmd_num wasn't found */ | ||
106 | return -1; | ||
107 | } | ||
108 | |||
109 | static int | ||
110 | int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) | ||
111 | { | ||
112 | int idx; | ||
113 | int ret; | ||
114 | char *s = (char *)p; | ||
115 | |||
116 | /* Take care of the easy one first (eg. it requires no searches) */ | ||
117 | if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) { | ||
118 | if ((e->cmd_defns == NULL) || | ||
119 | int_ctrl_cmd_is_null(e->cmd_defns)) | ||
120 | return 0; | ||
121 | return e->cmd_defns->cmd_num; | ||
122 | } | ||
123 | /* One or two commands require that "p" be a valid string buffer */ | ||
124 | if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || | ||
125 | (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || | ||
126 | (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) { | ||
127 | if (s == NULL) { | ||
128 | ENGINEerror(ERR_R_PASSED_NULL_PARAMETER); | ||
129 | return -1; | ||
130 | } | ||
131 | } | ||
132 | /* Now handle cmd_name -> cmd_num conversion */ | ||
133 | if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) { | ||
134 | if ((e->cmd_defns == NULL) || | ||
135 | ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) { | ||
136 | ENGINEerror(ENGINE_R_INVALID_CMD_NAME); | ||
137 | return -1; | ||
138 | } | ||
139 | return e->cmd_defns[idx].cmd_num; | ||
140 | } | ||
141 | /* For the rest of the commands, the 'long' argument must specify a | ||
142 | * valie command number - so we need to conduct a search. */ | ||
143 | if ((e->cmd_defns == NULL) || | ||
144 | ((idx = int_ctrl_cmd_by_num(e->cmd_defns, (unsigned int)i)) < 0)) { | ||
145 | ENGINEerror(ENGINE_R_INVALID_CMD_NUMBER); | ||
146 | return -1; | ||
147 | } | ||
148 | /* Now the logic splits depending on command type */ | ||
149 | switch (cmd) { | ||
150 | case ENGINE_CTRL_GET_NEXT_CMD_TYPE: | ||
151 | idx++; | ||
152 | if (int_ctrl_cmd_is_null(e->cmd_defns + idx)) | ||
153 | /* end-of-list */ | ||
154 | return 0; | ||
155 | else | ||
156 | return e->cmd_defns[idx].cmd_num; | ||
157 | case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: | ||
158 | return strlen(e->cmd_defns[idx].cmd_name); | ||
159 | case ENGINE_CTRL_GET_NAME_FROM_CMD: | ||
160 | ret = snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1, | ||
161 | "%s", e->cmd_defns[idx].cmd_name); | ||
162 | if (ret >= (strlen(e->cmd_defns[idx].cmd_name) + 1)) | ||
163 | ret = -1; | ||
164 | return ret; | ||
165 | case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: | ||
166 | if (e->cmd_defns[idx].cmd_desc) | ||
167 | return strlen(e->cmd_defns[idx].cmd_desc); | ||
168 | return strlen(int_no_description); | ||
169 | case ENGINE_CTRL_GET_DESC_FROM_CMD: | ||
170 | if (e->cmd_defns[idx].cmd_desc) { | ||
171 | ret = snprintf(s, | ||
172 | strlen(e->cmd_defns[idx].cmd_desc) + 1, | ||
173 | "%s", e->cmd_defns[idx].cmd_desc); | ||
174 | if (ret >= strlen(e->cmd_defns[idx].cmd_desc) + 1) | ||
175 | ret = -1; | ||
176 | return ret; | ||
177 | } | ||
178 | ret = snprintf(s, strlen(int_no_description) + 1, "%s", | ||
179 | int_no_description); | ||
180 | if (ret >= strlen(int_no_description) + 1) | ||
181 | ret = -1; | ||
182 | return ret; | ||
183 | case ENGINE_CTRL_GET_CMD_FLAGS: | ||
184 | return e->cmd_defns[idx].cmd_flags; | ||
185 | } | ||
186 | |||
187 | /* Shouldn't really be here ... */ | ||
188 | ENGINEerror(ENGINE_R_INTERNAL_LIST_ERROR); | ||
189 | return -1; | ||
190 | } | ||
191 | |||
192 | int | ||
193 | ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) | ||
194 | { | ||
195 | int ctrl_exists, ref_exists; | ||
196 | |||
197 | if (e == NULL) { | ||
198 | ENGINEerror(ERR_R_PASSED_NULL_PARAMETER); | ||
199 | return 0; | ||
200 | } | ||
201 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
202 | ref_exists = ((e->struct_ref > 0) ? 1 : 0); | ||
203 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
204 | ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); | ||
205 | if (!ref_exists) { | ||
206 | ENGINEerror(ENGINE_R_NO_REFERENCE); | ||
207 | return 0; | ||
208 | } | ||
209 | /* Intercept any "root-level" commands before trying to hand them on to | ||
210 | * ctrl() handlers. */ | ||
211 | switch (cmd) { | ||
212 | case ENGINE_CTRL_HAS_CTRL_FUNCTION: | ||
213 | return ctrl_exists; | ||
214 | case ENGINE_CTRL_GET_FIRST_CMD_TYPE: | ||
215 | case ENGINE_CTRL_GET_NEXT_CMD_TYPE: | ||
216 | case ENGINE_CTRL_GET_CMD_FROM_NAME: | ||
217 | case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: | ||
218 | case ENGINE_CTRL_GET_NAME_FROM_CMD: | ||
219 | case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: | ||
220 | case ENGINE_CTRL_GET_DESC_FROM_CMD: | ||
221 | case ENGINE_CTRL_GET_CMD_FLAGS: | ||
222 | if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) | ||
223 | return int_ctrl_helper(e, cmd, i, p, f); | ||
224 | if (!ctrl_exists) { | ||
225 | ENGINEerror(ENGINE_R_NO_CONTROL_FUNCTION); | ||
226 | /* For these cmd-related functions, failure is indicated | ||
227 | * by a -1 return value (because 0 is used as a valid | ||
228 | * return in some places). */ | ||
229 | return -1; | ||
230 | } | ||
231 | default: | ||
232 | break; | ||
233 | } | ||
234 | /* Anything else requires a ctrl() handler to exist. */ | ||
235 | if (!ctrl_exists) { | ||
236 | ENGINEerror(ENGINE_R_NO_CONTROL_FUNCTION); | ||
237 | return 0; | ||
238 | } | ||
239 | return e->ctrl(e, cmd, i, p, f); | ||
240 | } | ||
241 | |||
242 | int | ||
243 | ENGINE_cmd_is_executable(ENGINE *e, int cmd) | ||
244 | { | ||
245 | int flags; | ||
246 | |||
247 | if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, | ||
248 | NULL, NULL)) < 0) { | ||
249 | ENGINEerror(ENGINE_R_INVALID_CMD_NUMBER); | ||
250 | return 0; | ||
251 | } | ||
252 | if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) && | ||
253 | !(flags & ENGINE_CMD_FLAG_NUMERIC) && | ||
254 | !(flags & ENGINE_CMD_FLAG_STRING)) | ||
255 | return 0; | ||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | int | ||
260 | ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, long i, void *p, | ||
261 | void (*f)(void), int cmd_optional) | ||
262 | { | ||
263 | int num; | ||
264 | |||
265 | if ((e == NULL) || (cmd_name == NULL)) { | ||
266 | ENGINEerror(ERR_R_PASSED_NULL_PARAMETER); | ||
267 | return 0; | ||
268 | } | ||
269 | if ((e->ctrl == NULL) || | ||
270 | ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME, | ||
271 | 0, (void *)cmd_name, NULL)) <= 0)) { | ||
272 | /* If the command didn't *have* to be supported, we fake | ||
273 | * success. This allows certain settings to be specified for | ||
274 | * multiple ENGINEs and only require a change of ENGINE id | ||
275 | * (without having to selectively apply settings). Eg. changing | ||
276 | * from a hardware device back to the regular software ENGINE | ||
277 | * without editing the config file, etc. */ | ||
278 | if (cmd_optional) { | ||
279 | ERR_clear_error(); | ||
280 | return 1; | ||
281 | } | ||
282 | ENGINEerror(ENGINE_R_INVALID_CMD_NAME); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | /* Force the result of the control command to 0 or 1, for the reasons | ||
287 | * mentioned before. */ | ||
288 | if (ENGINE_ctrl(e, num, i, p, f) > 0) | ||
289 | return 1; | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | int | ||
295 | ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, | ||
296 | int cmd_optional) | ||
297 | { | ||
298 | int num, flags; | ||
299 | long l; | ||
300 | char *ptr; | ||
301 | |||
302 | if ((e == NULL) || (cmd_name == NULL)) { | ||
303 | ENGINEerror(ERR_R_PASSED_NULL_PARAMETER); | ||
304 | return 0; | ||
305 | } | ||
306 | if ((e->ctrl == NULL) || | ||
307 | ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME, 0, | ||
308 | (void *)cmd_name, NULL)) <= 0)) { | ||
309 | /* If the command didn't *have* to be supported, we fake | ||
310 | * success. This allows certain settings to be specified for | ||
311 | * multiple ENGINEs and only require a change of ENGINE id | ||
312 | * (without having to selectively apply settings). Eg. changing | ||
313 | * from a hardware device back to the regular software ENGINE | ||
314 | * without editing the config file, etc. */ | ||
315 | if (cmd_optional) { | ||
316 | ERR_clear_error(); | ||
317 | return 1; | ||
318 | } | ||
319 | ENGINEerror(ENGINE_R_INVALID_CMD_NAME); | ||
320 | return 0; | ||
321 | } | ||
322 | if (!ENGINE_cmd_is_executable(e, num)) { | ||
323 | ENGINEerror(ENGINE_R_CMD_NOT_EXECUTABLE); | ||
324 | return 0; | ||
325 | } | ||
326 | if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, | ||
327 | NULL, NULL)) < 0) { | ||
328 | /* Shouldn't happen, given that ENGINE_cmd_is_executable() | ||
329 | * returned success. */ | ||
330 | ENGINEerror(ENGINE_R_INTERNAL_LIST_ERROR); | ||
331 | return 0; | ||
332 | } | ||
333 | /* If the command takes no input, there must be no input. And vice | ||
334 | * versa. */ | ||
335 | if (flags & ENGINE_CMD_FLAG_NO_INPUT) { | ||
336 | if (arg != NULL) { | ||
337 | ENGINEerror(ENGINE_R_COMMAND_TAKES_NO_INPUT); | ||
338 | return 0; | ||
339 | } | ||
340 | /* We deliberately force the result of ENGINE_ctrl() to 0 or 1 | ||
341 | * rather than returning it as "return data". This is to ensure | ||
342 | * usage of these commands is consistent across applications and | ||
343 | * that certain applications don't understand it one way, and | ||
344 | * others another. */ | ||
345 | if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) | ||
346 | return 1; | ||
347 | return 0; | ||
348 | } | ||
349 | /* So, we require input */ | ||
350 | if (arg == NULL) { | ||
351 | ENGINEerror(ENGINE_R_COMMAND_TAKES_INPUT); | ||
352 | return 0; | ||
353 | } | ||
354 | /* If it takes string input, that's easy */ | ||
355 | if (flags & ENGINE_CMD_FLAG_STRING) { | ||
356 | /* Same explanation as above */ | ||
357 | if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) | ||
358 | return 1; | ||
359 | return 0; | ||
360 | } | ||
361 | /* If it doesn't take numeric either, then it is unsupported for use in | ||
362 | * a config-setting situation, which is what this function is for. This | ||
363 | * should never happen though, because ENGINE_cmd_is_executable() was | ||
364 | * used. */ | ||
365 | if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) { | ||
366 | ENGINEerror(ENGINE_R_INTERNAL_LIST_ERROR); | ||
367 | return 0; | ||
368 | } | ||
369 | l = strtol(arg, &ptr, 10); | ||
370 | if ((arg == ptr) || (*ptr != '\0')) { | ||
371 | ENGINEerror(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); | ||
372 | return 0; | ||
373 | } | ||
374 | /* Force the result of the control command to 0 or 1, for the reasons | ||
375 | * mentioned before. */ | ||
376 | if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0) | ||
377 | return 1; | ||
378 | return 0; | ||
379 | } | ||