aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-04-26 16:29:40 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-04-27 23:07:42 +0900
commit0d0067f3d03ef1bedf0a1e9da66606a381c77d7c (patch)
treec64a746061e4a064180d82395b7d987efa4cf5f8
parente605469019f038a01f385ee65a886a2057fd24f8 (diff)
downloadruby-0d0067f3d03ef1bedf0a1e9da66606a381c77d7c.tar.gz
ext/openssl: add SSLContext#security_level, #security_level=
OpenSSL 1.1.0 introduced "security level" and these methods deal with it. This patch includes many test changes: setting the level to 0. The default security level is 1 and this prohibits aNULL ciphers.
-rw-r--r--ext/openssl/extconf.rb1
-rw-r--r--ext/openssl/ossl_ssl.c55
-rw-r--r--test/openssl/test_pair.rb10
-rw-r--r--test/openssl/test_ssl.rb11
-rw-r--r--test/openssl/utils.rb1
5 files changed, 78 insertions, 0 deletions
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 6f31222..5c3ba84 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -128,6 +128,7 @@ have_func("X509_up_ref")
have_func("X509_CRL_up_ref")
have_func("X509_STORE_up_ref")
have_func("SSL_CTX_get_ciphers")
+have_func("SSL_CTX_get_security_level")
have_func_like("SSL_CTX_set_min_proto_version", "openssl/ssl.h")
have_func("SSL_SESSION_up_ref")
have_func("EVP_PKEY_up_ref")
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 2af2fc0..c4ed305 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -963,6 +963,59 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
}
/*
+ * call-seq:
+ * ctx.security_level => 0, .., 5
+ *
+ * The security level for this context. This is new in OpenSSL 1.1.0 and
+ * always returns 0 if using older OpenSSL.
+ */
+static VALUE
+ossl_sslctx_get_security_level(VALUE self)
+{
+ SSL_CTX *ctx;
+ int i;
+
+ GetSSLCTX(self, ctx);
+ if (!ctx) {
+ rb_warning("SSL_CTX is not initialized.");
+ return Qnil;
+ }
+
+#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
+ i = SSL_CTX_get_security_level(ctx);
+#else
+ i = 0;
+#endif
+ return INT2FIX(i);
+}
+
+/*
+ * call-seq:
+ * ctx.security_level = 0
+ * ctx.security_level = 5
+ *
+ * Sets the security level for this context. This is new in OpenSSL 1.1.0 and
+ * no-op if using older OpenSSL.
+ */
+static VALUE
+ossl_sslctx_set_security_level(VALUE self, VALUE v)
+{
+ SSL_CTX *ctx;
+
+ rb_check_frozen(self);
+
+ GetSSLCTX(self, ctx);
+ if (!ctx)
+ ossl_raise(eSSLError, "SSL_CTX is not initialized.");
+
+#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
+ SSL_CTX_set_security_level(ctx, NUM2INT(v));
+#endif
+
+ return v;
+}
+
+/*
* call-seq:
* ctx.session_add(session) -> true | false
*
@@ -2230,6 +2283,8 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
+ rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
+ rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index 06c3444..7f1a25d 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -12,6 +12,7 @@ module OpenSSL::SSLPairM
port = 0
ctx = OpenSSL::SSL::SSLContext.new()
ctx.ciphers = "ADH"
+ ctx.security_level = 0
ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
tcps = create_tcp_server(host, port)
ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
@@ -22,6 +23,7 @@ module OpenSSL::SSLPairM
host = "127.0.0.1"
ctx = OpenSSL::SSL::SSLContext.new()
ctx.ciphers = "ADH"
+ ctx.security_level = 0
s = create_tcp_client(host, port)
ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
ssl.connect
@@ -324,6 +326,7 @@ module OpenSSL::TestPairM
def test_connect_works_when_setting_dh_callback_to_nil
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
+ ctx2.security_level = 0
ctx2.tmp_dh_callback = nil
sock1, sock2 = tcp_pair
s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
@@ -331,6 +334,7 @@ module OpenSSL::TestPairM
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
ctx1.tmp_dh_callback = nil
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
t = Thread.new { s1.connect }
@@ -350,12 +354,14 @@ module OpenSSL::TestPairM
def test_connect_without_setting_dh_callback
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
+ ctx2.security_level = 0
sock1, sock2 = tcp_pair
s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
accepted = s2.accept_nonblock(exception: false)
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
t = Thread.new { s1.connect }
@@ -420,6 +426,7 @@ module OpenSSL::TestPairM
def test_connect_accept_nonblock_no_exception
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "ADH"
+ ctx2.security_level = 0
ctx2.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
sock1, sock2 = tcp_pair
@@ -430,6 +437,7 @@ module OpenSSL::TestPairM
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "ADH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
th = Thread.new do
rets = []
@@ -468,6 +476,7 @@ module OpenSSL::TestPairM
def test_connect_accept_nonblock
ctx = OpenSSL::SSL::SSLContext.new()
ctx.ciphers = "ADH"
+ ctx.security_level = 0
ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
sock1, sock2 = tcp_pair
@@ -491,6 +500,7 @@ module OpenSSL::TestPairM
sleep 0.1
ctx = OpenSSL::SSL::SSLContext.new()
ctx.ciphers = "ADH"
+ ctx.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx)
begin
sleep 0.2
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 6e9078d..5314853 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -424,6 +424,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
start_server(OpenSSL::SSL::VERIFY_NONE, true, {use_anon_cipher: true}){|server, port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ciphers = "aNULL"
+ ctx.security_level = 0
server_connect(port, ctx) { |ssl|
msg = "Peer verification enabled, but no certificate received. Anonymous cipher suite " \
"ADH-AES256-GCM-SHA384 was negotiated. Anonymous suites must be disabled to use peer verification."
@@ -687,6 +688,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx3 = OpenSSL::SSL::SSLContext.new
ctx3.ciphers = "DH"
+ ctx3.security_level = 0
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
@@ -698,6 +700,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
@@ -720,6 +723,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
+ ctx2.security_level = 0
ctx2.servername_cb = lambda { |args| Object.new }
sock1, sock2 = socketpair
@@ -728,6 +732,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
@@ -752,6 +757,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx3 = OpenSSL::SSL::SSLContext.new
ctx3.ciphers = "DH"
+ ctx3.security_level = 0
assert_not_predicate ctx3, :frozen?
ctx2 = OpenSSL::SSL::SSLContext.new
@@ -764,6 +770,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
@@ -785,6 +792,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
+ ctx2.security_level = 0
ctx2.servername_cb = lambda { |args| nil }
sock1, sock2 = socketpair
@@ -793,6 +801,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
@@ -815,6 +824,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
+ ctx2.security_level = 0
ctx2.servername_cb = lambda do |args|
cb_socket = args[0]
lambda_called = args[1]
@@ -827,6 +837,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"
+ ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index 02bafb6..a4340e7 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -273,6 +273,7 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
ctx = OpenSSL::SSL::SSLContext.new
ctx.ciphers = "ADH-AES256-GCM-SHA384" if use_anon_cipher
+ ctx.security_level = 0 if use_anon_cipher
ctx.cert_store = store
#ctx.extra_chain_cert = [ ca_cert ]
ctx.cert = @svr_cert