diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2021-09-27 11:41:52 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-27 11:41:52 +0900 |
commit | 87887fec2a2e973ed4e05187f7d05a4cb6d92eaa (patch) | |
tree | fd7ea362c48b244c9e74260428047fbae6007e0b | |
parent | b74e43bd71b9870e335da0120f5314cd6096e7e9 (diff) | |
parent | 202ff1372a40a8adf9aac74bfe8a39141b0c57e5 (diff) | |
download | ruby-openssl-87887fec2a2e973ed4e05187f7d05a4cb6d92eaa.tar.gz |
Merge pull request #458 from rhenium/ky/maint-refuse-openssl-3.0
[2.1.x and 2.2.x] ext/openssl/extconf.rb: require OpenSSL version >= 1.0.1, < 3
-rw-r--r-- | .github/workflows/test.yml | 7 | ||||
-rw-r--r-- | ext/openssl/extconf.rb | 43 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 6 | ||||
-rw-r--r-- | test/test_ssl.rb | 47 | ||||
-rw-r--r-- | test/test_ssl_session.rb | 1 | ||||
-rw-r--r-- | test/utils.rb | 8 |
6 files changed, 80 insertions, 32 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 48f59c5f..604a2a53 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,10 +74,11 @@ jobs: - openssl-1.0.1u # EOL - openssl-1.0.2u # EOL - openssl-1.1.0l # EOL - - openssl-1.1.1j + - openssl-1.1.1l - libressl-2.5.5 # EOL - - libressl-3.1.5 - - libressl-3.2.0 + - libressl-3.1.5 # EOL + - libressl-3.2.6 + - libressl-3.3.4 steps: - name: repo checkout uses: actions/checkout@v2 diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 264130bb..7e817ae2 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -37,9 +37,6 @@ if $mswin || $mingw have_library("ws2_32") end -Logging::message "=== Checking for required stuff... ===\n" -result = pkg_config("openssl") && have_header("openssl/ssl.h") - def find_openssl_library if $mswin || $mingw # required for static OpenSSL libraries @@ -90,19 +87,33 @@ def find_openssl_library return false end -unless result - unless find_openssl_library - Logging::message "=== Checking for required stuff failed. ===\n" - Logging::message "Makefile wasn't created. Fix the errors above.\n" - raise "OpenSSL library could not be found. You might want to use " \ - "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ - "is installed." - end +Logging::message "=== Checking for required stuff... ===\n" +pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h") + +if !pkg_config_found && !find_openssl_library + Logging::message "=== Checking for required stuff failed. ===\n" + Logging::message "Makefile wasn't created. Fix the errors above.\n" + raise "OpenSSL library could not be found. You might want to use " \ + "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ + "is installed." end -unless checking_for("OpenSSL version is 1.0.1 or later") { - try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") } - raise "OpenSSL >= 1.0.1 or LibreSSL is required" +version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") + is_libressl = true + checking_for("LibreSSL version >= 2.5.0") { + try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x20500000L", "openssl/opensslv.h") } +else + checking_for("OpenSSL version >= 1.0.1 and < 3.0.0") { + try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") && + !try_static_assert("OPENSSL_VERSION_MAJOR >= 3", "openssl/opensslv.h") } +end +unless version_ok + raise "OpenSSL >= 1.0.1, < 3.0.0 or LibreSSL >= 2.5.0 is required" +end + +# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h +if is_libressl && ($mswin || $mingw) + $defs.push("-DNOCRYPT") end Logging::message "=== Checking for OpenSSL features... ===\n" @@ -114,10 +125,6 @@ engines.each { |name| OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h") } -if ($mswin || $mingw) && have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") - $defs.push("-DNOCRYPT") -end - # added in 1.0.2 have_func("EC_curve_nist2nid") have_func("X509_REVOKED_dup") diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index f4271369..a8386f72 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -13,6 +13,12 @@ #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0])) +#if !defined(TLS1_3_VERSION) && \ + defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER >= 0x3020000fL +# define TLS1_3_VERSION 0x0304 +#endif + #ifdef _WIN32 # define TO_SOCKET(s) _get_osfhandle(s) #else diff --git a/test/test_ssl.rb b/test/test_ssl.rb index 764416be..53457e21 100644 --- a/test/test_ssl.rb +++ b/test/test_ssl.rb @@ -207,7 +207,10 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase def test_client_auth_success vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT - start_server(verify_mode: vflag) { |port| + start_server(verify_mode: vflag, + ctx_proc: proc { |ctx| + ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0) + }) { |port| ctx = OpenSSL::SSL::SSLContext.new ctx.key = @cli_key ctx.cert = @cli_cert @@ -253,6 +256,8 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase end def test_client_ca + pend "LibreSSL 3.2 has broken client CA support" if libressl?(3, 2, 0) + ctx_proc = Proc.new do |ctx| ctx.client_ca = [@ca_cert] end @@ -793,11 +798,13 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase def test_verify_hostname_on_connect ctx_proc = proc { |ctx| + san = "DNS:a.example.com,DNS:*.b.example.com" + san += ",DNS:c*.example.com,DNS:d.*.example.com" unless libressl?(3, 2, 2) exts = [ ["keyUsage", "keyEncipherment,digitalSignature", true], - ["subjectAltName", "DNS:a.example.com,DNS:*.b.example.com," \ - "DNS:c*.example.com,DNS:d.*.example.com"], + ["subjectAltName", san], ] + ctx.cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key) ctx.key = @svr_key } @@ -818,6 +825,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase ["cx.example.com", true], ["d.x.example.com", false], ].each do |name, expected_ok| + next if name.start_with?('cx') if libressl?(3, 2, 2) begin sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) @@ -1501,12 +1509,13 @@ end end end - def test_ecdh_curves + def test_ecdh_curves_tls12 pend "EC is disabled" unless defined?(OpenSSL::PKey::EC) ctx_proc = -> ctx { # Enable both ECDHE (~ TLS 1.2) cipher suites and TLS 1.3 - ctx.ciphers = "DEFAULT:!kRSA:!kEDH" + ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION + ctx.ciphers = "kEECDH" ctx.ecdh_curves = "P-384:P-521" } start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port| @@ -1515,13 +1524,9 @@ end server_connect(port, ctx) { |ssl| cs = ssl.cipher[0] - if /\ATLS/ =~ cs # Is TLS 1.3 is used? + assert_match (/\AECDH/), cs + if ssl.respond_to?(:tmp_key) assert_equal "secp384r1", ssl.tmp_key.group.curve_name - else - assert_match (/\AECDH/), cs - if ssl.respond_to?(:tmp_key) - assert_equal "secp384r1", ssl.tmp_key.group.curve_name - end end ssl.puts "abc"; assert_equal "abc\n", ssl.gets } @@ -1545,6 +1550,26 @@ end end end + def test_ecdh_curves_tls13 + pend "EC is disabled" unless defined?(OpenSSL::PKey::EC) + pend "TLS 1.3 not supported" unless tls13_supported? + + ctx_proc = -> ctx { + # Assume TLS 1.3 is enabled and chosen by default + ctx.ecdh_curves = "P-384:P-521" + } + start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port| + ctx = OpenSSL::SSL::SSLContext.new + ctx.ecdh_curves = "P-256:P-384" # disable P-521 + + server_connect(port, ctx) { |ssl| + assert_equal "TLSv1.3", ssl.ssl_version + assert_equal "secp384r1", ssl.tmp_key.group.curve_name + ssl.puts "abc"; assert_equal "abc\n", ssl.gets + } + end + end + def test_security_level ctx = OpenSSL::SSL::SSLContext.new begin diff --git a/test/test_ssl_session.rb b/test/test_ssl_session.rb index e199f86d..1d82aebf 100644 --- a/test/test_ssl_session.rb +++ b/test/test_ssl_session.rb @@ -122,6 +122,7 @@ __EOS__ ctx.options &= ~OpenSSL::SSL::OP_NO_TICKET # Disable server-side session cache which is enabled by default ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF + ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0) } start_server(ctx_proc: ctx_proc) do |port| sess1 = server_connect_with_session(port, nil, nil) { |ssl| diff --git a/test/utils.rb b/test/utils.rb index bf191630..34c89a2e 100644 --- a/test/utils.rb +++ b/test/utils.rb @@ -181,6 +181,14 @@ class OpenSSL::SSLTestCase < OpenSSL::TestCase rescue end + def tls13_supported? + return false unless defined?(OpenSSL::SSL::TLS1_3_VERSION) + ctx = OpenSSL::SSL::SSLContext.new + ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_3_VERSION + true + rescue + end + def readwrite_loop(ctx, ssl) while line = ssl.gets ssl.write(line) |