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