Home | History | Annotate | Line # | Download | only in apps
      1 /*
      2  * Copyright 1995-2021 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 <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 #include "apps.h"
     14 #include "progs.h"
     15 #include <openssl/err.h>
     16 #include <openssl/ssl.h>
     17 
     18 typedef enum OPTION_choice {
     19     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     20     OPT_STDNAME,
     21     OPT_CONVERT,
     22     OPT_SSL3,
     23     OPT_TLS1,
     24     OPT_TLS1_1,
     25     OPT_TLS1_2,
     26     OPT_TLS1_3,
     27     OPT_PSK,
     28     OPT_SRP,
     29     OPT_CIPHERSUITES,
     30     OPT_V, OPT_UPPER_V, OPT_S
     31 } OPTION_CHOICE;
     32 
     33 const OPTIONS ciphers_options[] = {
     34     {"help", OPT_HELP, '-', "Display this summary"},
     35     {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"},
     36     {"V", OPT_UPPER_V, '-', "Even more verbose"},
     37     {"s", OPT_S, '-', "Only supported ciphers"},
     38 #ifndef OPENSSL_NO_SSL3
     39     {"ssl3", OPT_SSL3, '-', "SSL3 mode"},
     40 #endif
     41 #ifndef OPENSSL_NO_TLS1
     42     {"tls1", OPT_TLS1, '-', "TLS1 mode"},
     43 #endif
     44 #ifndef OPENSSL_NO_TLS1_1
     45     {"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"},
     46 #endif
     47 #ifndef OPENSSL_NO_TLS1_2
     48     {"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"},
     49 #endif
     50 #ifndef OPENSSL_NO_TLS1_3
     51     {"tls1_3", OPT_TLS1_3, '-', "TLS1.3 mode"},
     52 #endif
     53     {"stdname", OPT_STDNAME, '-', "Show standard cipher names"},
     54 #ifndef OPENSSL_NO_PSK
     55     {"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"},
     56 #endif
     57 #ifndef OPENSSL_NO_SRP
     58     {"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"},
     59 #endif
     60     {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"},
     61     {"ciphersuites", OPT_CIPHERSUITES, 's',
     62      "Configure the TLSv1.3 ciphersuites to use"},
     63     {NULL}
     64 };
     65 
     66 #ifndef OPENSSL_NO_PSK
     67 static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity,
     68                               unsigned int max_identity_len,
     69                               unsigned char *psk,
     70                               unsigned int max_psk_len)
     71 {
     72     return 0;
     73 }
     74 #endif
     75 #ifndef OPENSSL_NO_SRP
     76 static char *dummy_srp(SSL *ssl, void *arg)
     77 {
     78     return "";
     79 }
     80 #endif
     81 
     82 int ciphers_main(int argc, char **argv)
     83 {
     84     SSL_CTX *ctx = NULL;
     85     SSL *ssl = NULL;
     86     STACK_OF(SSL_CIPHER) *sk = NULL;
     87     const SSL_METHOD *meth = TLS_server_method();
     88     int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0;
     89     int stdname = 0;
     90 #ifndef OPENSSL_NO_PSK
     91     int psk = 0;
     92 #endif
     93 #ifndef OPENSSL_NO_SRP
     94     int srp = 0;
     95 #endif
     96     const char *p;
     97     char *ciphers = NULL, *prog, *convert = NULL, *ciphersuites = NULL;
     98     char buf[512];
     99     OPTION_CHOICE o;
    100     int min_version = 0, max_version = 0;
    101 
    102     prog = opt_init(argc, argv, ciphers_options);
    103     while ((o = opt_next()) != OPT_EOF) {
    104         switch (o) {
    105         case OPT_EOF:
    106         case OPT_ERR:
    107  opthelp:
    108             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
    109             goto end;
    110         case OPT_HELP:
    111             opt_help(ciphers_options);
    112             ret = 0;
    113             goto end;
    114         case OPT_V:
    115             verbose = 1;
    116             break;
    117         case OPT_UPPER_V:
    118             verbose = Verbose = 1;
    119             break;
    120         case OPT_S:
    121             use_supported = 1;
    122             break;
    123         case OPT_STDNAME:
    124             stdname = verbose = 1;
    125             break;
    126         case OPT_CONVERT:
    127             convert = opt_arg();
    128             break;
    129         case OPT_SSL3:
    130             min_version = SSL3_VERSION;
    131             max_version = SSL3_VERSION;
    132             break;
    133         case OPT_TLS1:
    134             min_version = TLS1_VERSION;
    135             max_version = TLS1_VERSION;
    136             break;
    137         case OPT_TLS1_1:
    138             min_version = TLS1_1_VERSION;
    139             max_version = TLS1_1_VERSION;
    140             break;
    141         case OPT_TLS1_2:
    142             min_version = TLS1_2_VERSION;
    143             max_version = TLS1_2_VERSION;
    144             break;
    145         case OPT_TLS1_3:
    146             min_version = TLS1_3_VERSION;
    147             max_version = TLS1_3_VERSION;
    148             break;
    149         case OPT_PSK:
    150 #ifndef OPENSSL_NO_PSK
    151             psk = 1;
    152 #endif
    153             break;
    154         case OPT_SRP:
    155 #ifndef OPENSSL_NO_SRP
    156             srp = 1;
    157 #endif
    158             break;
    159         case OPT_CIPHERSUITES:
    160             ciphersuites = opt_arg();
    161             break;
    162         }
    163     }
    164     argv = opt_rest();
    165     argc = opt_num_rest();
    166 
    167     if (argc == 1)
    168         ciphers = *argv;
    169     else if (argc != 0)
    170         goto opthelp;
    171 
    172     if (convert != NULL) {
    173         BIO_printf(bio_out, "OpenSSL cipher name: %s\n",
    174                    OPENSSL_cipher_name(convert));
    175         ret = 0;
    176         goto end;
    177     }
    178 
    179     ctx = SSL_CTX_new(meth);
    180     if (ctx == NULL)
    181         goto err;
    182     if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
    183         goto err;
    184     if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
    185         goto err;
    186 
    187 #ifndef OPENSSL_NO_PSK
    188     if (psk)
    189         SSL_CTX_set_psk_client_callback(ctx, dummy_psk);
    190 #endif
    191 #ifndef OPENSSL_NO_SRP
    192     if (srp)
    193         SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp);
    194 #endif
    195 
    196     if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) {
    197         BIO_printf(bio_err, "Error setting TLSv1.3 ciphersuites\n");
    198         goto err;
    199     }
    200 
    201     if (ciphers != NULL) {
    202         if (!SSL_CTX_set_cipher_list(ctx, ciphers)) {
    203             BIO_printf(bio_err, "Error in cipher list\n");
    204             goto err;
    205         }
    206     }
    207     ssl = SSL_new(ctx);
    208     if (ssl == NULL)
    209         goto err;
    210 
    211     if (use_supported)
    212         sk = SSL_get1_supported_ciphers(ssl);
    213     else
    214         sk = SSL_get_ciphers(ssl);
    215 
    216     if (!verbose) {
    217         for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
    218             const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
    219             p = SSL_CIPHER_get_name(c);
    220             if (p == NULL)
    221                 break;
    222             if (i != 0)
    223                 BIO_printf(bio_out, ":");
    224             BIO_printf(bio_out, "%s", p);
    225         }
    226         BIO_printf(bio_out, "\n");
    227     } else {
    228 
    229         for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
    230             const SSL_CIPHER *c;
    231 
    232             c = sk_SSL_CIPHER_value(sk, i);
    233 
    234             if (Verbose) {
    235                 unsigned long id = SSL_CIPHER_get_id(c);
    236                 int id0 = (int)(id >> 24);
    237                 int id1 = (int)((id >> 16) & 0xffL);
    238                 int id2 = (int)((id >> 8) & 0xffL);
    239                 int id3 = (int)(id & 0xffL);
    240 
    241                 if ((id & 0xff000000L) == 0x03000000L)
    242                     BIO_printf(bio_out, "          0x%02X,0x%02X - ", id2, id3); /* SSL3
    243                                                                                   * cipher */
    244                 else
    245                     BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
    246             }
    247             if (stdname) {
    248                 const char *nm = SSL_CIPHER_standard_name(c);
    249                 if (nm == NULL)
    250                     nm = "UNKNOWN";
    251                 BIO_printf(bio_out, "%s - ", nm);
    252             }
    253             BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf)));
    254         }
    255     }
    256 
    257     ret = 0;
    258     goto end;
    259  err:
    260     ERR_print_errors(bio_err);
    261  end:
    262     if (use_supported)
    263         sk_SSL_CIPHER_free(sk);
    264     SSL_CTX_free(ctx);
    265     SSL_free(ssl);
    266     return ret;
    267 }
    268