1 /* 2 * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <internal/cryptlib.h> 11 #include <stdio.h> 12 #include <string.h> 13 #include <stdlib.h> 14 #include <openssl/bio.h> 15 #include <openssl/crypto.h> 16 #include <openssl/lhash.h> 17 #include <openssl/conf.h> 18 #include <openssl/x509.h> 19 #include <openssl/pem.h> 20 #include <openssl/ssl.h> 21 #ifndef OPENSSL_NO_ENGINE 22 # include <openssl/engine.h> 23 #endif 24 #include <openssl/err.h> 25 /* Needed to get the other O_xxx flags. */ 26 #ifdef OPENSSL_SYS_VMS 27 # include <unixio.h> 28 #endif 29 #include "apps.h" 30 #define INCLUDE_FUNCTION_TABLE 31 #include "progs.h" 32 33 /* Structure to hold the number of columns to be displayed and the 34 * field width used to display them. 35 */ 36 typedef struct { 37 int columns; 38 int width; 39 } DISPLAY_COLUMNS; 40 41 /* Special sentinel to exit the program. */ 42 #define EXIT_THE_PROGRAM (-1) 43 44 /* 45 * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with 46 * the base prototypes (we cast each variable inside the function to the 47 * required type of "FUNCTION*"). This removes the necessity for 48 * macro-generated wrapper functions. 49 */ 50 static LHASH_OF(FUNCTION) *prog_init(void); 51 static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]); 52 static void list_pkey(void); 53 static void list_pkey_meth(void); 54 static void list_type(FUNC_TYPE ft, int one); 55 static void list_disabled(void); 56 char *default_config_file = NULL; 57 58 BIO *bio_in = NULL; 59 BIO *bio_out = NULL; 60 BIO *bio_err = NULL; 61 62 static void calculate_columns(DISPLAY_COLUMNS *dc) 63 { 64 FUNCTION *f; 65 int len, maxlen = 0; 66 67 for (f = functions; f->name != NULL; ++f) 68 if (f->type == FT_general || f->type == FT_md || f->type == FT_cipher) 69 if ((len = strlen(f->name)) > maxlen) 70 maxlen = len; 71 72 dc->width = maxlen + 2; 73 dc->columns = (80 - 1) / dc->width; 74 } 75 76 static int apps_startup(void) 77 { 78 #ifdef SIGPIPE 79 signal(SIGPIPE, SIG_IGN); 80 #endif 81 82 /* Set non-default library initialisation settings */ 83 if (!OPENSSL_init_ssl(OPENSSL_INIT_ENGINE_ALL_BUILTIN 84 | OPENSSL_INIT_LOAD_CONFIG, NULL)) 85 return 0; 86 87 setup_ui_method(); 88 89 return 1; 90 } 91 92 static void apps_shutdown(void) 93 { 94 destroy_ui_method(); 95 destroy_prefix_method(); 96 } 97 98 static char *make_config_name(void) 99 { 100 const char *t; 101 size_t len; 102 char *p; 103 104 if ((t = getenv("OPENSSL_CONF")) != NULL) 105 return OPENSSL_strdup(t); 106 107 t = X509_get_default_cert_area(); 108 len = strlen(t) + 1 + strlen(OPENSSL_CONF) + 1; 109 p = app_malloc(len, "config filename buffer"); 110 strcpy(p, t); 111 #ifndef OPENSSL_SYS_VMS 112 strcat(p, "/"); 113 #endif 114 strcat(p, OPENSSL_CONF); 115 116 return p; 117 } 118 119 int main(int argc, char *argv[]) 120 { 121 FUNCTION f, *fp; 122 LHASH_OF(FUNCTION) *prog = NULL; 123 char **copied_argv = NULL; 124 char *p, *pname; 125 char buf[1024]; 126 const char *prompt; 127 ARGS arg; 128 int first, n, i, ret = 0; 129 130 arg.argv = NULL; 131 arg.size = 0; 132 133 /* Set up some of the environment. */ 134 default_config_file = make_config_name(); 135 bio_in = dup_bio_in(FORMAT_TEXT); 136 bio_out = dup_bio_out(FORMAT_TEXT); 137 bio_err = dup_bio_err(FORMAT_TEXT); 138 139 #if defined(OPENSSL_SYS_VMS) && defined(__DECC) 140 copied_argv = argv = copy_argv(&argc, argv); 141 #elif defined(_WIN32) 142 /* 143 * Replace argv[] with UTF-8 encoded strings. 144 */ 145 win32_utf8argv(&argc, &argv); 146 #endif 147 148 p = getenv("OPENSSL_DEBUG_MEMORY"); 149 if (p != NULL && strcmp(p, "on") == 0) 150 CRYPTO_set_mem_debug(1); 151 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 152 153 if (getenv("OPENSSL_FIPS")) { 154 BIO_printf(bio_err, "FIPS mode not supported.\n"); 155 return 1; 156 } 157 158 if (!apps_startup()) { 159 BIO_printf(bio_err, 160 "FATAL: Startup failure (dev note: apps_startup() failed)\n"); 161 ERR_print_errors(bio_err); 162 ret = 1; 163 goto end; 164 } 165 166 prog = prog_init(); 167 if (prog == NULL) { 168 BIO_printf(bio_err, 169 "FATAL: Startup failure (dev note: prog_init() failed)\n"); 170 ERR_print_errors(bio_err); 171 ret = 1; 172 goto end; 173 } 174 pname = opt_progname(argv[0]); 175 176 /* first check the program name */ 177 f.name = pname; 178 fp = lh_FUNCTION_retrieve(prog, &f); 179 if (fp != NULL) { 180 argv[0] = pname; 181 ret = fp->func(argc, argv); 182 goto end; 183 } 184 185 /* If there is stuff on the command line, run with that. */ 186 if (argc != 1) { 187 argc--; 188 argv++; 189 ret = do_cmd(prog, argc, argv); 190 if (ret < 0) 191 ret = 0; 192 goto end; 193 } 194 195 /* ok, lets enter interactive mode */ 196 for (;;) { 197 ret = 0; 198 /* Read a line, continue reading if line ends with \ */ 199 for (p = buf, n = sizeof(buf), i = 0, first = 1; n > 0; first = 0) { 200 prompt = first ? "OpenSSL> " : "> "; 201 p[0] = '\0'; 202 #ifndef READLINE 203 fputs(prompt, stdout); 204 fflush(stdout); 205 if (!fgets(p, n, stdin)) 206 goto end; 207 if (p[0] == '\0') 208 goto end; 209 i = strlen(p); 210 if (i <= 1) 211 break; 212 if (p[i - 2] != '\\') 213 break; 214 i -= 2; 215 p += i; 216 n -= i; 217 #else 218 { 219 extern char *readline(const char *); 220 extern void add_history(const char *cp); 221 char *text; 222 223 text = readline(prompt); 224 if (text == NULL) 225 goto end; 226 i = strlen(text); 227 if (i == 0 || i > n) 228 break; 229 if (text[i - 1] != '\\') { 230 p += strlen(strcpy(p, text)); 231 free(text); 232 add_history(buf); 233 break; 234 } 235 236 text[i - 1] = '\0'; 237 p += strlen(strcpy(p, text)); 238 free(text); 239 n -= i; 240 } 241 #endif 242 } 243 244 if (!chopup_args(&arg, buf)) { 245 BIO_printf(bio_err, "Can't parse (no memory?)\n"); 246 break; 247 } 248 249 ret = do_cmd(prog, arg.argc, arg.argv); 250 if (ret == EXIT_THE_PROGRAM) { 251 ret = 0; 252 goto end; 253 } 254 if (ret != 0) 255 BIO_printf(bio_err, "error in %s\n", arg.argv[0]); 256 (void)BIO_flush(bio_out); 257 (void)BIO_flush(bio_err); 258 } 259 ret = 1; 260 end: 261 OPENSSL_free(copied_argv); 262 OPENSSL_free(default_config_file); 263 lh_FUNCTION_free(prog); 264 OPENSSL_free(arg.argv); 265 app_RAND_write(); 266 267 BIO_free(bio_in); 268 BIO_free_all(bio_out); 269 apps_shutdown(); 270 #ifndef OPENSSL_NO_CRYPTO_MDEBUG 271 if (CRYPTO_mem_leaks(bio_err) <= 0) 272 ret = 1; 273 #endif 274 BIO_free(bio_err); 275 EXIT(ret); 276 } 277 278 static void list_cipher_fn(const EVP_CIPHER *c, 279 const char *from, const char *to, void *arg) 280 { 281 if (c != NULL) { 282 BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); 283 } else { 284 if (from == NULL) 285 from = "<undefined>"; 286 if (to == NULL) 287 to = "<undefined>"; 288 BIO_printf(arg, "%s => %s\n", from, to); 289 } 290 } 291 292 static void list_md_fn(const EVP_MD *m, 293 const char *from, const char *to, void *arg) 294 { 295 if (m != NULL) { 296 BIO_printf(arg, "%s\n", EVP_MD_name(m)); 297 } else { 298 if (from == NULL) 299 from = "<undefined>"; 300 if (to == NULL) 301 to = "<undefined>"; 302 BIO_printf((BIO *)arg, "%s => %s\n", from, to); 303 } 304 } 305 306 static void list_missing_help(void) 307 { 308 const FUNCTION *fp; 309 const OPTIONS *o; 310 311 for (fp = functions; fp->name != NULL; fp++) { 312 if ((o = fp->help) != NULL) { 313 /* If there is help, list what flags are not documented. */ 314 for ( ; o->name != NULL; o++) { 315 if (o->helpstr == NULL) 316 BIO_printf(bio_out, "%s %s\n", fp->name, o->name); 317 } 318 } else if (fp->func != dgst_main) { 319 /* If not aliased to the dgst command, */ 320 BIO_printf(bio_out, "%s *\n", fp->name); 321 } 322 } 323 } 324 325 static void list_options_for_command(const char *command) 326 { 327 const FUNCTION *fp; 328 const OPTIONS *o; 329 330 for (fp = functions; fp->name != NULL; fp++) 331 if (strcmp(fp->name, command) == 0) 332 break; 333 if (fp->name == NULL) { 334 BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", 335 command); 336 return; 337 } 338 339 if ((o = fp->help) == NULL) 340 return; 341 342 for ( ; o->name != NULL; o++) { 343 if (o->name == OPT_HELP_STR 344 || o->name == OPT_MORE_STR 345 || o->name[0] == '\0') 346 continue; 347 BIO_printf(bio_out, "%s %c\n", o->name, o->valtype); 348 } 349 } 350 351 352 /* Unified enum for help and list commands. */ 353 typedef enum HELPLIST_CHOICE { 354 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE, 355 OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_OPTIONS, 356 OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, 357 OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, OPT_MISSING_HELP 358 } HELPLIST_CHOICE; 359 360 const OPTIONS list_options[] = { 361 {"help", OPT_HELP, '-', "Display this summary"}, 362 {"1", OPT_ONE, '-', "List in one column"}, 363 {"commands", OPT_COMMANDS, '-', "List of standard commands"}, 364 {"digest-commands", OPT_DIGEST_COMMANDS, '-', 365 "List of message digest commands"}, 366 {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', 367 "List of message digest algorithms"}, 368 {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, 369 {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', 370 "List of cipher algorithms"}, 371 {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', 372 "List of public key algorithms"}, 373 {"public-key-methods", OPT_PK_METHOD, '-', 374 "List of public key methods"}, 375 {"disabled", OPT_DISABLED, '-', 376 "List of disabled features"}, 377 {"missing-help", OPT_MISSING_HELP, '-', 378 "List missing detailed help strings"}, 379 {"options", OPT_OPTIONS, 's', 380 "List options for specified command"}, 381 {NULL} 382 }; 383 384 int list_main(int argc, char **argv) 385 { 386 char *prog; 387 HELPLIST_CHOICE o; 388 int one = 0, done = 0; 389 390 prog = opt_init(argc, argv, list_options); 391 while ((o = opt_next()) != OPT_EOF) { 392 switch (o) { 393 case OPT_EOF: /* Never hit, but suppresses warning */ 394 case OPT_ERR: 395 opthelp: 396 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 397 return 1; 398 case OPT_HELP: 399 opt_help(list_options); 400 break; 401 case OPT_ONE: 402 one = 1; 403 break; 404 case OPT_COMMANDS: 405 list_type(FT_general, one); 406 break; 407 case OPT_DIGEST_COMMANDS: 408 list_type(FT_md, one); 409 break; 410 case OPT_DIGEST_ALGORITHMS: 411 EVP_MD_do_all_sorted(list_md_fn, bio_out); 412 break; 413 case OPT_CIPHER_COMMANDS: 414 list_type(FT_cipher, one); 415 break; 416 case OPT_CIPHER_ALGORITHMS: 417 EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); 418 break; 419 case OPT_PK_ALGORITHMS: 420 list_pkey(); 421 break; 422 case OPT_PK_METHOD: 423 list_pkey_meth(); 424 break; 425 case OPT_DISABLED: 426 list_disabled(); 427 break; 428 case OPT_MISSING_HELP: 429 list_missing_help(); 430 break; 431 case OPT_OPTIONS: 432 list_options_for_command(opt_arg()); 433 break; 434 } 435 done = 1; 436 } 437 if (opt_num_rest() != 0) { 438 BIO_printf(bio_err, "Extra arguments given.\n"); 439 goto opthelp; 440 } 441 442 if (!done) 443 goto opthelp; 444 445 return 0; 446 } 447 448 typedef enum HELP_CHOICE { 449 OPT_hERR = -1, OPT_hEOF = 0, OPT_hHELP 450 } HELP_CHOICE; 451 452 const OPTIONS help_options[] = { 453 {OPT_HELP_STR, 1, '-', "Usage: help [options]\n"}, 454 {OPT_HELP_STR, 1, '-', " help [command]\n"}, 455 {"help", OPT_hHELP, '-', "Display this summary"}, 456 {NULL} 457 }; 458 459 460 int help_main(int argc, char **argv) 461 { 462 FUNCTION *fp; 463 int i, nl; 464 FUNC_TYPE tp; 465 char *prog; 466 HELP_CHOICE o; 467 DISPLAY_COLUMNS dc; 468 469 prog = opt_init(argc, argv, help_options); 470 while ((o = opt_next()) != OPT_hEOF) { 471 switch (o) { 472 case OPT_hERR: 473 case OPT_hEOF: 474 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 475 return 1; 476 case OPT_hHELP: 477 opt_help(help_options); 478 return 0; 479 } 480 } 481 482 if (opt_num_rest() == 1) { 483 char *new_argv[3]; 484 485 new_argv[0] = opt_rest()[0]; 486 new_argv[1] = "--help"; 487 new_argv[2] = NULL; 488 return do_cmd(prog_init(), 2, new_argv); 489 } 490 if (opt_num_rest() != 0) { 491 BIO_printf(bio_err, "Usage: %s\n", prog); 492 return 1; 493 } 494 495 calculate_columns(&dc); 496 BIO_printf(bio_err, "Standard commands"); 497 i = 0; 498 tp = FT_none; 499 for (fp = functions; fp->name != NULL; fp++) { 500 nl = 0; 501 if (i++ % dc.columns == 0) { 502 BIO_printf(bio_err, "\n"); 503 nl = 1; 504 } 505 if (fp->type != tp) { 506 tp = fp->type; 507 if (!nl) 508 BIO_printf(bio_err, "\n"); 509 if (tp == FT_md) { 510 i = 1; 511 BIO_printf(bio_err, 512 "\nMessage Digest commands (see the `dgst' command for more details)\n"); 513 } else if (tp == FT_cipher) { 514 i = 1; 515 BIO_printf(bio_err, 516 "\nCipher commands (see the `enc' command for more details)\n"); 517 } 518 } 519 BIO_printf(bio_err, "%-*s", dc.width, fp->name); 520 } 521 BIO_printf(bio_err, "\n\n"); 522 return 0; 523 } 524 525 static void list_type(FUNC_TYPE ft, int one) 526 { 527 FUNCTION *fp; 528 int i = 0; 529 DISPLAY_COLUMNS dc = {0}; 530 531 if (!one) 532 calculate_columns(&dc); 533 534 for (fp = functions; fp->name != NULL; fp++) { 535 if (fp->type != ft) 536 continue; 537 if (one) { 538 BIO_printf(bio_out, "%s\n", fp->name); 539 } else { 540 if (i % dc.columns == 0 && i > 0) 541 BIO_printf(bio_out, "\n"); 542 BIO_printf(bio_out, "%-*s", dc.width, fp->name); 543 i++; 544 } 545 } 546 if (!one) 547 BIO_printf(bio_out, "\n\n"); 548 } 549 550 static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) 551 { 552 FUNCTION f, *fp; 553 554 if (argc <= 0 || argv[0] == NULL) 555 return 0; 556 f.name = argv[0]; 557 fp = lh_FUNCTION_retrieve(prog, &f); 558 if (fp == NULL) { 559 if (EVP_get_digestbyname(argv[0])) { 560 f.type = FT_md; 561 f.func = dgst_main; 562 fp = &f; 563 } else if (EVP_get_cipherbyname(argv[0])) { 564 f.type = FT_cipher; 565 f.func = enc_main; 566 fp = &f; 567 } 568 } 569 if (fp != NULL) { 570 return fp->func(argc, argv); 571 } 572 if ((strncmp(argv[0], "no-", 3)) == 0) { 573 /* 574 * User is asking if foo is unsupported, by trying to "run" the 575 * no-foo command. Strange. 576 */ 577 f.name = argv[0] + 3; 578 if (lh_FUNCTION_retrieve(prog, &f) == NULL) { 579 BIO_printf(bio_out, "%s\n", argv[0]); 580 return 0; 581 } 582 BIO_printf(bio_out, "%s\n", argv[0] + 3); 583 return 1; 584 } 585 if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 || 586 strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0) 587 /* Special value to mean "exit the program. */ 588 return EXIT_THE_PROGRAM; 589 590 BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", 591 argv[0]); 592 return 1; 593 } 594 595 static void list_pkey(void) 596 { 597 int i; 598 599 for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { 600 const EVP_PKEY_ASN1_METHOD *ameth; 601 int pkey_id, pkey_base_id, pkey_flags; 602 const char *pinfo, *pem_str; 603 ameth = EVP_PKEY_asn1_get0(i); 604 EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, 605 &pinfo, &pem_str, ameth); 606 if (pkey_flags & ASN1_PKEY_ALIAS) { 607 BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); 608 BIO_printf(bio_out, "\tAlias for: %s\n", 609 OBJ_nid2ln(pkey_base_id)); 610 } else { 611 BIO_printf(bio_out, "Name: %s\n", pinfo); 612 BIO_printf(bio_out, "\tType: %s Algorithm\n", 613 pkey_flags & ASN1_PKEY_DYNAMIC ? 614 "External" : "Builtin"); 615 BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); 616 if (pem_str == NULL) 617 pem_str = "(none)"; 618 BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); 619 } 620 621 } 622 } 623 624 static void list_pkey_meth(void) 625 { 626 size_t i; 627 size_t meth_count = EVP_PKEY_meth_get_count(); 628 629 for (i = 0; i < meth_count; i++) { 630 const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); 631 int pkey_id, pkey_flags; 632 633 EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); 634 BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id)); 635 BIO_printf(bio_out, "\tType: %s Algorithm\n", 636 pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); 637 } 638 } 639 640 static int function_cmp(const FUNCTION * a, const FUNCTION * b) 641 { 642 return strncmp(a->name, b->name, 8); 643 } 644 645 static unsigned long function_hash(const FUNCTION * a) 646 { 647 return OPENSSL_LH_strhash(a->name); 648 } 649 650 static int SortFnByName(const void *_f1, const void *_f2) 651 { 652 const FUNCTION *f1 = _f1; 653 const FUNCTION *f2 = _f2; 654 655 if (f1->type != f2->type) 656 return f1->type - f2->type; 657 return strcmp(f1->name, f2->name); 658 } 659 660 static void list_disabled(void) 661 { 662 BIO_puts(bio_out, "Disabled algorithms:\n"); 663 #ifdef OPENSSL_NO_ARIA 664 BIO_puts(bio_out, "ARIA\n"); 665 #endif 666 #ifdef OPENSSL_NO_BF 667 BIO_puts(bio_out, "BF\n"); 668 #endif 669 #ifdef OPENSSL_NO_BLAKE2 670 BIO_puts(bio_out, "BLAKE2\n"); 671 #endif 672 #ifdef OPENSSL_NO_CAMELLIA 673 BIO_puts(bio_out, "CAMELLIA\n"); 674 #endif 675 #ifdef OPENSSL_NO_CAST 676 BIO_puts(bio_out, "CAST\n"); 677 #endif 678 #ifdef OPENSSL_NO_CMAC 679 BIO_puts(bio_out, "CMAC\n"); 680 #endif 681 #ifdef OPENSSL_NO_CMS 682 BIO_puts(bio_out, "CMS\n"); 683 #endif 684 #ifdef OPENSSL_NO_COMP 685 BIO_puts(bio_out, "COMP\n"); 686 #endif 687 #ifdef OPENSSL_NO_DES 688 BIO_puts(bio_out, "DES\n"); 689 #endif 690 #ifdef OPENSSL_NO_DGRAM 691 BIO_puts(bio_out, "DGRAM\n"); 692 #endif 693 #ifdef OPENSSL_NO_DH 694 BIO_puts(bio_out, "DH\n"); 695 #endif 696 #ifdef OPENSSL_NO_DSA 697 BIO_puts(bio_out, "DSA\n"); 698 #endif 699 #if defined(OPENSSL_NO_DTLS) 700 BIO_puts(bio_out, "DTLS\n"); 701 #endif 702 #if defined(OPENSSL_NO_DTLS1) 703 BIO_puts(bio_out, "DTLS1\n"); 704 #endif 705 #if defined(OPENSSL_NO_DTLS1_2) 706 BIO_puts(bio_out, "DTLS1_2\n"); 707 #endif 708 #ifdef OPENSSL_NO_EC 709 BIO_puts(bio_out, "EC\n"); 710 #endif 711 #ifdef OPENSSL_NO_EC2M 712 BIO_puts(bio_out, "EC2M\n"); 713 #endif 714 #ifdef OPENSSL_NO_ENGINE 715 BIO_puts(bio_out, "ENGINE\n"); 716 #endif 717 #ifdef OPENSSL_NO_GOST 718 BIO_puts(bio_out, "GOST\n"); 719 #endif 720 #ifdef OPENSSL_NO_HEARTBEATS 721 BIO_puts(bio_out, "HEARTBEATS\n"); 722 #endif 723 #ifdef OPENSSL_NO_IDEA 724 BIO_puts(bio_out, "IDEA\n"); 725 #endif 726 #ifdef OPENSSL_NO_MD2 727 BIO_puts(bio_out, "MD2\n"); 728 #endif 729 #ifdef OPENSSL_NO_MD4 730 BIO_puts(bio_out, "MD4\n"); 731 #endif 732 #ifdef OPENSSL_NO_MD5 733 BIO_puts(bio_out, "MD5\n"); 734 #endif 735 #ifdef OPENSSL_NO_MDC2 736 BIO_puts(bio_out, "MDC2\n"); 737 #endif 738 #ifdef OPENSSL_NO_OCB 739 BIO_puts(bio_out, "OCB\n"); 740 #endif 741 #ifdef OPENSSL_NO_OCSP 742 BIO_puts(bio_out, "OCSP\n"); 743 #endif 744 #ifdef OPENSSL_NO_PSK 745 BIO_puts(bio_out, "PSK\n"); 746 #endif 747 #ifdef OPENSSL_NO_RC2 748 BIO_puts(bio_out, "RC2\n"); 749 #endif 750 #ifdef OPENSSL_NO_RC4 751 BIO_puts(bio_out, "RC4\n"); 752 #endif 753 #ifdef OPENSSL_NO_RC5 754 BIO_puts(bio_out, "RC5\n"); 755 #endif 756 #ifdef OPENSSL_NO_RMD160 757 BIO_puts(bio_out, "RMD160\n"); 758 #endif 759 #ifdef OPENSSL_NO_RSA 760 BIO_puts(bio_out, "RSA\n"); 761 #endif 762 #ifdef OPENSSL_NO_SCRYPT 763 BIO_puts(bio_out, "SCRYPT\n"); 764 #endif 765 #ifdef OPENSSL_NO_SCTP 766 BIO_puts(bio_out, "SCTP\n"); 767 #endif 768 #ifdef OPENSSL_NO_SEED 769 BIO_puts(bio_out, "SEED\n"); 770 #endif 771 #ifdef OPENSSL_NO_SM2 772 BIO_puts(bio_out, "SM2\n"); 773 #endif 774 #ifdef OPENSSL_NO_SM3 775 BIO_puts(bio_out, "SM3\n"); 776 #endif 777 #ifdef OPENSSL_NO_SM4 778 BIO_puts(bio_out, "SM4\n"); 779 #endif 780 #ifdef OPENSSL_NO_SOCK 781 BIO_puts(bio_out, "SOCK\n"); 782 #endif 783 #ifdef OPENSSL_NO_SRP 784 BIO_puts(bio_out, "SRP\n"); 785 #endif 786 #ifdef OPENSSL_NO_SRTP 787 BIO_puts(bio_out, "SRTP\n"); 788 #endif 789 #ifdef OPENSSL_NO_SSL3 790 BIO_puts(bio_out, "SSL3\n"); 791 #endif 792 #ifdef OPENSSL_NO_TLS1 793 BIO_puts(bio_out, "TLS1\n"); 794 #endif 795 #ifdef OPENSSL_NO_TLS1_1 796 BIO_puts(bio_out, "TLS1_1\n"); 797 #endif 798 #ifdef OPENSSL_NO_TLS1_2 799 BIO_puts(bio_out, "TLS1_2\n"); 800 #endif 801 #ifdef OPENSSL_NO_WHIRLPOOL 802 BIO_puts(bio_out, "WHIRLPOOL\n"); 803 #endif 804 #ifndef ZLIB 805 BIO_puts(bio_out, "ZLIB\n"); 806 #endif 807 } 808 809 static LHASH_OF(FUNCTION) *prog_init(void) 810 { 811 static LHASH_OF(FUNCTION) *ret = NULL; 812 static int prog_inited = 0; 813 FUNCTION *f; 814 size_t i; 815 816 if (prog_inited) 817 return ret; 818 819 prog_inited = 1; 820 821 /* Sort alphabetically within category. For nicer help displays. */ 822 for (i = 0, f = functions; f->name != NULL; ++f, ++i) 823 ; 824 qsort(functions, i, sizeof(*functions), SortFnByName); 825 826 if ((ret = lh_FUNCTION_new(function_hash, function_cmp)) == NULL) 827 return NULL; 828 829 for (f = functions; f->name != NULL; f++) 830 (void)lh_FUNCTION_insert(ret, f); 831 return ret; 832 } 833