Skip to content

Commit

Permalink
Merge pull request #841 from rhenium/ky/require-openssl-1.1.1
Browse files Browse the repository at this point in the history
Require OpenSSL 1.1.1 or later (Drop support for 1.1.0)
  • Loading branch information
rhenium authored Jan 21, 2025
2 parents 4a009a1 + ba83abe commit 050f0c6
Show file tree
Hide file tree
Showing 16 changed files with 38 additions and 166 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ jobs:
name-extra: [ '' ]
openssl:
# https://openssl-library.org/source/
- openssl-1.1.0l # EOL
- openssl-1.1.1w # EOL 2023-09-11, still used by RHEL 8 and Ubuntu 20.04
- openssl-3.0.15 # Supported until 2026-09-07
- openssl-3.1.7 # Supported until 2025-03-14
Expand Down
11 changes: 4 additions & 7 deletions ext/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@ def find_openssl_library
try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x30900000L", "openssl/opensslv.h") }
else
is_openssl = true
checking_for("OpenSSL version >= 1.1.0") {
try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10100000L", "openssl/opensslv.h") }
checking_for("OpenSSL version >= 1.1.1") {
try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10101000L", "openssl/opensslv.h") }
end
unless version_ok
raise "OpenSSL >= 1.1.0 or LibreSSL >= 3.9.0 is required"
raise "OpenSSL >= 1.1.1 or LibreSSL >= 3.9.0 is required"
end

# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h
Expand All @@ -138,11 +138,8 @@ def find_openssl_library
# added in 1.1.0, currently not in LibreSSL
have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h)

# added in 1.1.1
# added in OpenSSL 1.1.1 and LibreSSL 3.5.0, then removed in LibreSSL 4.0.0
have_func("EVP_PKEY_check(NULL)", evp_h)
have_func("EVP_PKEY_new_raw_private_key(0, NULL, (unsigned char *)\"\", 0)", evp_h)
have_func("SSL_CTX_set_ciphersuites(NULL, \"\")", ssl_h)
have_func("SSL_CTX_set_post_handshake_auth(NULL, 0)", ssl_h)

# added in 3.0.0
have_func("SSL_set0_tmp_dh_pkey(NULL, NULL)", ssl_h)
Expand Down
8 changes: 0 additions & 8 deletions ext/openssl/ossl_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,11 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)

GetHMAC(self, ctx);
StringValue(key);
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
(unsigned char *)RSTRING_PTR(key),
RSTRING_LENINT(key));
if (!pkey)
ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key");
#else
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
(unsigned char *)RSTRING_PTR(key),
RSTRING_LENINT(key));
if (!pkey)
ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
#endif
if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
NULL, pkey) != 1) {
EVP_PKEY_free(pkey);
Expand Down
49 changes: 0 additions & 49 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,6 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other)
}
#endif

#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
/*
* call-seq:
* OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey
Expand Down Expand Up @@ -665,9 +664,7 @@ ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)

return ossl_pkey_new(pkey);
}
#endif

#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
/*
* call-seq:
* OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey
Expand Down Expand Up @@ -698,7 +695,6 @@ ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)

return ossl_pkey_new(pkey);
}
#endif

/*
* call-seq:
Expand Down Expand Up @@ -889,7 +885,6 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
return do_pkcs8_export(argc, argv, self, 0);
}

#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
/*
* call-seq:
* pkey.raw_private_key => string
Expand All @@ -916,7 +911,6 @@ ossl_pkey_raw_private_key(VALUE self)

return str;
}
#endif

VALUE
ossl_pkey_export_spki(VALUE self, int to_der)
Expand Down Expand Up @@ -973,7 +967,6 @@ ossl_pkey_public_to_pem(VALUE self)
return ossl_pkey_export_spki(self, 0);
}

#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
/*
* call-seq:
* pkey.raw_public_key => string
Expand All @@ -1000,7 +993,6 @@ ossl_pkey_raw_public_key(VALUE self)

return str;
}
#endif

/*
* call-seq:
Expand Down Expand Up @@ -1104,7 +1096,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
rb_jump_tag(state);
}
}
#if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_IS_LIBRESSL
if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data),
RSTRING_LEN(data)) < 1) {
EVP_MD_CTX_free(ctx);
Expand All @@ -1125,30 +1116,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSign");
}
#else
if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSignUpdate");
}
if (EVP_DigestSignFinal(ctx, NULL, &siglen) < 1) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSignFinal");
}
if (siglen > LONG_MAX) {
EVP_MD_CTX_free(ctx);
rb_raise(ePKeyError, "signature would be too large");
}
sig = ossl_str_new(NULL, (long)siglen, &state);
if (state) {
EVP_MD_CTX_free(ctx);
rb_jump_tag(state);
}
if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
&siglen) < 1) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSignFinal");
}
#endif
EVP_MD_CTX_free(ctx);
rb_str_set_len(sig, siglen);
return sig;
Expand Down Expand Up @@ -1209,24 +1176,12 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
rb_jump_tag(state);
}
}
#if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_IS_LIBRESSL
ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig),
RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data),
RSTRING_LEN(data));
EVP_MD_CTX_free(ctx);
if (ret < 0)
ossl_raise(ePKeyError, "EVP_DigestVerify");
#else
if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate");
}
ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
RSTRING_LEN(sig));
EVP_MD_CTX_free(ctx);
if (ret < 0)
ossl_raise(ePKeyError, "EVP_DigestVerifyFinal");
#endif
if (ret)
return Qtrue;
else {
Expand Down Expand Up @@ -1739,10 +1694,8 @@ Init_ossl_pkey(void)
rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1);
rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1);
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2);
rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2);
#endif

rb_define_alloc_func(cPKey, ossl_pkey_alloc);
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
Expand All @@ -1758,10 +1711,8 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0);
rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0);
#endif
rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1);

rb_define_method(cPKey, "sign", ossl_pkey_sign, -1);
Expand Down
2 changes: 0 additions & 2 deletions ext/openssl/ossl_rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,7 @@ Init_ossl_rand(void)
rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1);
rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
rb_define_alias(rb_singleton_class(mRandom), "pseudo_bytes", "random_bytes");
#endif
#ifdef HAVE_RAND_EGD
rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);
rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
Expand Down
28 changes: 8 additions & 20 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ parse_proto_version(VALUE str)
{ "TLS1", TLS1_VERSION },
{ "TLS1_1", TLS1_1_VERSION },
{ "TLS1_2", TLS1_2_VERSION },
#ifdef TLS1_3_VERSION
{ "TLS1_3", TLS1_3_VERSION },
#endif
};

if (NIL_P(str))
Expand Down Expand Up @@ -383,7 +381,7 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
return 0;
}

#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
#if !OSSL_IS_LIBRESSL
/*
* It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
* SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
Expand Down Expand Up @@ -762,9 +760,7 @@ ossl_sslctx_setup(VALUE self)
SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
#endif

#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
SSL_CTX_set_post_handshake_auth(ctx, 1);
#endif

val = rb_attr_get(self, id_i_cert_store);
if (!NIL_P(val)) {
Expand Down Expand Up @@ -904,7 +900,7 @@ ossl_sslctx_setup(VALUE self)
OSSL_Debug("SSL TLSEXT servername callback added");
}

#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
#if !OSSL_IS_LIBRESSL
/*
* It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
* SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
Expand Down Expand Up @@ -1016,7 +1012,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
return v;
}

#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
/*
* call-seq:
* ctx.ciphersuites = "cipher1:cipher2:..."
Expand All @@ -1043,7 +1038,6 @@ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)

return v;
}
#endif

#ifndef OPENSSL_NO_DH
/*
Expand Down Expand Up @@ -2856,9 +2850,7 @@ Init_ossl_ssl(void)
ossl_sslctx_set_minmax_proto_version, 2);
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
#endif
#ifndef OPENSSL_NO_DH
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
#endif
Expand Down Expand Up @@ -2994,36 +2986,34 @@ Init_ossl_ssl(void)
#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
#endif
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1, missing in LibreSSL */
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
#endif
rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
rb_define_const(mSSL, "OP_NO_TICKET", ULONG2NUM(SSL_OP_NO_TICKET));
rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1, missing in LibreSSL */
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
#endif
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1, missing in LibreSSL */
rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
#endif
#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1, missing in LibreSSL */
rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
#endif
#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1, missing in LibreSSL */
rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
#endif
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2));
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
#endif
rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1, missing in LibreSSL */
rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
#endif
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
Expand Down Expand Up @@ -3085,10 +3075,8 @@ Init_ossl_ssl(void)
rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
/* TLS 1.2 */
rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
#ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
/* TLS 1.3 */
rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
#endif


sym_exception = ID2SYM(rb_intern_const("exception"));
Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Init_ossl_x509(void)
#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION) /* OpenSSL 1.1.0, missing in LibreSSL */
DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION);
#endif
#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED) /* OpenSSL 1.1.1, missing in LibreSSL */
DefX509Const(V_ERR_OCSP_VERIFY_NEEDED);
DefX509Const(V_ERR_OCSP_VERIFY_FAILED);
DefX509Const(V_ERR_OCSP_CERT_UNKNOWN);
Expand Down
9 changes: 0 additions & 9 deletions ext/openssl/ossl_x509store.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,15 +357,6 @@ ossl_x509store_add_file(VALUE self, VALUE file)
ossl_raise(eX509StoreError, "X509_STORE_add_lookup");
if (X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1)
ossl_raise(eX509StoreError, "X509_LOOKUP_load_file");
#if !OSSL_OPENSSL_PREREQ(1, 1, 1) && !OSSL_IS_LIBRESSL
/*
* X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
* did not check the return value of X509_STORE_add_{cert,crl}(), leaking
* "cert already in hash table" errors on the error queue, if duplicate
* certificates are found. Fixed by OpenSSL 1.1.1 and LibreSSL 3.5.0.
*/
ossl_clear_error();
#endif

return self;
}
Expand Down
6 changes: 0 additions & 6 deletions test/openssl/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def test_hmac_sign_verify
def test_ed25519
# Ed25519 is not FIPS-approved.
omit_on_fips
omit "Ed25519 not supported" if openssl? && !openssl?(1, 1, 1)

# Test vector from RFC 8032 Section 7.1 TEST 2
priv_pem = <<~EOF
Expand Down Expand Up @@ -157,9 +156,6 @@ def test_x25519
assert_equal bob_pem, bob.public_to_pem
assert_equal [shared_secret].pack("H*"), alice.derive(bob)

if openssl? && !openssl?(1, 1, 1)
omit "running OpenSSL version does not have raw public key support"
end
alice_private = OpenSSL::PKey.new_raw_private_key("X25519", alice.raw_private_key)
bob_public = OpenSSL::PKey.new_raw_public_key("X25519", bob.raw_public_key)
assert_equal alice_private.private_to_pem,
Expand All @@ -173,8 +169,6 @@ def test_x25519
end

def test_raw_initialize_errors
omit "Ed25519 not supported" if openssl? && !openssl?(1, 1, 1)

assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("foo123", "xxx") }
assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("ED25519", "xxx") }
assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_public_key("foo123", "xxx") }
Expand Down
2 changes: 1 addition & 1 deletion test/openssl/test_pkey_dh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def test_params_ok?
# applying the following commits in OpenSSL 1.1.1d to make `DH_check`
# function pass the RFC 7919 FFDHE group texts.
# https://github.com/openssl/openssl/pull/9435
unless openssl?(1, 1, 1, 4)
if openssl? && !openssl?(1, 1, 1, 4)
pend 'DH check for RFC 7919 FFDHE group texts is not implemented'
end

Expand Down
Loading

0 comments on commit 050f0c6

Please sign in to comment.