Check for OPENSSL_NO_RSA, OPENSSL_NO_DSA and OPENSSL_NO_DH and disable
[openssl.git] / crypto / engine / engine_lib.c
1 /* crypto/engine/engine_lib.c */
2 /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
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 "engine_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         }
107
108 /* In a slight break with convention - this static function must be
109  * called *outside* any locking of CRYPTO_LOCK_ENGINE. */
110 static void engine_def_check(void)
111         {
112         ENGINE *e;
113         if(engine_def_flag)
114                 return;
115         e = ENGINE_get_first();
116         if(e == NULL)
117                 /* The list is empty ... not much we can do! */
118                 return;
119         /* We have a structural reference, see if getting a functional
120          * reference is possible. This is done to cope with init errors
121          * in the engine - the following locked code does a bunch of
122          * manual "ENGINE_init"s which do *not* allow such an init
123          * error so this is worth doing. */
124         if(ENGINE_init(e))
125                 {
126                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
127                 /* Doing another check here prevents an obvious race
128                  * condition because the whole function itself cannot
129                  * be locked. */
130                 if(engine_def_flag)
131                         goto skip_set_defaults;
132                 /* OK, we got a functional reference, so we get one each
133                  * for the defaults too. */
134 #ifndef OPENSSL_NO_RSA
135                 engine_def_check_util(&engine_def_rsa, e);
136 #endif
137 #ifndef OPENSSL_NO_RSA
138                 engine_def_check_util(&engine_def_dsa, e);
139 #endif
140 #ifndef OPENSSL_NO_DH
141                 engine_def_check_util(&engine_def_dh, e);
142 #endif
143                 engine_def_check_util(&engine_def_rand, e);
144                 engine_def_check_util(&engine_def_bn_mod_exp, e);
145                 engine_def_check_util(&engine_def_bn_mod_exp_crt, e);
146                 engine_def_flag = 1;
147 skip_set_defaults:
148                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
149                 /* The "if" needs to be balanced out. */
150                 ENGINE_finish(e);
151                 }
152         /* We need to balance out the fact we obtained a structural
153          * reference to begin with from ENGINE_get_first(). */
154         ENGINE_free(e);
155         }
156
157 /* Initialise a engine type for use (or up its functional reference count
158  * if it's already in use). */
159 int ENGINE_init(ENGINE *e)
160         {
161         int to_return = 1;
162
163         if(e == NULL)
164                 {
165                 ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
166                 return 0;
167                 }
168         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
169         if((e->funct_ref == 0) && e->init)
170                 /* This is the first functional reference and the engine
171                  * requires initialisation so we do it now. */
172                 to_return = e->init(e);
173         if(to_return)
174                 {
175                 /* OK, we return a functional reference which is also a
176                  * structural reference. */
177                 e->struct_ref++;
178                 e->funct_ref++;
179                 }
180         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
181         return to_return;
182         }
183
184 /* Free a functional reference to a engine type */
185 int ENGINE_finish(ENGINE *e)
186         {
187         int to_return = 1;
188
189         if(e == NULL)
190                 {
191                 ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
192                 return 0;
193                 }
194         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
195         if((e->funct_ref == 1) && e->finish)
196 #if 0
197                 /* This is the last functional reference and the engine
198                  * requires cleanup so we do it now. */
199                 to_return = e->finish();
200         if(to_return)
201                 {
202                 /* Cleanup the functional reference which is also a
203                  * structural reference. */
204                 e->struct_ref--;
205                 e->funct_ref--;
206                 }
207         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
208 #else
209                 /* I'm going to deliberately do a convoluted version of this
210                  * piece of code because we don't want "finish" functions
211                  * being called inside a locked block of code, if at all
212                  * possible. I'd rather have this call take an extra couple
213                  * of ticks than have throughput serialised on a externally-
214                  * provided callback function that may conceivably never come
215                  * back. :-( */
216                 {
217                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
218                 /* CODE ALERT: This *IS* supposed to be "=" and NOT "==" :-) */
219                 if((to_return = e->finish(e)))
220                         {
221                         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
222                         /* Cleanup the functional reference which is also a
223                          * structural reference. */
224                         e->struct_ref--;
225                         e->funct_ref--;
226                         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
227                         }
228                 }
229         else
230                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
231 #endif
232         return to_return;
233         }
234
235 EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
236         const char *passphrase)
237         {
238         EVP_PKEY *pkey;
239
240         if(e == NULL)
241                 {
242                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
243                         ERR_R_PASSED_NULL_PARAMETER);
244                 return 0;
245                 }
246         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
247         if(e->funct_ref == 0)
248                 {
249                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
250                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
251                         ENGINE_R_NOT_INITIALISED);
252                 return 0;
253                 }
254         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
255         if (!e->load_privkey)
256                 {
257                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
258                         ENGINE_R_NO_LOAD_FUNCTION);
259                 return 0;
260                 }
261         pkey = e->load_privkey(e, key_id, passphrase);
262         if (!pkey)
263                 {
264                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
265                         ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
266                 return 0;
267                 }
268         return pkey;
269         }
270
271 EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
272         const char *passphrase)
273         {
274         EVP_PKEY *pkey;
275
276         if(e == NULL)
277                 {
278                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
279                         ERR_R_PASSED_NULL_PARAMETER);
280                 return 0;
281                 }
282         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
283         if(e->funct_ref == 0)
284                 {
285                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
286                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
287                         ENGINE_R_NOT_INITIALISED);
288                 return 0;
289                 }
290         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
291         if (!e->load_pubkey)
292                 {
293                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
294                         ENGINE_R_NO_LOAD_FUNCTION);
295                 return 0;
296                 }
297         pkey = e->load_pubkey(e, key_id, passphrase);
298         if (!pkey)
299                 {
300                 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
301                         ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
302                 return 0;
303                 }
304         return pkey;
305         }
306
307 /* These internal functions handle 'CMD'-related control commands when the
308  * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
309  * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
310
311 static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
312         {
313         if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
314                 return 1;
315         return 0;
316         }
317
318 static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
319         {
320         int idx = 0;
321         while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
322                 {
323                 idx++;
324                 defn++;
325                 }
326         if(int_ctrl_cmd_is_null(defn))
327                 /* The given name wasn't found */
328                 return -1;
329         return idx;
330         }
331
332 static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
333         {
334         int idx = 0;
335         /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
336          * our searches don't need to take any longer than necessary. */
337         while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
338                 {
339                 idx++;
340                 defn++;
341                 }
342         if(defn->cmd_num == num)
343                 return idx;
344         /* The given cmd_num wasn't found */
345         return -1;
346         }
347
348 static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)())
349         {
350         int idx;
351         char *s = (char *)p;
352         /* Take care of the easy one first (eg. it requires no searches) */
353         if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
354                 {
355                 if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
356                         return 0;
357                 return e->cmd_defns->cmd_num;
358                 }
359         /* One or two commands require that "p" be a valid string buffer */
360         if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
361                         (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
362                         (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
363                 {
364                 if(s == NULL)
365                         {
366                         ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
367                                 ERR_R_PASSED_NULL_PARAMETER);
368                         return -1;
369                         }
370                 }
371         /* Now handle cmd_name -> cmd_num conversion */
372         if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
373                 {
374                 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
375                                                 e->cmd_defns, s)) < 0))
376                         {
377                         ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
378                                 ENGINE_R_INVALID_CMD_NAME);
379                         return -1;
380                         }
381                 return e->cmd_defns[idx].cmd_num;
382                 }
383         /* For the rest of the commands, the 'long' argument must specify a
384          * valie command number - so we need to conduct a search. */
385         if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
386                                         (unsigned int)i)) < 0))
387                 {
388                 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
389                         ENGINE_R_INVALID_CMD_NUMBER);
390                 return -1;
391                 }
392         /* Now the logic splits depending on command type */
393         switch(cmd)
394                 {
395         case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
396                 idx++;
397                 if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
398                         /* end-of-list */
399                         return 0;
400                 else
401                         return e->cmd_defns[idx].cmd_num;
402         case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
403                 return strlen(e->cmd_defns[idx].cmd_name);
404         case ENGINE_CTRL_GET_NAME_FROM_CMD:
405                 return sprintf(s, "%s", e->cmd_defns[idx].cmd_name);
406         case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
407                 if(e->cmd_defns[idx].cmd_desc)
408                         return strlen(e->cmd_defns[idx].cmd_desc);
409                 return strlen(int_no_description);
410         case ENGINE_CTRL_GET_DESC_FROM_CMD:
411                 if(e->cmd_defns[idx].cmd_desc)
412                         return sprintf(s, "%s", e->cmd_defns[idx].cmd_desc);
413                 return sprintf(s, "%s", int_no_description);
414         case ENGINE_CTRL_GET_CMD_FLAGS:
415                 return e->cmd_defns[idx].cmd_flags;
416                 }
417         /* Shouldn't really be here ... */
418         ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
419         return -1;
420         }
421
422 int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
423         {
424         int ctrl_exists, ref_exists;
425         if(e == NULL)
426                 {
427                 ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
428                 return 0;
429                 }
430         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
431         ref_exists = ((e->struct_ref > 0) ? 1 : 0);
432         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
433         ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
434         if(!ref_exists)
435                 {
436                 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
437                 return 0;
438                 }
439         /* Intercept any "root-level" commands before trying to hand them on to
440          * ctrl() handlers. */
441         switch(cmd)
442                 {
443         case ENGINE_CTRL_HAS_CTRL_FUNCTION:
444                 return ctrl_exists;
445         case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
446         case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
447         case ENGINE_CTRL_GET_CMD_FROM_NAME:
448         case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
449         case ENGINE_CTRL_GET_NAME_FROM_CMD:
450         case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
451         case ENGINE_CTRL_GET_DESC_FROM_CMD:
452         case ENGINE_CTRL_GET_CMD_FLAGS:
453                 if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
454                         return int_ctrl_helper(e,cmd,i,p,f);
455                 if(!ctrl_exists)
456                         {
457                         ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
458                         /* For these cmd-related functions, failure is indicated
459                          * by a -1 return value (because 0 is used as a valid
460                          * return in some places). */
461                         return -1;
462                         }
463         default:
464                 break;
465                 }
466         /* Anything else requires a ctrl() handler to exist. */
467         if(!ctrl_exists)
468                 {
469                 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
470                 return 0;
471                 }
472         return e->ctrl(e, cmd, i, p, f);
473         }
474
475 int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
476         {
477         int flags;
478         if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
479                 {
480                 ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
481                         ENGINE_R_INVALID_CMD_NUMBER);
482                 return 0;
483                 }
484         if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
485                         !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
486                         !(flags & ENGINE_CMD_FLAG_STRING))
487                 return 0;
488         return 1;
489         }
490
491 int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
492                                 int cmd_optional)
493         {
494         int num, flags;
495         long l;
496         char *ptr;
497         if((e == NULL) || (cmd_name == NULL))
498                 {
499                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
500                         ERR_R_PASSED_NULL_PARAMETER);
501                 return 0;
502                 }
503         if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
504                                         ENGINE_CTRL_GET_CMD_FROM_NAME,
505                                         0, (void *)cmd_name, NULL)) <= 0))
506                 {
507                 /* If the command didn't *have* to be supported, we fake
508                  * success. This allows certain settings to be specified for
509                  * multiple ENGINEs and only require a change of ENGINE id
510                  * (without having to selectively apply settings). Eg. changing
511                  * from a hardware device back to the regular software ENGINE
512                  * without editing the config file, etc. */
513                 if(cmd_optional)
514                         {
515                         ERR_clear_error();
516                         return 1;
517                         }
518                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
519                         ENGINE_R_INVALID_CMD_NAME);
520                 return 0;
521                 }
522         if(!ENGINE_cmd_is_executable(e, num))
523                 {
524                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
525                         ENGINE_R_CMD_NOT_EXECUTABLE);
526                 return 0;
527                 }
528         if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
529                 {
530                 /* Shouldn't happen, given that ENGINE_cmd_is_executable()
531                  * returned success. */
532                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
533                         ENGINE_R_INTERNAL_LIST_ERROR);
534                 return 0;
535                 }
536         /* If the command takes no input, there must be no input. And vice
537          * versa. */
538         if(flags & ENGINE_CMD_FLAG_NO_INPUT)
539                 {
540                 if(arg != NULL)
541                         {
542                         ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
543                                 ENGINE_R_COMMAND_TAKES_NO_INPUT);
544                         return 0;
545                         }
546                 /* We deliberately force the result of ENGINE_ctrl() to 0 or 1
547                  * rather than returning it as "return data". This is to ensure
548                  * usage of these commands is consistent across applications and
549                  * that certain applications don't understand it one way, and
550                  * others another. */
551                 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
552                         return 1;
553                 return 0;
554                 }
555         /* So, we require input */
556         if(arg == NULL)
557                 {
558                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
559                         ENGINE_R_COMMAND_TAKES_INPUT);
560                 return 0;
561                 }
562         /* If it takes string input, that's easy */
563         if(flags & ENGINE_CMD_FLAG_STRING)
564                 {
565                 /* Same explanation as above */
566                 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
567                         return 1;
568                 return 0;
569                 }
570         /* If it doesn't take numeric either, then it is unsupported for use in
571          * a config-setting situation, which is what this function is for. This
572          * should never happen though, because ENGINE_cmd_is_executable() was
573          * used. */
574         if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
575                 {
576                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
577                         ENGINE_R_INTERNAL_LIST_ERROR);
578                 return 0;
579                 }
580         l = strtol(arg, &ptr, 10);
581         if((arg == ptr) || (*ptr != '\0'))
582                 {
583                 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
584                         ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
585                 return 0;
586                 }
587         /* Force the result of the control command to 0 or 1, for the reasons
588          * mentioned before. */
589         if(ENGINE_ctrl(e, num, l, NULL, NULL))
590                 return 1;
591         return 0;
592         }
593
594 static ENGINE *engine_get_default_type(ENGINE_TYPE t)
595         {
596         ENGINE *ret = NULL;
597
598         /* engine_def_check is lean and mean and won't replace any
599          * prior default engines ... so we must ensure that it is always
600          * the first function to get to touch the default values. */
601         engine_def_check();
602         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
603         switch(t)
604                 {
605 #ifndef OPENSSL_NO_RSA
606         case ENGINE_TYPE_RSA:
607                 ret = engine_def_rsa; break;
608 #endif
609 #ifndef OPENSSL_NO_DSA
610         case ENGINE_TYPE_DSA:
611                 ret = engine_def_dsa; break;
612 #endif
613 #ifndef OPENSSL_NO_DH
614         case ENGINE_TYPE_DH:
615                 ret = engine_def_dh; break;
616 #endif
617         case ENGINE_TYPE_RAND:
618                 ret = engine_def_rand; break;
619         case ENGINE_TYPE_BN_MOD_EXP:
620                 ret = engine_def_bn_mod_exp; break;
621         case ENGINE_TYPE_BN_MOD_EXP_CRT:
622                 ret = engine_def_bn_mod_exp_crt; break;
623                 }
624         /* Unforunately we can't do this work outside the lock with a
625          * call to ENGINE_init() because that would leave a race
626          * condition open. */
627         if(ret)
628                 {
629                 ret->struct_ref++;
630                 ret->funct_ref++;
631                 }
632         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
633         return ret;
634         }
635
636 #ifndef OPENSSL_NO_RSA
637 ENGINE *ENGINE_get_default_RSA(void)
638         {
639         return engine_get_default_type(ENGINE_TYPE_RSA);
640         }
641 #endif
642
643 #ifndef OPENSSL_NO_DSA
644 ENGINE *ENGINE_get_default_DSA(void)
645         {
646         return engine_get_default_type(ENGINE_TYPE_DSA);
647         }
648 #endif
649
650 #ifndef OPENSSL_NO_DH
651 ENGINE *ENGINE_get_default_DH(void)
652         {
653         return engine_get_default_type(ENGINE_TYPE_DH);
654         }
655 #endif
656
657 ENGINE *ENGINE_get_default_RAND(void)
658         {
659         return engine_get_default_type(ENGINE_TYPE_RAND);
660         }
661
662 ENGINE *ENGINE_get_default_BN_mod_exp(void)
663         {
664         return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP);
665         }
666
667 ENGINE *ENGINE_get_default_BN_mod_exp_crt(void)
668         {
669         return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT);
670         }
671
672 static int engine_set_default_type(ENGINE_TYPE t, ENGINE *e)
673         {
674         ENGINE *old = NULL;
675
676         if(e == NULL)
677                 {
678                 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE,
679                         ERR_R_PASSED_NULL_PARAMETER);
680                 return 0;
681                 }
682         /* engine_def_check is lean and mean and won't replace any
683          * prior default engines ... so we must ensure that it is always
684          * the first function to get to touch the default values. */
685         engine_def_check();
686         /* Attempt to get a functional reference (we need one anyway, but
687          * also, 'e' may be just a structural reference being passed in so
688          * this call may actually be the first). */
689         if(!ENGINE_init(e))
690                 {
691                 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE,
692                         ENGINE_R_INIT_FAILED);
693                 return 0;
694                 }
695         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
696         switch(t)
697                 {
698 #ifndef OPENSSL_NO_RSA
699         case ENGINE_TYPE_RSA:
700                 old = engine_def_rsa;
701                 engine_def_rsa = e; break;
702 #endif
703 #ifndef OPENSSL_NO_DSA
704         case ENGINE_TYPE_DSA:
705                 old = engine_def_dsa;
706                 engine_def_dsa = e; break;
707 #endif
708 #ifndef OPENSSL_NO_DH
709         case ENGINE_TYPE_DH:
710                 old = engine_def_dh;
711                 engine_def_dh = e; break;
712 #endif
713         case ENGINE_TYPE_RAND:
714                 old = engine_def_rand;
715                 engine_def_rand = e; break;
716         case ENGINE_TYPE_BN_MOD_EXP:
717                 old = engine_def_bn_mod_exp;
718                 engine_def_bn_mod_exp = e; break;
719         case ENGINE_TYPE_BN_MOD_EXP_CRT:
720                 old = engine_def_bn_mod_exp_crt;
721                 engine_def_bn_mod_exp_crt = e; break;
722                 }
723         CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
724         /* If we've replaced a previous value, then we need to remove the
725          * functional reference we had. */
726         if(old && !ENGINE_finish(old))
727                 {
728                 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE,
729                         ENGINE_R_FINISH_FAILED);
730                 return 0;
731                 }
732         return 1;
733         }
734
735 #ifndef OPENSSL_NO_RSA
736 int ENGINE_set_default_RSA(ENGINE *e)
737         {
738         return engine_set_default_type(ENGINE_TYPE_RSA, e);
739         }
740 #endif
741
742 #ifndef OPENSSL_NO_DSA
743 int ENGINE_set_default_DSA(ENGINE *e)
744         {
745         return engine_set_default_type(ENGINE_TYPE_DSA, e);
746         }
747 #endif
748
749 #ifndef OPENSSL_NO_DH
750 int ENGINE_set_default_DH(ENGINE *e)
751         {
752         return engine_set_default_type(ENGINE_TYPE_DH, e);
753         }
754 #endif
755
756 int ENGINE_set_default_RAND(ENGINE *e)
757         {
758         return engine_set_default_type(ENGINE_TYPE_RAND, e);
759         }
760
761 int ENGINE_set_default_BN_mod_exp(ENGINE *e)
762         {
763         return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP, e);
764         }
765
766 int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e)
767         {
768         return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT, e);
769         }
770
771 int ENGINE_set_default(ENGINE *e, unsigned int flags)
772         {
773 #ifndef OPENSSL_NO_RSA
774         if((flags & ENGINE_METHOD_RSA) && e->rsa_meth &&
775                         !ENGINE_set_default_RSA(e))
776                 return 0;
777 #endif
778 #ifndef OPENSSL_NO_DSA
779         if((flags & ENGINE_METHOD_DSA) && e->dsa_meth &&
780                         !ENGINE_set_default_DSA(e))
781                 return 0;
782 #endif
783 #ifndef OPENSSL_NO_DH
784         if((flags & ENGINE_METHOD_DH) && e->dh_meth &&
785                         !ENGINE_set_default_DH(e))
786                 return 0;
787 #endif
788         if((flags & ENGINE_METHOD_RAND) && e->rand_meth &&
789                         !ENGINE_set_default_RAND(e))
790                 return 0;
791         if((flags & ENGINE_METHOD_BN_MOD_EXP) && e->bn_mod_exp &&
792                         !ENGINE_set_default_BN_mod_exp(e))
793                 return 0;
794         if((flags & ENGINE_METHOD_BN_MOD_EXP_CRT) && e->bn_mod_exp_crt &&
795                         !ENGINE_set_default_BN_mod_exp_crt(e))
796                 return 0;
797         return 1;
798         }
799