From 7bf2e4d7f0c7ae19b7a8c416910886a7171e9820 Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 4 May 2022 13:01:35 +1000 Subject: tls: ban SSL3, TLS1, TLS1.1 and DTLS1.0 at security level one and above This is in line with the NEWS entry (erroneously) announcing such for 3.0. Fixes #18194 Reviewed-by: Tomas Mraz Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/18236) --- NEWS.md | 1 + ssl/ssl_cert.c | 14 +++------- test/bad_dtls_test.c | 1 + test/recipes/80-test_ssl_old.t | 54 ++++++++++++++++++++++++++++++------ test/ssl-tests/20-cert-select.cnf | 4 +-- test/ssl-tests/20-cert-select.cnf.in | 7 ++++- 6 files changed, 60 insertions(+), 21 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6f741ee61a..8dc94bc62f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -25,6 +25,7 @@ OpenSSL 3.1 by default. * TCP Fast Open (RFC7413) support is available on Linux, macOS, and FreeBSD where enabled and supported. + * SSL 3, TLS 1.0, TLS 1.1, and DTLS 1.0 only work at security level 0. OpenSSL 3.0 ----------- diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index e8c11eabc3..267e8695f9 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1047,18 +1047,12 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, } case SSL_SECOP_VERSION: if (!SSL_IS_DTLS(s)) { - /* SSLv3 not allowed at level 2 */ - if (nid <= SSL3_VERSION && level >= 2) - return 0; - /* TLS v1.1 and above only for level 3 */ - if (nid <= TLS1_VERSION && level >= 3) - return 0; - /* TLS v1.2 only for level 4 and above */ - if (nid <= TLS1_1_VERSION && level >= 4) + /* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */ + if (nid <= TLS1_1_VERSION && level > 0) return 0; } else { - /* DTLS v1.2 only for level 4 and above */ - if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level >= 4) + /* DTLS v1.0 only allowed at level 0 */ + if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level > 0) return 0; } break; diff --git a/test/bad_dtls_test.c b/test/bad_dtls_test.c index f8c6b142d8..8849269173 100644 --- a/test/bad_dtls_test.c +++ b/test/bad_dtls_test.c @@ -499,6 +499,7 @@ static int test_bad_dtls(void) || !TEST_true(SSL_CTX_set_cipher_list(ctx, "AES128-SHA"))) goto end; + SSL_CTX_set_security_level(ctx, 0); con = SSL_new(ctx); if (!TEST_ptr(con) || !TEST_true(SSL_set_session(con, sess))) diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t index 8c52b637fc..50b74a1e29 100644 --- a/test/recipes/80-test_ssl_old.t +++ b/test/recipes/80-test_ssl_old.t @@ -78,9 +78,10 @@ my $client_sess="client.ss"; # If you're adding tests here, you probably want to convert them to the # new format in ssl_test.c and add recipes to 80-test_ssl_new.t instead. plan tests => - ($no_fips ? 0 : 5) # testssl with fips provider + ($no_fips ? 0 : 6) # testssl with fips provider + 1 # For testss + 5 # For the testssl with default provider + + 1 # For security level 0 failure tests ; subtest 'test_ss' => sub { @@ -345,7 +346,6 @@ sub testssl { $dsa_cert = 1; } - subtest 'standard SSL tests' => sub { ###################################################################### plan tests => 19; @@ -527,6 +527,44 @@ sub testssl { } }; + subtest 'SSL security level failure tests' => sub { + ###################################################################### + plan tests => 3; + + SKIP: { + skip "SSLv3 is not supported by this OpenSSL build", 1 + if disabled("ssl3"); + + skip "SSLv3 is not supported by the FIPS provider", 1 + if $provider eq "fips"; + + is(run(test([@ssltest, "-bio_pair", "-ssl3", "-cipher", '@SECLEVEL=1'])), + 0, "test sslv3 fails at security level 1, expecting failure"); + } + + SKIP: { + skip "TLSv1.0 is not supported by this OpenSSL build", 1 + if $no_tls1; + + skip "TLSv1.0 is not supported by the FIPS provider", 1 + if $provider eq "fips"; + + is(run(test([@ssltest, "-bio_pair", "-tls1", "-cipher", '@SECLEVEL=1'])), + 0, 'test tls1 fails at security level 1, expecting failure'); + } + + SKIP: { + skip "TLSv1.1 is not supported by this OpenSSL build", 1 + if $no_tls1_1; + + skip "TLSv1.1 is not supported by the FIPS provider", 1 + if $provider eq "fips"; + + is(run(test([@ssltest, "-bio_pair", "-tls1_1", "-cipher", '@SECLEVEL=1'])), + 0, 'test tls1.1 fails at security level 1, expecting failure'); + } + }; + subtest 'RSA/(EC)DHE/PSK tests' => sub { ###################################################################### @@ -579,14 +617,14 @@ sub testssl { } SKIP: { - skip "TLSv1.1 is not supported by this OpenSSL build", 4 - if $no_tls1_1; + skip "TLSv1.2 is not supported by this OpenSSL build", 4 + if $no_tls1_2; SKIP: { skip "skipping auto DHE PSK test at SECLEVEL 3", 1 if ($no_dh || $no_psk); - ok(run(test(['ssl_old_test', '-tls1_1', '-dhe4096', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:DHE-PSK-AES256-CBC-SHA384'])), + ok(run(test(['ssl_old_test', '-tls1_2', '-dhe4096', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:DHE-PSK-AES256-CBC-SHA384'])), 'test auto DHE PSK meets security strength'); } @@ -594,7 +632,7 @@ sub testssl { skip "skipping auto ECDHE PSK test at SECLEVEL 3", 1 if ($no_ec || $no_psk); - ok(run(test(['ssl_old_test', '-tls1_1', '-no_dhe', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:ECDHE-PSK-AES256-CBC-SHA384'])), + ok(run(test(['ssl_old_test', '-tls1_2', '-no_dhe', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:ECDHE-PSK-AES256-CBC-SHA384'])), 'test auto ECDHE PSK meets security strength'); } @@ -602,7 +640,7 @@ sub testssl { skip "skipping no RSA PSK at SECLEVEL 3 test", 1 if ($no_rsa || $no_psk); - ok(!run(test(['ssl_old_test', '-tls1_1', '-no_dhe', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:RSA-PSK-AES256-CBC-SHA384'])), + ok(!run(test(['ssl_old_test', '-tls1_2', '-no_dhe', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:RSA-PSK-AES256-CBC-SHA384'])), 'test auto RSA PSK does not meet security level 3 requirements (PFS)'); } @@ -610,7 +648,7 @@ sub testssl { skip "skipping no PSK at SECLEVEL 3 test", 1 if ($no_psk); - ok(!run(test(['ssl_old_test', '-tls1_1', '-no_dhe', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:PSK-AES256-CBC-SHA384'])), + ok(!run(test(['ssl_old_test', '-tls1_2', '-no_dhe', '-psk', '0102030405', '-cipher', '@SECLEVEL=3:PSK-AES256-CBC-SHA384'])), 'test auto PSK does not meet security level 3 requirements (PFS)'); } } diff --git a/test/ssl-tests/20-cert-select.cnf b/test/ssl-tests/20-cert-select.cnf index 853deff1d4..5cb7aca3ea 100644 --- a/test/ssl-tests/20-cert-select.cnf +++ b/test/ssl-tests/20-cert-select.cnf @@ -1119,11 +1119,11 @@ client = 34-Only RSA-PSS Certificate, TLS v1.1-client [34-Only RSA-PSS Certificate, TLS v1.1-server] Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-cert.pem -CipherString = DEFAULT +CipherString = DEFAULT:@SECLEVEL=0 PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-key.pem [34-Only RSA-PSS Certificate, TLS v1.1-client] -CipherString = DEFAULT +CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = TLSv1.1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer diff --git a/test/ssl-tests/20-cert-select.cnf.in b/test/ssl-tests/20-cert-select.cnf.in index 26c7318974..d0cc5cfd5c 100644 --- a/test/ssl-tests/20-cert-select.cnf.in +++ b/test/ssl-tests/20-cert-select.cnf.in @@ -585,9 +585,14 @@ my @tests_pss = ( my @tests_tls_1_1 = ( { name => "Only RSA-PSS Certificate, TLS v1.1", - server => $server_pss_only, + server => { + "CipherString" => "DEFAULT:\@SECLEVEL=0", + "Certificate" => test_pem("server-pss-cert.pem"), + "PrivateKey" => test_pem("server-pss-key.pem"), + }, client => { "MaxProtocol" => "TLSv1.1", + "CipherString" => "DEFAULT:\@SECLEVEL=0", }, test => { "ExpectedResult" => "ServerFail" -- cgit v1.2.3