summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_ctrl.c
diff options
context:
space:
mode:
authortb <>2023-07-28 09:53:55 +0000
committertb <>2023-07-28 09:53:55 +0000
commitd4949db8e78438e8bb53c9c1297b068ac0df7827 (patch)
tree307457e0cf8fc786fb4c80edc29a92d5677d406e /src/lib/libcrypto/engine/eng_ctrl.c
parent681b4eb7a5896143c26eac201c041f6f22357b18 (diff)
downloadopenbsd-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.c379
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. */
64static 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
70static int
71int_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
78static int
79int_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
93static int
94int_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
109static int
110int_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
192int
193ENGINE_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
242int
243ENGINE_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
259int
260ENGINE_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
294int
295ENGINE_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}