1e71b7053SJung-uk Kim /* 2e71b7053SJung-uk Kim * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 874664626SKris Kennaway */ 974664626SKris Kennaway 1074664626SKris Kennaway #include <stdio.h> 1174664626SKris Kennaway #include <stdlib.h> 1274664626SKris Kennaway #include <string.h> 1374664626SKris Kennaway #include "apps.h" 14e71b7053SJung-uk Kim #include "progs.h" 1574664626SKris Kennaway #include <openssl/err.h> 1674664626SKris Kennaway #include <openssl/ssl.h> 1774664626SKris Kennaway 18e71b7053SJung-uk Kim typedef enum OPTION_choice { 19e71b7053SJung-uk Kim OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 20e71b7053SJung-uk Kim OPT_STDNAME, 21e71b7053SJung-uk Kim OPT_CONVERT, 22e71b7053SJung-uk Kim OPT_SSL3, 23e71b7053SJung-uk Kim OPT_TLS1, 24e71b7053SJung-uk Kim OPT_TLS1_1, 25e71b7053SJung-uk Kim OPT_TLS1_2, 26e71b7053SJung-uk Kim OPT_TLS1_3, 27e71b7053SJung-uk Kim OPT_PSK, 28e71b7053SJung-uk Kim OPT_SRP, 29e71b7053SJung-uk Kim OPT_CIPHERSUITES, 30e71b7053SJung-uk Kim OPT_V, OPT_UPPER_V, OPT_S 31e71b7053SJung-uk Kim } OPTION_CHOICE; 3274664626SKris Kennaway 33e71b7053SJung-uk Kim const OPTIONS ciphers_options[] = { 34e71b7053SJung-uk Kim {"help", OPT_HELP, '-', "Display this summary"}, 35e71b7053SJung-uk Kim {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, 36e71b7053SJung-uk Kim {"V", OPT_UPPER_V, '-', "Even more verbose"}, 37e71b7053SJung-uk Kim {"s", OPT_S, '-', "Only supported ciphers"}, 385c87c606SMark Murray #ifndef OPENSSL_NO_SSL3 39e71b7053SJung-uk Kim {"ssl3", OPT_SSL3, '-', "SSL3 mode"}, 4074664626SKris Kennaway #endif 415c87c606SMark Murray #ifndef OPENSSL_NO_TLS1 42e71b7053SJung-uk Kim {"tls1", OPT_TLS1, '-', "TLS1 mode"}, 43ddd58736SKris Kennaway #endif 44e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_1 45e71b7053SJung-uk Kim {"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"}, 46e71b7053SJung-uk Kim #endif 47e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_2 48e71b7053SJung-uk Kim {"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"}, 49e71b7053SJung-uk Kim #endif 50e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_3 51e71b7053SJung-uk Kim {"tls1_3", OPT_TLS1_3, '-', "TLS1.3 mode"}, 52e71b7053SJung-uk Kim #endif 53e71b7053SJung-uk Kim {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, 54e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 55e71b7053SJung-uk Kim {"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"}, 56e71b7053SJung-uk Kim #endif 57e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 58e71b7053SJung-uk Kim {"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"}, 59e71b7053SJung-uk Kim #endif 60e71b7053SJung-uk Kim {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, 61e71b7053SJung-uk Kim {"ciphersuites", OPT_CIPHERSUITES, 's', 62e71b7053SJung-uk Kim "Configure the TLSv1.3 ciphersuites to use"}, 63e71b7053SJung-uk Kim {NULL} 64e71b7053SJung-uk Kim }; 6574664626SKris Kennaway 66e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 67e71b7053SJung-uk Kim static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity, 68e71b7053SJung-uk Kim unsigned int max_identity_len, 69e71b7053SJung-uk Kim unsigned char *psk, 70e71b7053SJung-uk Kim unsigned int max_psk_len) 71e71b7053SJung-uk Kim { 72e71b7053SJung-uk Kim return 0; 73e71b7053SJung-uk Kim } 74e71b7053SJung-uk Kim #endif 75e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 76e71b7053SJung-uk Kim static char *dummy_srp(SSL *ssl, void *arg) 77e71b7053SJung-uk Kim { 78e71b7053SJung-uk Kim return ""; 79e71b7053SJung-uk Kim } 80e71b7053SJung-uk Kim #endif 81e71b7053SJung-uk Kim 82e71b7053SJung-uk Kim int ciphers_main(int argc, char **argv) 83e71b7053SJung-uk Kim { 84e71b7053SJung-uk Kim SSL_CTX *ctx = NULL; 85e71b7053SJung-uk Kim SSL *ssl = NULL; 86e71b7053SJung-uk Kim STACK_OF(SSL_CIPHER) *sk = NULL; 87e71b7053SJung-uk Kim const SSL_METHOD *meth = TLS_server_method(); 88e71b7053SJung-uk Kim int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0; 89e71b7053SJung-uk Kim int stdname = 0; 90e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 91e71b7053SJung-uk Kim int psk = 0; 92e71b7053SJung-uk Kim #endif 93e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 94e71b7053SJung-uk Kim int srp = 0; 95e71b7053SJung-uk Kim #endif 96e71b7053SJung-uk Kim const char *p; 97e71b7053SJung-uk Kim char *ciphers = NULL, *prog, *convert = NULL, *ciphersuites = NULL; 98e71b7053SJung-uk Kim char buf[512]; 99e71b7053SJung-uk Kim OPTION_CHOICE o; 100e71b7053SJung-uk Kim int min_version = 0, max_version = 0; 101e71b7053SJung-uk Kim 102e71b7053SJung-uk Kim prog = opt_init(argc, argv, ciphers_options); 103e71b7053SJung-uk Kim while ((o = opt_next()) != OPT_EOF) { 104e71b7053SJung-uk Kim switch (o) { 105e71b7053SJung-uk Kim case OPT_EOF: 106e71b7053SJung-uk Kim case OPT_ERR: 107e71b7053SJung-uk Kim opthelp: 108e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 109e71b7053SJung-uk Kim goto end; 110e71b7053SJung-uk Kim case OPT_HELP: 111e71b7053SJung-uk Kim opt_help(ciphers_options); 112e71b7053SJung-uk Kim ret = 0; 113e71b7053SJung-uk Kim goto end; 114e71b7053SJung-uk Kim case OPT_V: 115e71b7053SJung-uk Kim verbose = 1; 116e71b7053SJung-uk Kim break; 117e71b7053SJung-uk Kim case OPT_UPPER_V: 118e71b7053SJung-uk Kim verbose = Verbose = 1; 119e71b7053SJung-uk Kim break; 120e71b7053SJung-uk Kim case OPT_S: 121e71b7053SJung-uk Kim use_supported = 1; 122e71b7053SJung-uk Kim break; 123e71b7053SJung-uk Kim case OPT_STDNAME: 124e71b7053SJung-uk Kim stdname = verbose = 1; 125e71b7053SJung-uk Kim break; 126e71b7053SJung-uk Kim case OPT_CONVERT: 127e71b7053SJung-uk Kim convert = opt_arg(); 128e71b7053SJung-uk Kim break; 129e71b7053SJung-uk Kim case OPT_SSL3: 130e71b7053SJung-uk Kim min_version = SSL3_VERSION; 131e71b7053SJung-uk Kim max_version = SSL3_VERSION; 132e71b7053SJung-uk Kim break; 133e71b7053SJung-uk Kim case OPT_TLS1: 134e71b7053SJung-uk Kim min_version = TLS1_VERSION; 135e71b7053SJung-uk Kim max_version = TLS1_VERSION; 136e71b7053SJung-uk Kim break; 137e71b7053SJung-uk Kim case OPT_TLS1_1: 138e71b7053SJung-uk Kim min_version = TLS1_1_VERSION; 139e71b7053SJung-uk Kim max_version = TLS1_1_VERSION; 140e71b7053SJung-uk Kim break; 141e71b7053SJung-uk Kim case OPT_TLS1_2: 142e71b7053SJung-uk Kim min_version = TLS1_2_VERSION; 143e71b7053SJung-uk Kim max_version = TLS1_2_VERSION; 144e71b7053SJung-uk Kim break; 145e71b7053SJung-uk Kim case OPT_TLS1_3: 146e71b7053SJung-uk Kim min_version = TLS1_3_VERSION; 147e71b7053SJung-uk Kim max_version = TLS1_3_VERSION; 148e71b7053SJung-uk Kim break; 149e71b7053SJung-uk Kim case OPT_PSK: 150e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 151e71b7053SJung-uk Kim psk = 1; 152e71b7053SJung-uk Kim #endif 153e71b7053SJung-uk Kim break; 154e71b7053SJung-uk Kim case OPT_SRP: 155e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 156e71b7053SJung-uk Kim srp = 1; 157e71b7053SJung-uk Kim #endif 158e71b7053SJung-uk Kim break; 159e71b7053SJung-uk Kim case OPT_CIPHERSUITES: 160e71b7053SJung-uk Kim ciphersuites = opt_arg(); 161e71b7053SJung-uk Kim break; 162e71b7053SJung-uk Kim } 163e71b7053SJung-uk Kim } 164e71b7053SJung-uk Kim argv = opt_rest(); 165e71b7053SJung-uk Kim argc = opt_num_rest(); 166e71b7053SJung-uk Kim 167e71b7053SJung-uk Kim if (argc == 1) 168e71b7053SJung-uk Kim ciphers = *argv; 169e71b7053SJung-uk Kim else if (argc != 0) 170e71b7053SJung-uk Kim goto opthelp; 171e71b7053SJung-uk Kim 172e71b7053SJung-uk Kim if (convert != NULL) { 173e71b7053SJung-uk Kim BIO_printf(bio_out, "OpenSSL cipher name: %s\n", 174e71b7053SJung-uk Kim OPENSSL_cipher_name(convert)); 17574664626SKris Kennaway goto end; 17674664626SKris Kennaway } 17774664626SKris Kennaway 17874664626SKris Kennaway ctx = SSL_CTX_new(meth); 1796f9291ceSJung-uk Kim if (ctx == NULL) 1806f9291ceSJung-uk Kim goto err; 181e71b7053SJung-uk Kim if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) 182e71b7053SJung-uk Kim goto err; 183e71b7053SJung-uk Kim if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) 184e71b7053SJung-uk Kim goto err; 185e71b7053SJung-uk Kim 186e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 187e71b7053SJung-uk Kim if (psk) 188e71b7053SJung-uk Kim SSL_CTX_set_psk_client_callback(ctx, dummy_psk); 189e71b7053SJung-uk Kim #endif 190e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 191e71b7053SJung-uk Kim if (srp) 192e71b7053SJung-uk Kim SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp); 193e71b7053SJung-uk Kim #endif 194e71b7053SJung-uk Kim 195e71b7053SJung-uk Kim if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) { 196e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting TLSv1.3 ciphersuites\n"); 197e71b7053SJung-uk Kim goto err; 198e71b7053SJung-uk Kim } 199e71b7053SJung-uk Kim 200f579bf8eSKris Kennaway if (ciphers != NULL) { 201f579bf8eSKris Kennaway if (!SSL_CTX_set_cipher_list(ctx, ciphers)) { 202f579bf8eSKris Kennaway BIO_printf(bio_err, "Error in cipher list\n"); 203f579bf8eSKris Kennaway goto err; 204f579bf8eSKris Kennaway } 205f579bf8eSKris Kennaway } 20674664626SKris Kennaway ssl = SSL_new(ctx); 2076f9291ceSJung-uk Kim if (ssl == NULL) 2086f9291ceSJung-uk Kim goto err; 20974664626SKris Kennaway 210e71b7053SJung-uk Kim if (use_supported) 211e71b7053SJung-uk Kim sk = SSL_get1_supported_ciphers(ssl); 212e71b7053SJung-uk Kim else 213e71b7053SJung-uk Kim sk = SSL_get_ciphers(ssl); 214e71b7053SJung-uk Kim 2156f9291ceSJung-uk Kim if (!verbose) { 216e71b7053SJung-uk Kim for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { 217e71b7053SJung-uk Kim const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); 218e71b7053SJung-uk Kim p = SSL_CIPHER_get_name(c); 2196f9291ceSJung-uk Kim if (p == NULL) 2206f9291ceSJung-uk Kim break; 2216f9291ceSJung-uk Kim if (i != 0) 222e71b7053SJung-uk Kim BIO_printf(bio_out, ":"); 223e71b7053SJung-uk Kim BIO_printf(bio_out, "%s", p); 22474664626SKris Kennaway } 225e71b7053SJung-uk Kim BIO_printf(bio_out, "\n"); 226e71b7053SJung-uk Kim } else { 22774664626SKris Kennaway 2286f9291ceSJung-uk Kim for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { 229e71b7053SJung-uk Kim const SSL_CIPHER *c; 2301f13597dSJung-uk Kim 2311f13597dSJung-uk Kim c = sk_SSL_CIPHER_value(sk, i); 2321f13597dSJung-uk Kim 2336f9291ceSJung-uk Kim if (Verbose) { 2341f13597dSJung-uk Kim unsigned long id = SSL_CIPHER_get_id(c); 2351f13597dSJung-uk Kim int id0 = (int)(id >> 24); 2361f13597dSJung-uk Kim int id1 = (int)((id >> 16) & 0xffL); 2371f13597dSJung-uk Kim int id2 = (int)((id >> 8) & 0xffL); 2381f13597dSJung-uk Kim int id3 = (int)(id & 0xffL); 2391f13597dSJung-uk Kim 240e71b7053SJung-uk Kim if ((id & 0xff000000L) == 0x03000000L) 241e71b7053SJung-uk Kim BIO_printf(bio_out, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 242e71b7053SJung-uk Kim * cipher */ 243e71b7053SJung-uk Kim else 244e71b7053SJung-uk Kim BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ 2456f9291ceSJung-uk Kim } 2467bded2dbSJung-uk Kim if (stdname) { 2477bded2dbSJung-uk Kim const char *nm = SSL_CIPHER_standard_name(c); 2487bded2dbSJung-uk Kim if (nm == NULL) 2497bded2dbSJung-uk Kim nm = "UNKNOWN"; 250e71b7053SJung-uk Kim BIO_printf(bio_out, "%s - ", nm); 2517bded2dbSJung-uk Kim } 252e71b7053SJung-uk Kim BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf))); 25374664626SKris Kennaway } 25474664626SKris Kennaway } 25574664626SKris Kennaway 25674664626SKris Kennaway ret = 0; 257e71b7053SJung-uk Kim goto end; 25874664626SKris Kennaway err: 25974664626SKris Kennaway ERR_print_errors(bio_err); 26074664626SKris Kennaway end: 261e71b7053SJung-uk Kim if (use_supported) 262e71b7053SJung-uk Kim sk_SSL_CIPHER_free(sk); 2636f9291ceSJung-uk Kim SSL_CTX_free(ctx); 2646f9291ceSJung-uk Kim SSL_free(ssl); 265e71b7053SJung-uk Kim return ret; 26674664626SKris Kennaway } 267