OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
eng_ctrl.c
Go to the documentation of this file.
1 /* crypto/engine/eng_ctrl.c */
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
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  * ([email protected]). This product includes software written by Tim
52  * Hudson ([email protected]).
53  *
54  */
55 
56 #include "eng_int.h"
57 
58 /* When querying a ENGINE-specific control command's 'description', this string
59  * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
60 static const char *int_no_description = "";
61 
62 /* These internal functions handle 'CMD'-related control commands when the
63  * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
64  * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
65 
66 static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
67  {
68  if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
69  return 1;
70  return 0;
71  }
72 
73 static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
74  {
75  int idx = 0;
76  while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
77  {
78  idx++;
79  defn++;
80  }
81  if(int_ctrl_cmd_is_null(defn))
82  /* The given name wasn't found */
83  return -1;
84  return idx;
85  }
86 
87 static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
88  {
89  int idx = 0;
90  /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
91  * our searches don't need to take any longer than necessary. */
92  while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
93  {
94  idx++;
95  defn++;
96  }
97  if(defn->cmd_num == num)
98  return idx;
99  /* The given cmd_num wasn't found */
100  return -1;
101  }
102 
103 static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
104  void (*f)(void))
105  {
106  int idx;
107  char *s = (char *)p;
108  /* Take care of the easy one first (eg. it requires no searches) */
110  {
111  if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
112  return 0;
113  return e->cmd_defns->cmd_num;
114  }
115  /* One or two commands require that "p" be a valid string buffer */
116  if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
119  {
120  if(s == NULL)
121  {
124  return -1;
125  }
126  }
127  /* Now handle cmd_name -> cmd_num conversion */
129  {
130  if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
131  e->cmd_defns, s)) < 0))
132  {
135  return -1;
136  }
137  return e->cmd_defns[idx].cmd_num;
138  }
139  /* For the rest of the commands, the 'long' argument must specify a
140  * valie command number - so we need to conduct a search. */
141  if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
142  (unsigned int)i)) < 0))
143  {
146  return -1;
147  }
148  /* Now the logic splits depending on command type */
149  switch(cmd)
150  {
152  idx++;
153  if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
154  /* end-of-list */
155  return 0;
156  else
157  return e->cmd_defns[idx].cmd_num;
159  return strlen(e->cmd_defns[idx].cmd_name);
161  return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
162  "%s", e->cmd_defns[idx].cmd_name);
164  if(e->cmd_defns[idx].cmd_desc)
165  return strlen(e->cmd_defns[idx].cmd_desc);
166  return strlen(int_no_description);
168  if(e->cmd_defns[idx].cmd_desc)
169  return BIO_snprintf(s,
170  strlen(e->cmd_defns[idx].cmd_desc) + 1,
171  "%s", e->cmd_defns[idx].cmd_desc);
172  return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
173  int_no_description);
175  return e->cmd_defns[idx].cmd_flags;
176  }
177  /* Shouldn't really be here ... */
179  return -1;
180  }
181 
182 int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
183  {
184  int ctrl_exists, ref_exists;
185  if(e == NULL)
186  {
188  return 0;
189  }
191  ref_exists = ((e->struct_ref > 0) ? 1 : 0);
193  ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
194  if(!ref_exists)
195  {
197  return 0;
198  }
199  /* Intercept any "root-level" commands before trying to hand them on to
200  * ctrl() handlers. */
201  switch(cmd)
202  {
204  return ctrl_exists;
213  if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
214  return int_ctrl_helper(e,cmd,i,p,f);
215  if(!ctrl_exists)
216  {
218  /* For these cmd-related functions, failure is indicated
219  * by a -1 return value (because 0 is used as a valid
220  * return in some places). */
221  return -1;
222  }
223  default:
224  break;
225  }
226  /* Anything else requires a ctrl() handler to exist. */
227  if(!ctrl_exists)
228  {
230  return 0;
231  }
232  return e->ctrl(e, cmd, i, p, f);
233  }
234 
236  {
237  int flags;
238  if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
239  {
242  return 0;
243  }
244  if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
245  !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
246  !(flags & ENGINE_CMD_FLAG_STRING))
247  return 0;
248  return 1;
249  }
250 
251 int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
252  long i, void *p, void (*f)(void), int cmd_optional)
253  {
254  int num;
255 
256  if((e == NULL) || (cmd_name == NULL))
257  {
260  return 0;
261  }
262  if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
264  0, (void *)cmd_name, NULL)) <= 0))
265  {
266  /* If the command didn't *have* to be supported, we fake
267  * success. This allows certain settings to be specified for
268  * multiple ENGINEs and only require a change of ENGINE id
269  * (without having to selectively apply settings). Eg. changing
270  * from a hardware device back to the regular software ENGINE
271  * without editing the config file, etc. */
272  if(cmd_optional)
273  {
274  ERR_clear_error();
275  return 1;
276  }
279  return 0;
280  }
281  /* Force the result of the control command to 0 or 1, for the reasons
282  * mentioned before. */
283  if (ENGINE_ctrl(e, num, i, p, f) > 0)
284  return 1;
285  return 0;
286  }
287 
288 int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
289  int cmd_optional)
290  {
291  int num, flags;
292  long l;
293  char *ptr;
294  if((e == NULL) || (cmd_name == NULL))
295  {
298  return 0;
299  }
300  if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
302  0, (void *)cmd_name, NULL)) <= 0))
303  {
304  /* If the command didn't *have* to be supported, we fake
305  * success. This allows certain settings to be specified for
306  * multiple ENGINEs and only require a change of ENGINE id
307  * (without having to selectively apply settings). Eg. changing
308  * from a hardware device back to the regular software ENGINE
309  * without editing the config file, etc. */
310  if(cmd_optional)
311  {
312  ERR_clear_error();
313  return 1;
314  }
317  return 0;
318  }
319  if(!ENGINE_cmd_is_executable(e, num))
320  {
323  return 0;
324  }
325  if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
326  {
327  /* Shouldn't happen, given that ENGINE_cmd_is_executable()
328  * returned success. */
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  {
337  if(arg != NULL)
338  {
341  return 0;
342  }
343  /* We deliberately force the result of ENGINE_ctrl() to 0 or 1
344  * rather than returning it as "return data". This is to ensure
345  * usage of these commands is consistent across applications and
346  * that certain applications don't understand it one way, and
347  * others another. */
348  if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
349  return 1;
350  return 0;
351  }
352  /* So, we require input */
353  if(arg == NULL)
354  {
357  return 0;
358  }
359  /* If it takes string input, that's easy */
360  if(flags & ENGINE_CMD_FLAG_STRING)
361  {
362  /* Same explanation as above */
363  if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
364  return 1;
365  return 0;
366  }
367  /* If it doesn't take numeric either, then it is unsupported for use in
368  * a config-setting situation, which is what this function is for. This
369  * should never happen though, because ENGINE_cmd_is_executable() was
370  * used. */
371  if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
372  {
375  return 0;
376  }
377  l = strtol(arg, &ptr, 10);
378  if((arg == ptr) || (*ptr != '\0'))
379  {
382  return 0;
383  }
384  /* Force the result of the control command to 0 or 1, for the reasons
385  * mentioned before. */
386  if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
387  return 1;
388  return 0;
389  }