]>
Commit | Line | Data |
---|---|---|
2b671586 | 1 | /* crypto/engine/eng_lib.c */ |
14cfde9c UM |
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL |
3 | * project 2000. | |
4 | */ | |
5 | /* ==================================================================== | |
2b671586 | 6 | * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. |
14cfde9c UM |
7 | * |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * licensing@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | * | |
53 | * This product includes cryptographic software written by Eric Young | |
54 | * (eay@cryptsoft.com). This product includes software written by Tim | |
55 | * Hudson (tjh@cryptsoft.com). | |
56 | * | |
57 | */ | |
58 | ||
59 | #include <openssl/crypto.h> | |
60 | #include "cryptlib.h" | |
61 | #include "eng_int.h" | |
62 | #include <openssl/engine.h> | |
63 | ||
64 | /* These pointers each have their own "functional reference" when they | |
65 | * are non-NULL. Similarly, when they are retrieved by a call to | |
66 | * ENGINE_get_default_[RSA|DSA|...] the returned pointer is also a | |
67 | * reference and the caller is responsible for freeing that when they | |
68 | * are finished with it (with a call to ENGINE_finish() *NOT* just | |
69 | * ENGINE_free()!!!!!!). */ | |
70 | #ifndef OPENSSL_NO_RSA | |
71 | static ENGINE *engine_def_rsa = NULL; | |
72 | #endif | |
73 | #ifndef OPENSSL_NO_DSA | |
74 | static ENGINE *engine_def_dsa = NULL; | |
75 | #endif | |
76 | #ifndef OPENSSL_NO_DH | |
77 | static ENGINE *engine_def_dh = NULL; | |
78 | #endif | |
79 | static ENGINE *engine_def_rand = NULL; | |
80 | static ENGINE *engine_def_bn_mod_exp = NULL; | |
81 | static ENGINE *engine_def_bn_mod_exp_crt = NULL; | |
82 | /* A static "once-only" flag used to control if/when the above were | |
83 | * initialised to suitable start-up defaults. */ | |
84 | static int engine_def_flag = 0; | |
85 | ||
86 | /* When querying a ENGINE-specific control command's 'description', this string | |
87 | * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */ | |
88 | static const char *int_no_description = ""; | |
89 | ||
90 | /* This is used in certain static utility functions to save code | |
91 | * repetition for per-algorithm functions. */ | |
92 | typedef enum { | |
93 | ENGINE_TYPE_RSA, | |
94 | ENGINE_TYPE_DSA, | |
95 | ENGINE_TYPE_DH, | |
96 | ENGINE_TYPE_RAND, | |
97 | ENGINE_TYPE_BN_MOD_EXP, | |
98 | ENGINE_TYPE_BN_MOD_EXP_CRT | |
99 | } ENGINE_TYPE; | |
100 | ||
101 | static void engine_def_check_util(ENGINE **def, ENGINE *val) | |
102 | { | |
103 | *def = val; | |
104 | val->struct_ref++; | |
105 | val->funct_ref++; | |
106 | engine_ref_debug(val, 0, 1) | |
107 | engine_ref_debug(val, 1, 1) | |
108 | } | |
109 | ||
110 | /* In a slight break with convention - this static function must be | |
111 | * called *outside* any locking of CRYPTO_LOCK_ENGINE. */ | |
112 | static void engine_def_check(void) | |
113 | { | |
114 | ENGINE *e; | |
115 | if(engine_def_flag) | |
116 | return; | |
117 | e = ENGINE_get_first(); | |
118 | if(e == NULL) | |
119 | /* The list is empty ... not much we can do! */ | |
120 | return; | |
121 | /* We have a structural reference, see if getting a functional | |
122 | * reference is possible. This is done to cope with init errors | |
123 | * in the engine - the following locked code does a bunch of | |
124 | * manual "ENGINE_init"s which do *not* allow such an init | |
125 | * error so this is worth doing. */ | |
126 | if(ENGINE_init(e)) | |
127 | { | |
128 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
129 | /* Doing another check here prevents an obvious race | |
130 | * condition because the whole function itself cannot | |
131 | * be locked. */ | |
132 | if(engine_def_flag) | |
133 | goto skip_set_defaults; | |
134 | /* OK, we got a functional reference, so we get one each | |
135 | * for the defaults too. */ | |
136 | #ifndef OPENSSL_NO_RSA | |
137 | engine_def_check_util(&engine_def_rsa, e); | |
138 | #endif | |
139 | #ifndef OPENSSL_NO_DSA | |
140 | engine_def_check_util(&engine_def_dsa, e); | |
141 | #endif | |
142 | #ifndef OPENSSL_NO_DH | |
143 | engine_def_check_util(&engine_def_dh, e); | |
144 | #endif | |
145 | engine_def_check_util(&engine_def_rand, e); | |
146 | engine_def_check_util(&engine_def_bn_mod_exp, e); | |
147 | engine_def_check_util(&engine_def_bn_mod_exp_crt, e); | |
148 | engine_def_flag = 1; | |
149 | skip_set_defaults: | |
150 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
151 | /* The "if" needs to be balanced out. */ | |
152 | ENGINE_finish(e); | |
153 | } | |
154 | /* We need to balance out the fact we obtained a structural | |
155 | * reference to begin with from ENGINE_get_first(). */ | |
156 | ENGINE_free(e); | |
157 | } | |
158 | ||
159 | /* Initialise a engine type for use (or up its functional reference count | |
160 | * if it's already in use). */ | |
161 | int ENGINE_init(ENGINE *e) | |
162 | { | |
163 | int to_return = 1; | |
164 | ||
165 | if(e == NULL) | |
166 | { | |
167 | ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER); | |
168 | return 0; | |
169 | } | |
170 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
171 | if((e->funct_ref == 0) && e->init) | |
172 | /* This is the first functional reference and the engine | |
173 | * requires initialisation so we do it now. */ | |
174 | to_return = e->init(e); | |
175 | if(to_return) | |
176 | { | |
177 | /* OK, we return a functional reference which is also a | |
178 | * structural reference. */ | |
179 | e->struct_ref++; | |
180 | e->funct_ref++; | |
181 | engine_ref_debug(e, 0, 1) | |
182 | engine_ref_debug(e, 1, 1) | |
183 | } | |
184 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
185 | return to_return; | |
186 | } | |
187 | ||
188 | /* Free a functional reference to a engine type */ | |
189 | int ENGINE_finish(ENGINE *e) | |
190 | { | |
191 | int to_return = 1; | |
192 | ||
193 | if(e == NULL) | |
194 | { | |
195 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER); | |
196 | return 0; | |
197 | } | |
198 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
199 | /* Reduce the functional reference count here so if it's the terminating | |
200 | * case, we can release the lock safely and call the finish() handler | |
201 | * without risk of a race. We get a race if we leave the count until | |
202 | * after and something else is calling "finish" at the same time - | |
203 | * there's a chance that both threads will together take the count from | |
204 | * 2 to 0 without either calling finish(). */ | |
205 | e->funct_ref--; | |
206 | engine_ref_debug(e, 1, -1) | |
207 | if((e->funct_ref == 0) && e->finish) | |
208 | { | |
209 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
210 | if(!(to_return = e->finish(e))) | |
211 | { | |
212 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); | |
213 | return 0; | |
214 | } | |
215 | } | |
216 | else | |
217 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
218 | #ifdef REF_CHECK | |
219 | if(e->funct_ref < 0) | |
220 | { | |
221 | fprintf(stderr,"ENGINE_finish, bad functional reference count\n"); | |
222 | abort(); | |
223 | } | |
224 | #endif | |
225 | /* Release the structural reference too */ | |
226 | if(!ENGINE_free(e)) | |
227 | { | |
228 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); | |
229 | return 0; | |
230 | } | |
231 | return to_return; | |
232 | } | |
233 | ||
234 | EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, | |
235 | UI_METHOD *ui_method, void *callback_data) | |
236 | { | |
237 | EVP_PKEY *pkey; | |
238 | ||
239 | if(e == NULL) | |
240 | { | |
241 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | |
242 | ERR_R_PASSED_NULL_PARAMETER); | |
243 | return 0; | |
244 | } | |
245 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
246 | if(e->funct_ref == 0) | |
247 | { | |
248 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
249 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | |
250 | ENGINE_R_NOT_INITIALISED); | |
251 | return 0; | |
252 | } | |
253 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
254 | if (!e->load_privkey) | |
255 | { | |
256 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | |
257 | ENGINE_R_NO_LOAD_FUNCTION); | |
258 | return 0; | |
259 | } | |
260 | pkey = e->load_privkey(e, key_id, ui_method, callback_data); | |
261 | if (!pkey) | |
262 | { | |
263 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | |
264 | ENGINE_R_FAILED_LOADING_PRIVATE_KEY); | |
265 | return 0; | |
266 | } | |
267 | return pkey; | |
268 | } | |
269 | ||
270 | EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, | |
271 | UI_METHOD *ui_method, void *callback_data) | |
272 | { | |
273 | EVP_PKEY *pkey; | |
274 | ||
275 | if(e == NULL) | |
276 | { | |
277 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | |
278 | ERR_R_PASSED_NULL_PARAMETER); | |
279 | return 0; | |
280 | } | |
281 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
282 | if(e->funct_ref == 0) | |
283 | { | |
284 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
285 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | |
286 | ENGINE_R_NOT_INITIALISED); | |
287 | return 0; | |
288 | } | |
289 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
290 | if (!e->load_pubkey) | |
291 | { | |
292 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | |
293 | ENGINE_R_NO_LOAD_FUNCTION); | |
294 | return 0; | |
295 | } | |
296 | pkey = e->load_pubkey(e, key_id, ui_method, callback_data); | |
297 | if (!pkey) | |
298 | { | |
299 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | |
300 | ENGINE_R_FAILED_LOADING_PUBLIC_KEY); | |
301 | return 0; | |
302 | } | |
303 | return pkey; | |
304 | } | |
305 | ||
306 | /* These internal functions handle 'CMD'-related control commands when the | |
307 | * ENGINE in question has asked us to take care of it (ie. the ENGINE did not | |
308 | * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */ | |
309 | ||
310 | static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) | |
311 | { | |
312 | if((defn->cmd_num == 0) || (defn->cmd_name == NULL)) | |
313 | return 1; | |
314 | return 0; | |
315 | } | |
316 | ||
317 | static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) | |
318 | { | |
319 | int idx = 0; | |
320 | while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) | |
321 | { | |
322 | idx++; | |
323 | defn++; | |
324 | } | |
325 | if(int_ctrl_cmd_is_null(defn)) | |
326 | /* The given name wasn't found */ | |
327 | return -1; | |
328 | return idx; | |
329 | } | |
330 | ||
331 | static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) | |
332 | { | |
333 | int idx = 0; | |
334 | /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So | |
335 | * our searches don't need to take any longer than necessary. */ | |
336 | while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) | |
337 | { | |
338 | idx++; | |
339 | defn++; | |
340 | } | |
341 | if(defn->cmd_num == num) | |
342 | return idx; | |
343 | /* The given cmd_num wasn't found */ | |
344 | return -1; | |
345 | } | |
346 | ||
347 | static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)()) | |
348 | { | |
349 | int idx; | |
350 | char *s = (char *)p; | |
351 | /* Take care of the easy one first (eg. it requires no searches) */ | |
352 | if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) | |
353 | { | |
354 | if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns)) | |
355 | return 0; | |
356 | return e->cmd_defns->cmd_num; | |
357 | } | |
358 | /* One or two commands require that "p" be a valid string buffer */ | |
359 | if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || | |
360 | (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || | |
361 | (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) | |
362 | { | |
363 | if(s == NULL) | |
364 | { | |
365 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER, | |
366 | ERR_R_PASSED_NULL_PARAMETER); | |
367 | return -1; | |
368 | } | |
369 | } | |
370 | /* Now handle cmd_name -> cmd_num conversion */ | |
371 | if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) | |
372 | { | |
373 | if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name( | |
374 | e->cmd_defns, s)) < 0)) | |
375 | { | |
376 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER, | |
377 | ENGINE_R_INVALID_CMD_NAME); | |
378 | return -1; | |
379 | } | |
380 | return e->cmd_defns[idx].cmd_num; | |
381 | } | |
382 | /* For the rest of the commands, the 'long' argument must specify a | |
383 | * valie command number - so we need to conduct a search. */ | |
384 | if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, | |
385 | (unsigned int)i)) < 0)) | |
386 | { | |
387 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER, | |
388 | ENGINE_R_INVALID_CMD_NUMBER); | |
389 | return -1; | |
390 | } | |
391 | /* Now the logic splits depending on command type */ | |
392 | switch(cmd) | |
393 | { | |
394 | case ENGINE_CTRL_GET_NEXT_CMD_TYPE: | |
395 | idx++; | |
396 | if(int_ctrl_cmd_is_null(e->cmd_defns + idx)) | |
397 | /* end-of-list */ | |
398 | return 0; | |
399 | else | |
400 | return e->cmd_defns[idx].cmd_num; | |
401 | case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: | |
402 | return strlen(e->cmd_defns[idx].cmd_name); | |
403 | case ENGINE_CTRL_GET_NAME_FROM_CMD: | |
404 | return sprintf(s, "%s", e->cmd_defns[idx].cmd_name); | |
405 | case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: | |
406 | if(e->cmd_defns[idx].cmd_desc) | |
407 | return strlen(e->cmd_defns[idx].cmd_desc); | |
408 | return strlen(int_no_description); | |
409 | case ENGINE_CTRL_GET_DESC_FROM_CMD: | |
410 | if(e->cmd_defns[idx].cmd_desc) | |
411 | return sprintf(s, "%s", e->cmd_defns[idx].cmd_desc); | |
412 | return sprintf(s, "%s", int_no_description); | |
413 | case ENGINE_CTRL_GET_CMD_FLAGS: | |
414 | return e->cmd_defns[idx].cmd_flags; | |
415 | } | |
416 | /* Shouldn't really be here ... */ | |
417 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR); | |
418 | return -1; | |
419 | } | |
420 | ||
421 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | |
422 | { | |
423 | int ctrl_exists, ref_exists; | |
424 | if(e == NULL) | |
425 | { | |
426 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER); | |
427 | return 0; | |
428 | } | |
429 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
430 | ref_exists = ((e->struct_ref > 0) ? 1 : 0); | |
431 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
432 | ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); | |
433 | if(!ref_exists) | |
434 | { | |
435 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE); | |
436 | return 0; | |
437 | } | |
438 | /* Intercept any "root-level" commands before trying to hand them on to | |
439 | * ctrl() handlers. */ | |
440 | switch(cmd) | |
441 | { | |
442 | case ENGINE_CTRL_HAS_CTRL_FUNCTION: | |
443 | return ctrl_exists; | |
444 | case ENGINE_CTRL_GET_FIRST_CMD_TYPE: | |
445 | case ENGINE_CTRL_GET_NEXT_CMD_TYPE: | |
446 | case ENGINE_CTRL_GET_CMD_FROM_NAME: | |
447 | case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: | |
448 | case ENGINE_CTRL_GET_NAME_FROM_CMD: | |
449 | case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: | |
450 | case ENGINE_CTRL_GET_DESC_FROM_CMD: | |
451 | case ENGINE_CTRL_GET_CMD_FLAGS: | |
452 | if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) | |
453 | return int_ctrl_helper(e,cmd,i,p,f); | |
454 | if(!ctrl_exists) | |
455 | { | |
456 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); | |
457 | /* For these cmd-related functions, failure is indicated | |
458 | * by a -1 return value (because 0 is used as a valid | |
459 | * return in some places). */ | |
460 | return -1; | |
461 | } | |
462 | default: | |
463 | break; | |
464 | } | |
465 | /* Anything else requires a ctrl() handler to exist. */ | |
466 | if(!ctrl_exists) | |
467 | { | |
468 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); | |
469 | return 0; | |
470 | } | |
471 | return e->ctrl(e, cmd, i, p, f); | |
472 | } | |
473 | ||
474 | int ENGINE_cmd_is_executable(ENGINE *e, int cmd) | |
475 | { | |
476 | int flags; | |
477 | if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) | |
478 | { | |
479 | ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, | |
480 | ENGINE_R_INVALID_CMD_NUMBER); | |
481 | return 0; | |
482 | } | |
483 | if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) && | |
484 | !(flags & ENGINE_CMD_FLAG_NUMERIC) && | |
485 | !(flags & ENGINE_CMD_FLAG_STRING)) | |
486 | return 0; | |
487 | return 1; | |
488 | } | |
489 | ||
490 | int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, | |
491 | long i, void *p, void (*f)(), int cmd_optional) | |
492 | { | |
493 | int num; | |
494 | ||
495 | if((e == NULL) || (cmd_name == NULL)) | |
496 | { | |
497 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
498 | ERR_R_PASSED_NULL_PARAMETER); | |
499 | return 0; | |
500 | } | |
501 | if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, | |
502 | ENGINE_CTRL_GET_CMD_FROM_NAME, | |
503 | 0, (void *)cmd_name, NULL)) <= 0)) | |
504 | { | |
505 | /* If the command didn't *have* to be supported, we fake | |
506 | * success. This allows certain settings to be specified for | |
507 | * multiple ENGINEs and only require a change of ENGINE id | |
508 | * (without having to selectively apply settings). Eg. changing | |
509 | * from a hardware device back to the regular software ENGINE | |
510 | * without editing the config file, etc. */ | |
511 | if(cmd_optional) | |
512 | { | |
513 | ERR_clear_error(); | |
514 | return 1; | |
515 | } | |
516 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, | |
517 | ENGINE_R_INVALID_CMD_NAME); | |
518 | return 0; | |
519 | } | |
520 | /* Force the result of the control command to 0 or 1, for the reasons | |
521 | * mentioned before. */ | |
522 | if (ENGINE_ctrl(e, num, i, p, f)) | |
523 | return 1; | |
524 | return 0; | |
525 | } | |
526 | ||
527 | int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, | |
528 | int cmd_optional) | |
529 | { | |
530 | int num, flags; | |
531 | long l; | |
532 | char *ptr; | |
533 | if((e == NULL) || (cmd_name == NULL)) | |
534 | { | |
535 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
536 | ERR_R_PASSED_NULL_PARAMETER); | |
537 | return 0; | |
538 | } | |
539 | if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, | |
540 | ENGINE_CTRL_GET_CMD_FROM_NAME, | |
541 | 0, (void *)cmd_name, NULL)) <= 0)) | |
542 | { | |
543 | /* If the command didn't *have* to be supported, we fake | |
544 | * success. This allows certain settings to be specified for | |
545 | * multiple ENGINEs and only require a change of ENGINE id | |
546 | * (without having to selectively apply settings). Eg. changing | |
547 | * from a hardware device back to the regular software ENGINE | |
548 | * without editing the config file, etc. */ | |
549 | if(cmd_optional) | |
550 | { | |
551 | ERR_clear_error(); | |
552 | return 1; | |
553 | } | |
554 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
555 | ENGINE_R_INVALID_CMD_NAME); | |
556 | return 0; | |
557 | } | |
558 | if(!ENGINE_cmd_is_executable(e, num)) | |
559 | { | |
560 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
561 | ENGINE_R_CMD_NOT_EXECUTABLE); | |
562 | return 0; | |
563 | } | |
564 | if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) | |
565 | { | |
566 | /* Shouldn't happen, given that ENGINE_cmd_is_executable() | |
567 | * returned success. */ | |
568 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
569 | ENGINE_R_INTERNAL_LIST_ERROR); | |
570 | return 0; | |
571 | } | |
572 | /* If the command takes no input, there must be no input. And vice | |
573 | * versa. */ | |
574 | if(flags & ENGINE_CMD_FLAG_NO_INPUT) | |
575 | { | |
576 | if(arg != NULL) | |
577 | { | |
578 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
579 | ENGINE_R_COMMAND_TAKES_NO_INPUT); | |
580 | return 0; | |
581 | } | |
582 | /* We deliberately force the result of ENGINE_ctrl() to 0 or 1 | |
583 | * rather than returning it as "return data". This is to ensure | |
584 | * usage of these commands is consistent across applications and | |
585 | * that certain applications don't understand it one way, and | |
586 | * others another. */ | |
587 | if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) | |
588 | return 1; | |
589 | return 0; | |
590 | } | |
591 | /* So, we require input */ | |
592 | if(arg == NULL) | |
593 | { | |
594 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
595 | ENGINE_R_COMMAND_TAKES_INPUT); | |
596 | return 0; | |
597 | } | |
598 | /* If it takes string input, that's easy */ | |
599 | if(flags & ENGINE_CMD_FLAG_STRING) | |
600 | { | |
601 | /* Same explanation as above */ | |
602 | if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) | |
603 | return 1; | |
604 | return 0; | |
605 | } | |
606 | /* If it doesn't take numeric either, then it is unsupported for use in | |
607 | * a config-setting situation, which is what this function is for. This | |
608 | * should never happen though, because ENGINE_cmd_is_executable() was | |
609 | * used. */ | |
610 | if(!(flags & ENGINE_CMD_FLAG_NUMERIC)) | |
611 | { | |
612 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
613 | ENGINE_R_INTERNAL_LIST_ERROR); | |
614 | return 0; | |
615 | } | |
616 | l = strtol(arg, &ptr, 10); | |
617 | if((arg == ptr) || (*ptr != '\0')) | |
618 | { | |
619 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | |
620 | ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); | |
621 | return 0; | |
622 | } | |
623 | /* Force the result of the control command to 0 or 1, for the reasons | |
624 | * mentioned before. */ | |
625 | if(ENGINE_ctrl(e, num, l, NULL, NULL)) | |
626 | return 1; | |
627 | return 0; | |
628 | } | |
629 | ||
630 | static ENGINE *engine_get_default_type(ENGINE_TYPE t) | |
631 | { | |
632 | ENGINE *ret = NULL; | |
633 | ||
634 | /* engine_def_check is lean and mean and won't replace any | |
635 | * prior default engines ... so we must ensure that it is always | |
636 | * the first function to get to touch the default values. */ | |
637 | engine_def_check(); | |
638 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
639 | switch(t) | |
640 | { | |
641 | #ifndef OPENSSL_NO_RSA | |
642 | case ENGINE_TYPE_RSA: | |
643 | ret = engine_def_rsa; break; | |
644 | #endif | |
645 | #ifndef OPENSSL_NO_DSA | |
646 | case ENGINE_TYPE_DSA: | |
647 | ret = engine_def_dsa; break; | |
648 | #endif | |
649 | #ifndef OPENSSL_NO_DH | |
650 | case ENGINE_TYPE_DH: | |
651 | ret = engine_def_dh; break; | |
652 | #endif | |
653 | case ENGINE_TYPE_RAND: | |
654 | ret = engine_def_rand; break; | |
655 | case ENGINE_TYPE_BN_MOD_EXP: | |
656 | ret = engine_def_bn_mod_exp; break; | |
657 | case ENGINE_TYPE_BN_MOD_EXP_CRT: | |
658 | ret = engine_def_bn_mod_exp_crt; break; | |
659 | default: | |
660 | break; | |
661 | } | |
662 | /* Unforunately we can't do this work outside the lock with a | |
663 | * call to ENGINE_init() because that would leave a race | |
664 | * condition open. */ | |
665 | if(ret) | |
666 | { | |
667 | ret->struct_ref++; | |
668 | ret->funct_ref++; | |
669 | engine_ref_debug(ret, 0, 1) | |
670 | engine_ref_debug(ret, 1, 1) | |
671 | } | |
672 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
673 | return ret; | |
674 | } | |
675 | ||
676 | #ifndef OPENSSL_NO_RSA | |
677 | ENGINE *ENGINE_get_default_RSA(void) | |
678 | { | |
679 | return engine_get_default_type(ENGINE_TYPE_RSA); | |
680 | } | |
681 | #endif | |
682 | ||
683 | #ifndef OPENSSL_NO_DSA | |
684 | ENGINE *ENGINE_get_default_DSA(void) | |
685 | { | |
686 | return engine_get_default_type(ENGINE_TYPE_DSA); | |
687 | } | |
688 | #endif | |
689 | ||
690 | #ifndef OPENSSL_NO_DH | |
691 | ENGINE *ENGINE_get_default_DH(void) | |
692 | { | |
693 | return engine_get_default_type(ENGINE_TYPE_DH); | |
694 | } | |
695 | #endif | |
696 | ||
697 | ENGINE *ENGINE_get_default_RAND(void) | |
698 | { | |
699 | return engine_get_default_type(ENGINE_TYPE_RAND); | |
700 | } | |
701 | ||
702 | ENGINE *ENGINE_get_default_BN_mod_exp(void) | |
703 | { | |
704 | return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP); | |
705 | } | |
706 | ||
707 | ENGINE *ENGINE_get_default_BN_mod_exp_crt(void) | |
708 | { | |
709 | return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT); | |
710 | } | |
711 | ||
712 | static int engine_set_default_type(ENGINE_TYPE t, ENGINE *e) | |
713 | { | |
714 | ENGINE *old = NULL; | |
715 | ||
716 | /* engine_def_check is lean and mean and won't replace any | |
717 | * prior default engines ... so we must ensure that it is always | |
718 | * the first function to get to touch the default values. */ | |
719 | engine_def_check(); | |
720 | /* Attempt to get a functional reference (we need one anyway, but | |
721 | * also, 'e' may be just a structural reference being passed in so | |
722 | * this call may actually be the first). */ | |
723 | if(e && !ENGINE_init(e)) | |
724 | { | |
725 | ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE, | |
726 | ENGINE_R_INIT_FAILED); | |
727 | return 0; | |
728 | } | |
729 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | |
730 | switch(t) | |
731 | { | |
732 | #ifndef OPENSSL_NO_RSA | |
733 | case ENGINE_TYPE_RSA: | |
734 | old = engine_def_rsa; | |
735 | engine_def_rsa = e; break; | |
736 | #endif | |
737 | #ifndef OPENSSL_NO_DSA | |
738 | case ENGINE_TYPE_DSA: | |
739 | old = engine_def_dsa; | |
740 | engine_def_dsa = e; break; | |
741 | #endif | |
742 | #ifndef OPENSSL_NO_DH | |
743 | case ENGINE_TYPE_DH: | |
744 | old = engine_def_dh; | |
745 | engine_def_dh = e; break; | |
746 | #endif | |
747 | case ENGINE_TYPE_RAND: | |
748 | old = engine_def_rand; | |
749 | engine_def_rand = e; break; | |
750 | case ENGINE_TYPE_BN_MOD_EXP: | |
751 | old = engine_def_bn_mod_exp; | |
752 | engine_def_bn_mod_exp = e; break; | |
753 | case ENGINE_TYPE_BN_MOD_EXP_CRT: | |
754 | old = engine_def_bn_mod_exp_crt; | |
755 | engine_def_bn_mod_exp_crt = e; break; | |
756 | default: | |
757 | break; | |
758 | } | |
759 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | |
760 | /* If we've replaced a previous value, then we need to remove the | |
761 | * functional reference we had. */ | |
762 | if(old && !ENGINE_finish(old)) | |
763 | { | |
764 | ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE, | |
765 | ENGINE_R_FINISH_FAILED); | |
766 | return 0; | |
767 | } | |
768 | return 1; | |
769 | } | |
770 | ||
771 | #ifndef OPENSSL_NO_RSA | |
772 | int ENGINE_set_default_RSA(ENGINE *e) | |
773 | { | |
774 | return engine_set_default_type(ENGINE_TYPE_RSA, e); | |
775 | } | |
776 | #endif | |
777 | ||
778 | #ifndef OPENSSL_NO_DSA | |
779 | int ENGINE_set_default_DSA(ENGINE *e) | |
780 | { | |
781 | return engine_set_default_type(ENGINE_TYPE_DSA, e); | |
782 | } | |
783 | #endif | |
784 | ||
785 | #ifndef OPENSSL_NO_DH | |
786 | int ENGINE_set_default_DH(ENGINE *e) | |
787 | { | |
788 | return engine_set_default_type(ENGINE_TYPE_DH, e); | |
789 | } | |
790 | #endif | |
791 | ||
792 | int ENGINE_set_default_RAND(ENGINE *e) | |
793 | { | |
794 | return engine_set_default_type(ENGINE_TYPE_RAND, e); | |
795 | } | |
796 | ||
797 | int ENGINE_set_default_BN_mod_exp(ENGINE *e) | |
798 | { | |
799 | return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP, e); | |
800 | } | |
801 | ||
802 | int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e) | |
803 | { | |
804 | return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT, e); | |
805 | } | |
806 | ||
807 | int ENGINE_set_default(ENGINE *e, unsigned int flags) | |
808 | { | |
809 | #ifndef OPENSSL_NO_RSA | |
810 | if((flags & ENGINE_METHOD_RSA) && e->rsa_meth && | |
811 | !ENGINE_set_default_RSA(e)) | |
812 | return 0; | |
813 | #endif | |
814 | #ifndef OPENSSL_NO_DSA | |
815 | if((flags & ENGINE_METHOD_DSA) && e->dsa_meth && | |
816 | !ENGINE_set_default_DSA(e)) | |
817 | return 0; | |
818 | #endif | |
819 | #ifndef OPENSSL_NO_DH | |
820 | if((flags & ENGINE_METHOD_DH) && e->dh_meth && | |
821 | !ENGINE_set_default_DH(e)) | |
822 | return 0; | |
823 | #endif | |
824 | if((flags & ENGINE_METHOD_RAND) && e->rand_meth && | |
825 | !ENGINE_set_default_RAND(e)) | |
826 | return 0; | |
827 | if((flags & ENGINE_METHOD_BN_MOD_EXP) && e->bn_mod_exp && | |
828 | !ENGINE_set_default_BN_mod_exp(e)) | |
829 | return 0; | |
830 | if((flags & ENGINE_METHOD_BN_MOD_EXP_CRT) && e->bn_mod_exp_crt && | |
831 | !ENGINE_set_default_BN_mod_exp_crt(e)) | |
832 | return 0; | |
833 | return 1; | |
834 | } | |
835 | ||
836 | int ENGINE_clear_defaults(void) | |
837 | { | |
838 | /* If the defaults haven't even been set yet, don't bother. Any kind of | |
839 | * "cleanup" has a kind of implicit race-condition if another thread is | |
840 | * trying to keep going, so we don't address that with locking. The | |
841 | * first ENGINE_set_default_*** call will actually *create* a standard | |
842 | * set of default ENGINEs (including init() and functional reference | |
843 | * counts aplenty) before the rest of this function undoes them all. So | |
844 | * save some hassle ... */ | |
845 | if(!engine_def_flag) | |
846 | return 1; | |
847 | if((0 == 1) || | |
848 | #ifndef OPENSSL_NO_RSA | |
849 | !ENGINE_set_default_RSA(NULL) || | |
850 | #endif | |
851 | #ifndef OPENSSL_NO_DSA | |
852 | !ENGINE_set_default_DSA(NULL) || | |
853 | #endif | |
854 | #ifndef OPENSSL_NO_DH | |
855 | !ENGINE_set_default_DH(NULL) || | |
856 | #endif | |
857 | !ENGINE_set_default_RAND(NULL) || | |
858 | !ENGINE_set_default_BN_mod_exp(NULL) || | |
859 | !ENGINE_set_default_BN_mod_exp_crt(NULL) || | |
860 | !RAND_set_rand_method(NULL)) | |
861 | return 0; | |
862 | return 1; | |
863 | } | |
864 |