OLD | NEW |
| (Empty) |
1 /* apps/openssl.c */ | |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | |
3 * All rights reserved. | |
4 * | |
5 * This package is an SSL implementation written | |
6 * by Eric Young (eay@cryptsoft.com). | |
7 * The implementation was written so as to conform with Netscapes SSL. | |
8 * | |
9 * This library is free for commercial and non-commercial use as long as | |
10 * the following conditions are aheared to. The following conditions | |
11 * apply to all code found in this distribution, be it the RC4, RSA, | |
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
13 * included with this distribution is covered by the same copyright terms | |
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
15 * | |
16 * Copyright remains Eric Young's, and as such any Copyright notices in | |
17 * the code are not to be removed. | |
18 * If this package is used in a product, Eric Young should be given attribution | |
19 * as the author of the parts of the library used. | |
20 * This can be in the form of a textual message at program startup or | |
21 * in documentation (online or textual) provided with the package. | |
22 * | |
23 * Redistribution and use in source and binary forms, with or without | |
24 * modification, are permitted provided that the following conditions | |
25 * are met: | |
26 * 1. Redistributions of source code must retain the copyright | |
27 * notice, this list of conditions and the following disclaimer. | |
28 * 2. Redistributions in binary form must reproduce the above copyright | |
29 * notice, this list of conditions and the following disclaimer in the | |
30 * documentation and/or other materials provided with the distribution. | |
31 * 3. All advertising materials mentioning features or use of this software | |
32 * must display the following acknowledgement: | |
33 * "This product includes cryptographic software written by | |
34 * Eric Young (eay@cryptsoft.com)" | |
35 * The word 'cryptographic' can be left out if the rouines from the library | |
36 * being used are not cryptographic related :-). | |
37 * 4. If you include any Windows specific code (or a derivative thereof) from | |
38 * the apps directory (application code) you must include an acknowledgement: | |
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
40 * | |
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | |
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
51 * SUCH DAMAGE. | |
52 * | |
53 * The licence and distribution terms for any publically available version or | |
54 * derivative of this code cannot be changed. i.e. this code cannot simply be | |
55 * copied and put under another distribution licence | |
56 * [including the GNU Public Licence.] | |
57 */ | |
58 /* ==================================================================== | |
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. | |
60 * | |
61 * Redistribution and use in source and binary forms, with or without | |
62 * modification, are permitted provided that the following conditions | |
63 * are met: | |
64 * | |
65 * 1. Redistributions of source code must retain the above copyright | |
66 * notice, this list of conditions and the following disclaimer. | |
67 * | |
68 * 2. Redistributions in binary form must reproduce the above copyright | |
69 * notice, this list of conditions and the following disclaimer in | |
70 * the documentation and/or other materials provided with the | |
71 * distribution. | |
72 * | |
73 * 3. All advertising materials mentioning features or use of this | |
74 * software must display the following acknowledgment: | |
75 * "This product includes software developed by the OpenSSL Project | |
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | |
77 * | |
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
79 * endorse or promote products derived from this software without | |
80 * prior written permission. For written permission, please contact | |
81 * openssl-core@openssl.org. | |
82 * | |
83 * 5. Products derived from this software may not be called "OpenSSL" | |
84 * nor may "OpenSSL" appear in their names without prior written | |
85 * permission of the OpenSSL Project. | |
86 * | |
87 * 6. Redistributions of any form whatsoever must retain the following | |
88 * acknowledgment: | |
89 * "This product includes software developed by the OpenSSL Project | |
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
91 * | |
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
103 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
104 * ==================================================================== | |
105 * | |
106 * This product includes cryptographic software written by Eric Young | |
107 * (eay@cryptsoft.com). This product includes software written by Tim | |
108 * Hudson (tjh@cryptsoft.com). | |
109 * | |
110 */ | |
111 | |
112 | |
113 #include <stdio.h> | |
114 #include <string.h> | |
115 #include <stdlib.h> | |
116 #define OPENSSL_C /* tells apps.h to use complete apps_startup() */ | |
117 #include "apps.h" | |
118 #include <openssl/bio.h> | |
119 #include <openssl/crypto.h> | |
120 #include <openssl/lhash.h> | |
121 #include <openssl/conf.h> | |
122 #include <openssl/x509.h> | |
123 #include <openssl/pem.h> | |
124 #include <openssl/ssl.h> | |
125 #ifndef OPENSSL_NO_ENGINE | |
126 #include <openssl/engine.h> | |
127 #endif | |
128 #define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */ | |
129 #include "progs.h" | |
130 #include "s_apps.h" | |
131 #include <openssl/err.h> | |
132 #ifdef OPENSSL_FIPS | |
133 #include <openssl/fips.h> | |
134 #endif | |
135 | |
136 /* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the | |
137 * base prototypes (we cast each variable inside the function to the required | |
138 * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper | |
139 * functions. */ | |
140 | |
141 static LHASH_OF(FUNCTION) *prog_init(void ); | |
142 static int do_cmd(LHASH_OF(FUNCTION) *prog,int argc,char *argv[]); | |
143 static void list_pkey(BIO *out); | |
144 static void list_cipher(BIO *out); | |
145 static void list_md(BIO *out); | |
146 char *default_config_file=NULL; | |
147 | |
148 /* Make sure there is only one when MONOLITH is defined */ | |
149 #ifdef MONOLITH | |
150 CONF *config=NULL; | |
151 BIO *bio_err=NULL; | |
152 #endif | |
153 | |
154 | |
155 static void lock_dbg_cb(int mode, int type, const char *file, int line) | |
156 { | |
157 static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ | |
158 const char *errstr = NULL; | |
159 int rw; | |
160 | |
161 rw = mode & (CRYPTO_READ|CRYPTO_WRITE); | |
162 if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) | |
163 { | |
164 errstr = "invalid mode"; | |
165 goto err; | |
166 } | |
167 | |
168 if (type < 0 || type >= CRYPTO_NUM_LOCKS) | |
169 { | |
170 errstr = "type out of bounds"; | |
171 goto err; | |
172 } | |
173 | |
174 if (mode & CRYPTO_LOCK) | |
175 { | |
176 if (modes[type]) | |
177 { | |
178 errstr = "already locked"; | |
179 /* must not happen in a single-threaded program | |
180 * (would deadlock) */ | |
181 goto err; | |
182 } | |
183 | |
184 modes[type] = rw; | |
185 } | |
186 else if (mode & CRYPTO_UNLOCK) | |
187 { | |
188 if (!modes[type]) | |
189 { | |
190 errstr = "not locked"; | |
191 goto err; | |
192 } | |
193 | |
194 if (modes[type] != rw) | |
195 { | |
196 errstr = (rw == CRYPTO_READ) ? | |
197 "CRYPTO_r_unlock on write lock" : | |
198 "CRYPTO_w_unlock on read lock"; | |
199 } | |
200 | |
201 modes[type] = 0; | |
202 } | |
203 else | |
204 { | |
205 errstr = "invalid mode"; | |
206 goto err; | |
207 } | |
208 | |
209 err: | |
210 if (errstr) | |
211 { | |
212 /* we cannot use bio_err here */ | |
213 fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at
%s:%d\n", | |
214 errstr, mode, type, file, line); | |
215 } | |
216 } | |
217 | |
218 #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) | |
219 # define ARGV _Argv | |
220 #else | |
221 # define ARGV Argv | |
222 #endif | |
223 | |
224 int main(int Argc, char *ARGV[]) | |
225 { | |
226 ARGS arg; | |
227 #define PROG_NAME_SIZE 39 | |
228 char pname[PROG_NAME_SIZE+1]; | |
229 FUNCTION f,*fp; | |
230 MS_STATIC const char *prompt; | |
231 MS_STATIC char buf[1024]; | |
232 char *to_free=NULL; | |
233 int n,i,ret=0; | |
234 int argc; | |
235 char **argv,*p; | |
236 LHASH_OF(FUNCTION) *prog=NULL; | |
237 long errline; | |
238 | |
239 #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) | |
240 /* 2011-03-22 SMS. | |
241 * If we have 32-bit pointers everywhere, then we're safe, and | |
242 * we bypass this mess, as on non-VMS systems. (See ARGV, | |
243 * above.) | |
244 * Problem 1: Compaq/HP C before V7.3 always used 32-bit | |
245 * pointers for argv[]. | |
246 * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers | |
247 * everywhere else, we always allocate and use a 64-bit | |
248 * duplicate of argv[]. | |
249 * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed | |
250 * to NULL-terminate a 64-bit argv[]. (As this was written, the | |
251 * compiler ECO was available only on IA64.) | |
252 * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a | |
253 * 64-bit argv[argc] for NULL, and, if necessary, use a | |
254 * (properly) NULL-terminated (64-bit) duplicate of argv[]. | |
255 * The same code is used in either case to duplicate argv[]. | |
256 * Some of these decisions could be handled in preprocessing, | |
257 * but the code tends to get even uglier, and the penalty for | |
258 * deciding at compile- or run-time is tiny. | |
259 */ | |
260 char **Argv = NULL; | |
261 int free_Argv = 0; | |
262 | |
263 if ((sizeof( _Argv) < 8) /* 32-bit argv[]. */ | |
264 # if !defined( VMS_TRUST_ARGV) | |
265 || (_Argv[ Argc] != NULL) /* Untrusted argv[argc] not NULL. */ | |
266 # endif | |
267 ) | |
268 { | |
269 int i; | |
270 Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *)); | |
271 if (Argv == NULL) | |
272 { ret = -1; goto end; } | |
273 for(i = 0; i < Argc; i++) | |
274 Argv[i] = _Argv[i]; | |
275 Argv[ Argc] = NULL; /* Certain NULL termination. */ | |
276 free_Argv = 1; | |
277 } | |
278 else | |
279 { | |
280 /* Use the known-good 32-bit argv[] (which needs the | |
281 * type cast to satisfy the compiler), or the trusted or | |
282 * tested-good 64-bit argv[] as-is. */ | |
283 Argv = (char **)_Argv; | |
284 } | |
285 #endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */ | |
286 | |
287 arg.data=NULL; | |
288 arg.count=0; | |
289 | |
290 if (bio_err == NULL) | |
291 if ((bio_err=BIO_new(BIO_s_file())) != NULL) | |
292 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); | |
293 | |
294 if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compi
led-in library defaults */ | |
295 { | |
296 if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) | |
297 { | |
298 CRYPTO_malloc_debug_init(); | |
299 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); | |
300 } | |
301 else | |
302 { | |
303 /* OPENSSL_DEBUG_MEMORY=off */ | |
304 CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); | |
305 } | |
306 } | |
307 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); | |
308 | |
309 #if 0 | |
310 if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) | |
311 #endif | |
312 { | |
313 CRYPTO_set_locking_callback(lock_dbg_cb); | |
314 } | |
315 | |
316 if(getenv("OPENSSL_FIPS")) { | |
317 #ifdef OPENSSL_FIPS | |
318 if (!FIPS_mode_set(1)) { | |
319 ERR_load_crypto_strings(); | |
320 ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); | |
321 EXIT(1); | |
322 } | |
323 #else | |
324 fprintf(stderr, "FIPS mode not supported.\n"); | |
325 EXIT(1); | |
326 #endif | |
327 } | |
328 | |
329 apps_startup(); | |
330 | |
331 /* Lets load up our environment a little */ | |
332 p=getenv("OPENSSL_CONF"); | |
333 if (p == NULL) | |
334 p=getenv("SSLEAY_CONF"); | |
335 if (p == NULL) | |
336 p=to_free=make_config_name(); | |
337 | |
338 default_config_file=p; | |
339 | |
340 config=NCONF_new(NULL); | |
341 i=NCONF_load(config,p,&errline); | |
342 if (i == 0) | |
343 { | |
344 if (ERR_GET_REASON(ERR_peek_last_error()) | |
345 == CONF_R_NO_SUCH_FILE) | |
346 { | |
347 #if 0 /* ANDROID */ | |
348 BIO_printf(bio_err, | |
349 "WARNING: can't open config file: %s\n",p); | |
350 #endif | |
351 ERR_clear_error(); | |
352 NCONF_free(config); | |
353 config = NULL; | |
354 } | |
355 else | |
356 { | |
357 ERR_print_errors(bio_err); | |
358 NCONF_free(config); | |
359 exit(1); | |
360 } | |
361 } | |
362 | |
363 prog=prog_init(); | |
364 | |
365 /* first check the program name */ | |
366 program_name(Argv[0],pname,sizeof pname); | |
367 | |
368 f.name=pname; | |
369 fp=lh_FUNCTION_retrieve(prog,&f); | |
370 if (fp != NULL) | |
371 { | |
372 Argv[0]=pname; | |
373 ret=fp->func(Argc,Argv); | |
374 goto end; | |
375 } | |
376 | |
377 /* ok, now check that there are not arguments, if there are, | |
378 * run with them, shifting the ssleay off the front */ | |
379 if (Argc != 1) | |
380 { | |
381 Argc--; | |
382 Argv++; | |
383 ret=do_cmd(prog,Argc,Argv); | |
384 if (ret < 0) ret=0; | |
385 goto end; | |
386 } | |
387 | |
388 /* ok, lets enter the old 'OpenSSL>' mode */ | |
389 | |
390 for (;;) | |
391 { | |
392 ret=0; | |
393 p=buf; | |
394 n=sizeof buf; | |
395 i=0; | |
396 for (;;) | |
397 { | |
398 p[0]='\0'; | |
399 if (i++) | |
400 prompt=">"; | |
401 else prompt="OpenSSL> "; | |
402 fputs(prompt,stdout); | |
403 fflush(stdout); | |
404 if (!fgets(p,n,stdin)) | |
405 goto end; | |
406 if (p[0] == '\0') goto end; | |
407 i=strlen(p); | |
408 if (i <= 1) break; | |
409 if (p[i-2] != '\\') break; | |
410 i-=2; | |
411 p+=i; | |
412 n-=i; | |
413 } | |
414 if (!chopup_args(&arg,buf,&argc,&argv)) break; | |
415 | |
416 ret=do_cmd(prog,argc,argv); | |
417 if (ret < 0) | |
418 { | |
419 ret=0; | |
420 goto end; | |
421 } | |
422 if (ret != 0) | |
423 BIO_printf(bio_err,"error in %s\n",argv[0]); | |
424 (void)BIO_flush(bio_err); | |
425 } | |
426 BIO_printf(bio_err,"bad exit\n"); | |
427 ret=1; | |
428 end: | |
429 if (to_free) | |
430 OPENSSL_free(to_free); | |
431 if (config != NULL) | |
432 { | |
433 NCONF_free(config); | |
434 config=NULL; | |
435 } | |
436 if (prog != NULL) lh_FUNCTION_free(prog); | |
437 if (arg.data != NULL) OPENSSL_free(arg.data); | |
438 | |
439 apps_shutdown(); | |
440 | |
441 CRYPTO_mem_leaks(bio_err); | |
442 if (bio_err != NULL) | |
443 { | |
444 BIO_free(bio_err); | |
445 bio_err=NULL; | |
446 } | |
447 #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) | |
448 /* Free any duplicate Argv[] storage. */ | |
449 if (free_Argv) | |
450 { | |
451 OPENSSL_free(Argv); | |
452 } | |
453 #endif | |
454 OPENSSL_EXIT(ret); | |
455 } | |
456 | |
457 #define LIST_STANDARD_COMMANDS "list-standard-commands" | |
458 #define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands" | |
459 #define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms" | |
460 #define LIST_CIPHER_COMMANDS "list-cipher-commands" | |
461 #define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms" | |
462 #define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms" | |
463 | |
464 | |
465 static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) | |
466 { | |
467 FUNCTION f,*fp; | |
468 int i,ret=1,tp,nl; | |
469 | |
470 if ((argc <= 0) || (argv[0] == NULL)) | |
471 { ret=0; goto end; } | |
472 f.name=argv[0]; | |
473 fp=lh_FUNCTION_retrieve(prog,&f); | |
474 if (fp == NULL) | |
475 { | |
476 if (EVP_get_digestbyname(argv[0])) | |
477 { | |
478 f.type = FUNC_TYPE_MD; | |
479 f.func = dgst_main; | |
480 fp = &f; | |
481 } | |
482 else if (EVP_get_cipherbyname(argv[0])) | |
483 { | |
484 f.type = FUNC_TYPE_CIPHER; | |
485 f.func = enc_main; | |
486 fp = &f; | |
487 } | |
488 } | |
489 if (fp != NULL) | |
490 { | |
491 ret=fp->func(argc,argv); | |
492 } | |
493 else if ((strncmp(argv[0],"no-",3)) == 0) | |
494 { | |
495 BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE); | |
496 #ifdef OPENSSL_SYS_VMS | |
497 { | |
498 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); | |
499 bio_stdout = BIO_push(tmpbio, bio_stdout); | |
500 } | |
501 #endif | |
502 f.name=argv[0]+3; | |
503 ret = (lh_FUNCTION_retrieve(prog,&f) != NULL); | |
504 if (!ret) | |
505 BIO_printf(bio_stdout, "%s\n", argv[0]); | |
506 else | |
507 BIO_printf(bio_stdout, "%s\n", argv[0]+3); | |
508 BIO_free_all(bio_stdout); | |
509 goto end; | |
510 } | |
511 else if ((strcmp(argv[0],"quit") == 0) || | |
512 (strcmp(argv[0],"q") == 0) || | |
513 (strcmp(argv[0],"exit") == 0) || | |
514 (strcmp(argv[0],"bye") == 0)) | |
515 { | |
516 ret= -1; | |
517 goto end; | |
518 } | |
519 else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) || | |
520 (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) || | |
521 (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) || | |
522 (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) || | |
523 (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) || | |
524 (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)) | |
525 { | |
526 int list_type; | |
527 BIO *bio_stdout; | |
528 | |
529 if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) | |
530 list_type = FUNC_TYPE_GENERAL; | |
531 else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) | |
532 list_type = FUNC_TYPE_MD; | |
533 else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) | |
534 list_type = FUNC_TYPE_MD_ALG; | |
535 else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0) | |
536 list_type = FUNC_TYPE_PKEY; | |
537 else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) | |
538 list_type = FUNC_TYPE_CIPHER_ALG; | |
539 else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */ | |
540 list_type = FUNC_TYPE_CIPHER; | |
541 bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE); | |
542 #ifdef OPENSSL_SYS_VMS | |
543 { | |
544 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); | |
545 bio_stdout = BIO_push(tmpbio, bio_stdout); | |
546 } | |
547 #endif | |
548 | |
549 if (!load_config(bio_err, NULL)) | |
550 goto end; | |
551 | |
552 if (list_type == FUNC_TYPE_PKEY) | |
553 list_pkey(bio_stdout); | |
554 if (list_type == FUNC_TYPE_MD_ALG) | |
555 list_md(bio_stdout); | |
556 if (list_type == FUNC_TYPE_CIPHER_ALG) | |
557 list_cipher(bio_stdout); | |
558 else | |
559 { | |
560 for (fp=functions; fp->name != NULL; fp++) | |
561 if (fp->type == list_type) | |
562 BIO_printf(bio_stdout, "%s\n", | |
563 fp->name); | |
564 } | |
565 BIO_free_all(bio_stdout); | |
566 ret=0; | |
567 goto end; | |
568 } | |
569 else | |
570 { | |
571 BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n
", | |
572 argv[0]); | |
573 BIO_printf(bio_err, "\nStandard commands"); | |
574 i=0; | |
575 tp=0; | |
576 for (fp=functions; fp->name != NULL; fp++) | |
577 { | |
578 nl=0; | |
579 #ifdef OPENSSL_NO_CAMELLIA | |
580 if (((i++) % 5) == 0) | |
581 #else | |
582 if (((i++) % 4) == 0) | |
583 #endif | |
584 { | |
585 BIO_printf(bio_err,"\n"); | |
586 nl=1; | |
587 } | |
588 if (fp->type != tp) | |
589 { | |
590 tp=fp->type; | |
591 if (!nl) BIO_printf(bio_err,"\n"); | |
592 if (tp == FUNC_TYPE_MD) | |
593 { | |
594 i=1; | |
595 BIO_printf(bio_err, | |
596 "\nMessage Digest commands (see
the `dgst' command for more details)\n"); | |
597 } | |
598 else if (tp == FUNC_TYPE_CIPHER) | |
599 { | |
600 i=1; | |
601 BIO_printf(bio_err,"\nCipher commands (s
ee the `enc' command for more details)\n"); | |
602 } | |
603 } | |
604 #ifdef OPENSSL_NO_CAMELLIA | |
605 BIO_printf(bio_err,"%-15s",fp->name); | |
606 #else | |
607 BIO_printf(bio_err,"%-18s",fp->name); | |
608 #endif | |
609 } | |
610 BIO_printf(bio_err,"\n\n"); | |
611 ret=0; | |
612 } | |
613 end: | |
614 return(ret); | |
615 } | |
616 | |
617 static int SortFnByName(const void *_f1,const void *_f2) | |
618 { | |
619 const FUNCTION *f1=_f1; | |
620 const FUNCTION *f2=_f2; | |
621 | |
622 if(f1->type != f2->type) | |
623 return f1->type-f2->type; | |
624 return strcmp(f1->name,f2->name); | |
625 } | |
626 | |
627 static void list_pkey(BIO *out) | |
628 { | |
629 int i; | |
630 for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) | |
631 { | |
632 const EVP_PKEY_ASN1_METHOD *ameth; | |
633 int pkey_id, pkey_base_id, pkey_flags; | |
634 const char *pinfo, *pem_str; | |
635 ameth = EVP_PKEY_asn1_get0(i); | |
636 EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, | |
637 &pinfo, &pem_str, ameth); | |
638 if (pkey_flags & ASN1_PKEY_ALIAS) | |
639 { | |
640 BIO_printf(out, "Name: %s\n", | |
641 OBJ_nid2ln(pkey_id)); | |
642 BIO_printf(out, "\tType: Alias to %s\n", | |
643 OBJ_nid2ln(pkey_base_id)); | |
644 } | |
645 else | |
646 { | |
647 BIO_printf(out, "Name: %s\n", pinfo); | |
648 BIO_printf(out, "\tType: %s Algorithm\n", | |
649 pkey_flags & ASN1_PKEY_DYNAMIC ? | |
650 "External" : "Builtin"); | |
651 BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); | |
652 if (pem_str == NULL) | |
653 pem_str = "(none)"; | |
654 BIO_printf(out, "\tPEM string: %s\n", pem_str); | |
655 } | |
656 | |
657 } | |
658 } | |
659 | |
660 static void list_cipher_fn(const EVP_CIPHER *c, | |
661 const char *from, const char *to, void *arg) | |
662 { | |
663 if (c) | |
664 BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); | |
665 else | |
666 { | |
667 if (!from) | |
668 from = "<undefined>"; | |
669 if (!to) | |
670 to = "<undefined>"; | |
671 BIO_printf(arg, "%s => %s\n", from, to); | |
672 } | |
673 } | |
674 | |
675 static void list_cipher(BIO *out) | |
676 { | |
677 EVP_CIPHER_do_all_sorted(list_cipher_fn, out); | |
678 } | |
679 | |
680 static void list_md_fn(const EVP_MD *m, | |
681 const char *from, const char *to, void *arg) | |
682 { | |
683 if (m) | |
684 BIO_printf(arg, "%s\n", EVP_MD_name(m)); | |
685 else | |
686 { | |
687 if (!from) | |
688 from = "<undefined>"; | |
689 if (!to) | |
690 to = "<undefined>"; | |
691 BIO_printf(arg, "%s => %s\n", from, to); | |
692 } | |
693 } | |
694 | |
695 static void list_md(BIO *out) | |
696 { | |
697 EVP_MD_do_all_sorted(list_md_fn, out); | |
698 } | |
699 | |
700 static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b) | |
701 { | |
702 return strncmp(a->name,b->name,8); | |
703 } | |
704 static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION) | |
705 | |
706 static unsigned long MS_CALLBACK function_hash(const FUNCTION *a) | |
707 { | |
708 return lh_strhash(a->name); | |
709 } | |
710 static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION) | |
711 | |
712 static LHASH_OF(FUNCTION) *prog_init(void) | |
713 { | |
714 LHASH_OF(FUNCTION) *ret; | |
715 FUNCTION *f; | |
716 size_t i; | |
717 | |
718 /* Purely so it looks nice when the user hits ? */ | |
719 for(i=0,f=functions ; f->name != NULL ; ++f,++i) | |
720 ; | |
721 qsort(functions,i,sizeof *functions,SortFnByName); | |
722 | |
723 if ((ret=lh_FUNCTION_new()) == NULL) | |
724 return(NULL); | |
725 | |
726 for (f=functions; f->name != NULL; f++) | |
727 (void)lh_FUNCTION_insert(ret,f); | |
728 return(ret); | |
729 } | |
730 | |
OLD | NEW |