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