summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-06-07 05:57:25 +0000
committerrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-06-07 05:57:25 +0000
commit74c38e5d9cd7efe904f7cb99b047f386c5d46581 (patch)
treeaee7e9ad37c510845d8869a236c4d43a26ea3e32
parent04e1badd381297a92e9fc7fb3877f9b0305809a7 (diff)
openssl: avoid deprecated version-specific ssl methods if necessary
* ext/openssl/extconf.rb: Check for SSL_CTX_set_min_proto_version() macro added in OpenSSL 1.1.0. Version-specific methods, such as TLSv1_method(), are deprecated in OpenSSL 1.1.0. We need to use version-flexible methods (TLS_*method() or SSLv23_*method()) and disable other protocol versions as necessary. [ruby-core:75225] [Feature #12324] * ext/openssl/ossl_ssl.c: Use SSL_CTX_set_{min,max}_proto_version() to fix the protocol version. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55304 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--ext/openssl/extconf.rb1
-rw-r--r--ext/openssl/ossl_ssl.c75
3 files changed, 53 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index eddda6252e..75ef68b516 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Tue Jun 7 14:57:09 2016 Kazuki Yamaguchi <k@rhe.jp>
+
+ * ext/openssl/extconf.rb: Check for SSL_CTX_set_min_proto_version()
+ macro added in OpenSSL 1.1.0. Version-specific methods, such as
+ TLSv1_method(), are deprecated in OpenSSL 1.1.0. We need to use
+ version-flexible methods (TLS_*method() or SSLv23_*method()) and
+ disable other protocol versions as necessary.
+ [ruby-core:75225] [Feature #12324]
+
+ * ext/openssl/ossl_ssl.c: Use SSL_CTX_set_{min,max}_proto_version() to
+ fix the protocol version.
+
Tue Jun 7 12:55:34 2016 Martin Duerst <duerst@it.aoyama.ac.jp>
* regenc.c (onigenc_not_support_case_map): Move to end of file;
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index a74774c761..f5a6d8e87c 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -145,6 +145,7 @@ have_func("X509_STORE_up_ref")
have_func("SSL_SESSION_up_ref")
have_func("EVP_PKEY_up_ref")
OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed
+OpenSSL.check_func_or_macro("SSL_CTX_set_min_proto_version", "openssl/ssl.h")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 5fcebb9e91..af0ab6d64e 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -88,35 +88,34 @@ static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
*/
static const struct {
const char *name;
- SSL_METHOD *(*func)(void);
+ SSL_METHOD *(*func)(void); /* FIXME: constify when dropping 0.9.8 */
+ int version;
} ossl_ssl_method_tab[] = {
-#define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
- OSSL_SSL_METHOD_ENTRY(TLSv1),
- OSSL_SSL_METHOD_ENTRY(TLSv1_server),
- OSSL_SSL_METHOD_ENTRY(TLSv1_client),
-#if defined(HAVE_TLSV1_2_METHOD)
- OSSL_SSL_METHOD_ENTRY(TLSv1_2),
- OSSL_SSL_METHOD_ENTRY(TLSv1_2_server),
- OSSL_SSL_METHOD_ENTRY(TLSv1_2_client),
-#endif
-#if defined(HAVE_TLSV1_1_METHOD)
- OSSL_SSL_METHOD_ENTRY(TLSv1_1),
- OSSL_SSL_METHOD_ENTRY(TLSv1_1_server),
- OSSL_SSL_METHOD_ENTRY(TLSv1_1_client),
+#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
+#define OSSL_SSL_METHOD_ENTRY(name, version) \
+ { #name, (SSL_METHOD *(*)(void))TLS_method, version }, \
+ { #name"_server", (SSL_METHOD *(*)(void))TLS_server_method, version }, \
+ { #name"_client", (SSL_METHOD *(*)(void))TLS_client_method, version }
+#else
+#define OSSL_SSL_METHOD_ENTRY(name, version) \
+ { #name, (SSL_METHOD *(*)(void))name##_method, version }, \
+ { #name"_server", (SSL_METHOD *(*)(void))name##_server_method, version }, \
+ { #name"_client", (SSL_METHOD *(*)(void))name##_client_method, version }
#endif
#if defined(HAVE_SSLV2_METHOD)
- OSSL_SSL_METHOD_ENTRY(SSLv2),
- OSSL_SSL_METHOD_ENTRY(SSLv2_server),
- OSSL_SSL_METHOD_ENTRY(SSLv2_client),
+ OSSL_SSL_METHOD_ENTRY(SSLv2, SSL2_VERSION),
#endif
#if defined(HAVE_SSLV3_METHOD)
- OSSL_SSL_METHOD_ENTRY(SSLv3),
- OSSL_SSL_METHOD_ENTRY(SSLv3_server),
- OSSL_SSL_METHOD_ENTRY(SSLv3_client),
+ OSSL_SSL_METHOD_ENTRY(SSLv3, SSL3_VERSION),
#endif
- OSSL_SSL_METHOD_ENTRY(SSLv23),
- OSSL_SSL_METHOD_ENTRY(SSLv23_server),
- OSSL_SSL_METHOD_ENTRY(SSLv23_client),
+ OSSL_SSL_METHOD_ENTRY(TLSv1, TLS1_VERSION),
+#if defined(HAVE_TLSV1_1_METHOD)
+ OSSL_SSL_METHOD_ENTRY(TLSv1_1, TLS1_1_VERSION),
+#endif
+#if defined(HAVE_TLSV1_2_METHOD)
+ OSSL_SSL_METHOD_ENTRY(TLSv1_2, TLS1_2_VERSION),
+#endif
+ OSSL_SSL_METHOD_ENTRY(SSLv23, 0),
#undef OSSL_SSL_METHOD_ENTRY
};
@@ -189,30 +188,36 @@ ossl_sslctx_s_alloc(VALUE klass)
static VALUE
ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
{
- SSL_METHOD *method = NULL;
+ SSL_CTX *ctx;
const char *s;
VALUE m = ssl_method;
int i;
- SSL_CTX *ctx;
+ GetSSLCTX(self, ctx);
if (RB_TYPE_P(ssl_method, T_SYMBOL))
m = rb_sym2str(ssl_method);
s = StringValueCStr(m);
for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
- method = ossl_ssl_method_tab[i].func();
- break;
+#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
+ int version = ossl_ssl_method_tab[i].version;
+#endif
+ SSL_METHOD *method = ossl_ssl_method_tab[i].func();
+
+ if (SSL_CTX_set_ssl_version(ctx, method) != 1)
+ ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
+
+#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
+ if (!SSL_CTX_set_min_proto_version(ctx, version))
+ ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
+ if (!SSL_CTX_set_max_proto_version(ctx, version))
+ ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
+#endif
+ return ssl_method;
}
}
- if (!method) {
- ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
- }
- GetSSLCTX(self, ctx);
- if (SSL_CTX_set_ssl_version(ctx, method) != 1) {
- ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
- }
- return ssl_method;
+ ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
}
static VALUE