mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
Add a ciphersuite config sanity check for servers
Ensure that there are ciphersuites enabled for the maximum supported version we will accept in a ClientHello. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3316)
This commit is contained in:
parent
aafec89c63
commit
38a7315060
@ -2194,8 +2194,7 @@ __owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello,
|
||||
DOWNGRADE *dgrd);
|
||||
__owur int ssl_choose_client_version(SSL *s, int version, int checkdgrd,
|
||||
int *al);
|
||||
int ssl_get_client_min_max_version(const SSL *s, int *min_version,
|
||||
int *max_version);
|
||||
int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version);
|
||||
|
||||
__owur long tls1_default_timeout(void);
|
||||
__owur int dtls1_do_write(SSL *s, int type);
|
||||
|
@ -674,7 +674,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
|
||||
}
|
||||
|
||||
if ((context & SSL_EXT_CLIENT_HELLO) != 0) {
|
||||
reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
|
||||
reason = ssl_get_min_max_version(s, &min_version, &max_version);
|
||||
if (reason != 0) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, reason);
|
||||
goto err;
|
||||
|
@ -464,7 +464,7 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
|
||||
reason = ssl_get_min_max_version(s, &min_version, &max_version);
|
||||
if (reason != 0) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, reason);
|
||||
return 0;
|
||||
|
@ -78,6 +78,39 @@ int tls_setup_handshake(SSL *s)
|
||||
return 0;
|
||||
|
||||
if (s->server) {
|
||||
STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s);
|
||||
int i, ver_min, ver_max, ok = 0;
|
||||
|
||||
/*
|
||||
* Sanity check that the maximum version we accept has ciphers
|
||||
* enabled. For clients we do this check during construction of the
|
||||
* ClientHello.
|
||||
*/
|
||||
if (ssl_get_min_max_version(s, &ver_min, &ver_max) != 0) {
|
||||
SSLerr(SSL_F_TLS_SETUP_HANDSHAKE, ERR_R_INTERNAL_ERROR);
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
|
||||
const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
|
||||
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
if (DTLS_VERSION_GE(ver_max, c->min_dtls) &&
|
||||
DTLS_VERSION_LE(ver_max, c->max_dtls))
|
||||
ok = 1;
|
||||
} else if (ver_max >= c->min_tls && ver_max <= c->max_tls) {
|
||||
ok = 1;
|
||||
}
|
||||
if (ok)
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
SSLerr(SSL_F_TLS_SETUP_HANDSHAKE, SSL_R_NO_CIPHERS_AVAILABLE);
|
||||
ERR_add_error_data(1, "No ciphers enabled for max supported "
|
||||
"SSL/TLS version");
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (SSL_IS_FIRST_HANDSHAKE(s)) {
|
||||
s->ctx->stats.sess_accept++;
|
||||
} else if (!s->s3->send_connection_binding &&
|
||||
@ -1781,7 +1814,7 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd, int *al)
|
||||
}
|
||||
|
||||
/*
|
||||
* ssl_get_client_min_max_version - get minimum and maximum client version
|
||||
* ssl_get_min_max_version - get minimum and maximum protocol version
|
||||
* @s: The SSL connection
|
||||
* @min_version: The minimum supported version
|
||||
* @max_version: The maximum supported version
|
||||
@ -1799,8 +1832,7 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd, int *al)
|
||||
* Returns 0 on success or an SSL error reason number on failure. On failure
|
||||
* min_version and max_version will also be set to 0.
|
||||
*/
|
||||
int ssl_get_client_min_max_version(const SSL *s, int *min_version,
|
||||
int *max_version)
|
||||
int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version)
|
||||
{
|
||||
int version;
|
||||
int hole;
|
||||
@ -1894,7 +1926,7 @@ int ssl_set_client_hello_version(SSL *s)
|
||||
{
|
||||
int ver_min, ver_max, ret;
|
||||
|
||||
ret = ssl_get_client_min_max_version(s, &ver_min, &ver_max);
|
||||
ret = ssl_get_min_max_version(s, &ver_min, &ver_max);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
@ -1013,7 +1013,7 @@ void ssl_set_client_disabled(SSL *s)
|
||||
s->s3->tmp.mask_a = 0;
|
||||
s->s3->tmp.mask_k = 0;
|
||||
ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
|
||||
ssl_get_client_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver);
|
||||
ssl_get_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver);
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
/* with PSK there must be client callback set */
|
||||
if (!s->psk_client_callback) {
|
||||
|
@ -396,6 +396,7 @@ SKIP: {
|
||||
skip "No EC support in this OpenSSL build", 1 if disabled("ec");
|
||||
$proxy->clear();
|
||||
$proxy->clientflags("-no_tls1_3");
|
||||
$proxy->serverflags("-no_tls1_3");
|
||||
$proxy->ciphers("ECDHE-RSA-AES128-SHA");
|
||||
$proxy->start();
|
||||
checkhandshake($proxy, checkhandshake::EC_HANDSHAKE,
|
||||
|
@ -18,6 +18,7 @@ client = 0-srp-client
|
||||
[0-srp-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = SRP
|
||||
MaxProtocol = TLSv1.2
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
|
||||
[0-srp-client]
|
||||
@ -52,6 +53,7 @@ client = 1-srp-bad-password-client
|
||||
[1-srp-bad-password-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = SRP
|
||||
MaxProtocol = TLSv1.2
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
|
||||
[1-srp-bad-password-client]
|
||||
@ -86,6 +88,7 @@ client = 2-srp-auth-client
|
||||
[2-srp-auth-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = aSRP
|
||||
MaxProtocol = TLSv1.2
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
|
||||
[2-srp-auth-client]
|
||||
@ -120,6 +123,7 @@ client = 3-srp-auth-bad-password-client
|
||||
[3-srp-auth-bad-password-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = aSRP
|
||||
MaxProtocol = TLSv1.2
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
|
||||
[3-srp-auth-bad-password-client]
|
||||
|
@ -15,89 +15,93 @@ package ssltests;
|
||||
|
||||
our @tests = (
|
||||
{
|
||||
name => "srp",
|
||||
server => {
|
||||
"CipherString" => "SRP",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
name => "srp",
|
||||
server => {
|
||||
"CipherString" => "SRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "SRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success"
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "SRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success"
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "srp-bad-password",
|
||||
server => {
|
||||
"CipherString" => "SRP",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
name => "srp-bad-password",
|
||||
server => {
|
||||
"CipherString" => "SRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "SRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "passw0rd",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
# Server fails first with bad client Finished.
|
||||
"ExpectedResult" => "ServerFail"
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "SRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "passw0rd",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
# Server fails first with bad client Finished.
|
||||
"ExpectedResult" => "ServerFail"
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "srp-auth",
|
||||
server => {
|
||||
"CipherString" => "aSRP",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
name => "srp-auth",
|
||||
server => {
|
||||
"CipherString" => "aSRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "aSRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success"
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "aSRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success"
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "srp-auth-bad-password",
|
||||
server => {
|
||||
"CipherString" => "aSRP",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
name => "srp-auth-bad-password",
|
||||
server => {
|
||||
"CipherString" => "aSRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "password",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "aSRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "passw0rd",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
# Server fails first with bad client Finished.
|
||||
"ExpectedResult" => "ServerFail"
|
||||
},
|
||||
client => {
|
||||
"CipherString" => "aSRP",
|
||||
"MaxProtocol" => "TLSv1.2",
|
||||
extra => {
|
||||
"SRPUser" => "user",
|
||||
"SRPPassword" => "passw0rd",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
# Server fails first with bad client Finished.
|
||||
"ExpectedResult" => "ServerFail"
|
||||
},
|
||||
},
|
||||
);
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user