Changeset View
Changeset View
Standalone View
Standalone View
apps/ciphers.c
/* | /* | ||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. | * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. | ||||
* | * | ||||
* Licensed under the OpenSSL license (the "License"). You may not use | * Licensed under the Apache License 2.0 (the "License"). You may not use | ||||
* this file except in compliance with the License. You can obtain a copy | * this file except in compliance with the License. You can obtain a copy | ||||
* in the file LICENSE in the source distribution or at | * in the file LICENSE in the source distribution or at | ||||
* https://www.openssl.org/source/license.html | * https://www.openssl.org/source/license.html | ||||
*/ | */ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "apps.h" | #include "apps.h" | ||||
#include "progs.h" | #include "progs.h" | ||||
#include <openssl/err.h> | #include <openssl/err.h> | ||||
#include <openssl/ssl.h> | #include <openssl/ssl.h> | ||||
#include "s_apps.h" | |||||
typedef enum OPTION_choice { | typedef enum OPTION_choice { | ||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, | OPT_COMMON, | ||||
OPT_STDNAME, | OPT_STDNAME, | ||||
OPT_CONVERT, | OPT_CONVERT, | ||||
OPT_SSL3, | OPT_SSL3, | ||||
OPT_TLS1, | OPT_TLS1, | ||||
OPT_TLS1_1, | OPT_TLS1_1, | ||||
OPT_TLS1_2, | OPT_TLS1_2, | ||||
OPT_TLS1_3, | OPT_TLS1_3, | ||||
OPT_PSK, | OPT_PSK, | ||||
OPT_SRP, | OPT_SRP, | ||||
OPT_CIPHERSUITES, | OPT_CIPHERSUITES, | ||||
OPT_V, OPT_UPPER_V, OPT_S | OPT_V, OPT_UPPER_V, OPT_S, OPT_PROV_ENUM | ||||
} OPTION_CHOICE; | } OPTION_CHOICE; | ||||
const OPTIONS ciphers_options[] = { | const OPTIONS ciphers_options[] = { | ||||
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [cipher]\n"}, | |||||
OPT_SECTION("General"), | |||||
{"help", OPT_HELP, '-', "Display this summary"}, | {"help", OPT_HELP, '-', "Display this summary"}, | ||||
OPT_SECTION("Output"), | |||||
{"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, | {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, | ||||
{"V", OPT_UPPER_V, '-', "Even more verbose"}, | {"V", OPT_UPPER_V, '-', "Even more verbose"}, | ||||
{"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, | |||||
{"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, | |||||
OPT_SECTION("Cipher specification"), | |||||
{"s", OPT_S, '-', "Only supported ciphers"}, | {"s", OPT_S, '-', "Only supported ciphers"}, | ||||
#ifndef OPENSSL_NO_SSL3 | #ifndef OPENSSL_NO_SSL3 | ||||
{"ssl3", OPT_SSL3, '-', "SSL3 mode"}, | {"ssl3", OPT_SSL3, '-', "Ciphers compatible with SSL3"}, | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_TLS1 | #ifndef OPENSSL_NO_TLS1 | ||||
{"tls1", OPT_TLS1, '-', "TLS1 mode"}, | {"tls1", OPT_TLS1, '-', "Ciphers compatible with TLS1"}, | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_TLS1_1 | #ifndef OPENSSL_NO_TLS1_1 | ||||
{"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"}, | {"tls1_1", OPT_TLS1_1, '-', "Ciphers compatible with TLS1.1"}, | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_TLS1_2 | #ifndef OPENSSL_NO_TLS1_2 | ||||
{"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"}, | {"tls1_2", OPT_TLS1_2, '-', "Ciphers compatible with TLS1.2"}, | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_TLS1_3 | #ifndef OPENSSL_NO_TLS1_3 | ||||
{"tls1_3", OPT_TLS1_3, '-', "TLS1.3 mode"}, | {"tls1_3", OPT_TLS1_3, '-', "Ciphers compatible with TLS1.3"}, | ||||
#endif | #endif | ||||
{"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, | |||||
#ifndef OPENSSL_NO_PSK | #ifndef OPENSSL_NO_PSK | ||||
{"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"}, | {"psk", OPT_PSK, '-', "Include ciphersuites requiring PSK"}, | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_SRP | #ifndef OPENSSL_NO_SRP | ||||
{"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"}, | {"srp", OPT_SRP, '-', "(deprecated) Include ciphersuites requiring SRP"}, | ||||
#endif | #endif | ||||
{"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, | |||||
{"ciphersuites", OPT_CIPHERSUITES, 's', | {"ciphersuites", OPT_CIPHERSUITES, 's', | ||||
"Configure the TLSv1.3 ciphersuites to use"}, | "Configure the TLSv1.3 ciphersuites to use"}, | ||||
OPT_PROV_OPTIONS, | |||||
OPT_PARAMETERS(), | |||||
{"cipher", 0, 0, "Cipher string to decode (optional)"}, | |||||
{NULL} | {NULL} | ||||
}; | }; | ||||
#ifndef OPENSSL_NO_PSK | #ifndef OPENSSL_NO_PSK | ||||
static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity, | static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity, | ||||
unsigned int max_identity_len, | unsigned int max_identity_len, | ||||
unsigned char *psk, | unsigned char *psk, | ||||
unsigned int max_psk_len) | unsigned int max_psk_len) | ||||
{ | { | ||||
return 0; | return 0; | ||||
} | } | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_SRP | |||||
static char *dummy_srp(SSL *ssl, void *arg) | |||||
{ | |||||
return ""; | |||||
} | |||||
#endif | |||||
int ciphers_main(int argc, char **argv) | int ciphers_main(int argc, char **argv) | ||||
{ | { | ||||
SSL_CTX *ctx = NULL; | SSL_CTX *ctx = NULL; | ||||
SSL *ssl = NULL; | SSL *ssl = NULL; | ||||
STACK_OF(SSL_CIPHER) *sk = NULL; | STACK_OF(SSL_CIPHER) *sk = NULL; | ||||
const SSL_METHOD *meth = TLS_server_method(); | const SSL_METHOD *meth = TLS_server_method(); | ||||
int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0; | int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0; | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | #endif | ||||
case OPT_SRP: | case OPT_SRP: | ||||
#ifndef OPENSSL_NO_SRP | #ifndef OPENSSL_NO_SRP | ||||
srp = 1; | srp = 1; | ||||
#endif | #endif | ||||
break; | break; | ||||
case OPT_CIPHERSUITES: | case OPT_CIPHERSUITES: | ||||
ciphersuites = opt_arg(); | ciphersuites = opt_arg(); | ||||
break; | break; | ||||
case OPT_PROV_CASES: | |||||
if (!opt_provider(o)) | |||||
goto end; | |||||
break; | |||||
} | } | ||||
} | } | ||||
/* Optional arg is cipher name. */ | |||||
argv = opt_rest(); | argv = opt_rest(); | ||||
argc = opt_num_rest(); | argc = opt_num_rest(); | ||||
if (argc == 1) | if (argc == 1) | ||||
ciphers = *argv; | ciphers = argv[0]; | ||||
else if (argc != 0) | else if (argc != 0) | ||||
goto opthelp; | goto opthelp; | ||||
if (convert != NULL) { | if (convert != NULL) { | ||||
BIO_printf(bio_out, "OpenSSL cipher name: %s\n", | BIO_printf(bio_out, "OpenSSL cipher name: %s\n", | ||||
OPENSSL_cipher_name(convert)); | OPENSSL_cipher_name(convert)); | ||||
ret = 0; | ret = 0; | ||||
goto end; | goto end; | ||||
} | } | ||||
ctx = SSL_CTX_new(meth); | ctx = SSL_CTX_new_ex(app_get0_libctx(), app_get0_propq(), meth); | ||||
if (ctx == NULL) | if (ctx == NULL) | ||||
goto err; | goto err; | ||||
if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) | if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) | ||||
goto err; | goto err; | ||||
if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) | if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) | ||||
goto err; | goto err; | ||||
#ifndef OPENSSL_NO_PSK | #ifndef OPENSSL_NO_PSK | ||||
if (psk) | if (psk) | ||||
SSL_CTX_set_psk_client_callback(ctx, dummy_psk); | SSL_CTX_set_psk_client_callback(ctx, dummy_psk); | ||||
#endif | #endif | ||||
#ifndef OPENSSL_NO_SRP | #ifndef OPENSSL_NO_SRP | ||||
if (srp) | if (srp) | ||||
SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp); | set_up_dummy_srp(ctx); | ||||
#endif | #endif | ||||
if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) { | if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) { | ||||
BIO_printf(bio_err, "Error setting TLSv1.3 ciphersuites\n"); | BIO_printf(bio_err, "Error setting TLSv1.3 ciphersuites\n"); | ||||
goto err; | goto err; | ||||
} | } | ||||
if (ciphers != NULL) { | if (ciphers != NULL) { | ||||
Show All 9 Lines | #endif | ||||
if (use_supported) | if (use_supported) | ||||
sk = SSL_get1_supported_ciphers(ssl); | sk = SSL_get1_supported_ciphers(ssl); | ||||
else | else | ||||
sk = SSL_get_ciphers(ssl); | sk = SSL_get_ciphers(ssl); | ||||
if (!verbose) { | if (!verbose) { | ||||
for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { | for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { | ||||
const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); | const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); | ||||
if (!ossl_assert(c != NULL)) | |||||
continue; | |||||
p = SSL_CIPHER_get_name(c); | p = SSL_CIPHER_get_name(c); | ||||
if (p == NULL) | if (p == NULL) | ||||
break; | break; | ||||
if (i != 0) | if (i != 0) | ||||
BIO_printf(bio_out, ":"); | BIO_printf(bio_out, ":"); | ||||
BIO_printf(bio_out, "%s", p); | BIO_printf(bio_out, "%s", p); | ||||
} | } | ||||
BIO_printf(bio_out, "\n"); | BIO_printf(bio_out, "\n"); | ||||
} else { | } else { | ||||
for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { | for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { | ||||
const SSL_CIPHER *c; | const SSL_CIPHER *c; | ||||
c = sk_SSL_CIPHER_value(sk, i); | c = sk_SSL_CIPHER_value(sk, i); | ||||
if (!ossl_assert(c != NULL)) | |||||
continue; | |||||
if (Verbose) { | if (Verbose) { | ||||
unsigned long id = SSL_CIPHER_get_id(c); | unsigned long id = SSL_CIPHER_get_id(c); | ||||
int id0 = (int)(id >> 24); | int id0 = (int)(id >> 24); | ||||
int id1 = (int)((id >> 16) & 0xffL); | int id1 = (int)((id >> 16) & 0xffL); | ||||
int id2 = (int)((id >> 8) & 0xffL); | int id2 = (int)((id >> 8) & 0xffL); | ||||
int id3 = (int)(id & 0xffL); | int id3 = (int)(id & 0xffL); | ||||
if ((id & 0xff000000L) == 0x03000000L) | if ((id & 0xff000000L) == 0x03000000L) | ||||
BIO_printf(bio_out, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 | BIO_printf(bio_out, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 | ||||
* cipher */ | * cipher */ | ||||
else | else | ||||
BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ | BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ | ||||
} | } | ||||
if (stdname) { | if (stdname) { | ||||
const char *nm = SSL_CIPHER_standard_name(c); | const char *nm = SSL_CIPHER_standard_name(c); | ||||
if (nm == NULL) | if (nm == NULL) | ||||
nm = "UNKNOWN"; | nm = "UNKNOWN"; | ||||
BIO_printf(bio_out, "%s - ", nm); | BIO_printf(bio_out, "%-45s - ", nm); | ||||
} | } | ||||
BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf))); | BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf))); | ||||
} | } | ||||
} | } | ||||
ret = 0; | ret = 0; | ||||
goto end; | goto end; | ||||
err: | err: | ||||
ERR_print_errors(bio_err); | ERR_print_errors(bio_err); | ||||
end: | end: | ||||
if (use_supported) | if (use_supported) | ||||
sk_SSL_CIPHER_free(sk); | sk_SSL_CIPHER_free(sk); | ||||
SSL_CTX_free(ctx); | SSL_CTX_free(ctx); | ||||
SSL_free(ssl); | SSL_free(ssl); | ||||
return ret; | return ret; | ||||
} | } |