[前][次][番号順一覧][スレッド一覧]

ruby-changes:43235

From: rhe <ko1@a...>
Date: Tue, 7 Jun 2016 16:52:29 +0900 (JST)
Subject: [ruby-changes:43235] rhe:r55309 (trunk): openssl: add SSL::SSLContext#security_level{=, }

rhe	2016-06-07 16:52:24 +0900 (Tue, 07 Jun 2016)

  New Revision: 55309

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55309

  Log:
    openssl: add SSL::SSLContext#security_level{=,}
    
    * ext/openssl/extconf.rb: Check for SSL_CTX_get_security_level().
      OpenSSL 1.1.0 introduced "security level".
      [ruby-core:75225] [Feature #12324]
    
    * ext/openssl/ossl_ssl.c (ossl_sslctx_{get,set}_security_level): Add
      SSLContext#security_level and #security_level=.
    
    * test/openssl/test_ssl.rb (test_security_level): Add test. ...but this
      doesn't actually test it. Because #security_level= is necessary in
      order to run other tests on OpenSSL 1.1.0, go without tests for now.
      Will fix after converting SSLContext#key= and #cert= to normal methods.

  Modified files:
    trunk/ext/openssl/extconf.rb
    trunk/ext/openssl/ossl_ssl.c
    trunk/test/openssl/test_ssl.rb
Index: ext/openssl/extconf.rb
===================================================================
--- ext/openssl/extconf.rb	(revision 55308)
+++ ext/openssl/extconf.rb	(revision 55309)
@@ -146,6 +146,7 @@ have_func("SSL_SESSION_up_ref") https://github.com/ruby/ruby/blob/trunk/ext/openssl/extconf.rb#L146
 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")
+have_func("SSL_CTX_get_security_level")
 
 Logging::message "=== Checking done. ===\n"
 
Index: ext/openssl/ossl_ssl.c
===================================================================
--- ext/openssl/ossl_ssl.c	(revision 55308)
+++ ext/openssl/ossl_ssl.c	(revision 55309)
@@ -1073,6 +1073,68 @@ ossl_sslctx_set_ecdh_curves(VALUE self, https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1073
 #endif
 
 /*
+ * call-seq:
+ *    ctx.security_level -> Integer
+ *
+ * Returns the security level for the context.
+ *
+ * See also OpenSSL::SSL::SSLContext#security_level=.
+ */
+static VALUE
+ossl_sslctx_get_security_level(VALUE self)
+{
+    SSL_CTX *ctx;
+
+    GetSSLCTX(self, ctx);
+
+#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
+    return INT2FIX(SSL_CTX_get_security_level(ctx));
+#else
+    (void)ctx;
+    return INT2FIX(0);
+#endif
+}
+
+/*
+ * call-seq:
+ *    ctx.security_level=(integer) -> Integer
+ *
+ * Sets the security level for the context. OpenSSL limits parameters according
+ * to the level. The "parameters" include: ciphersuites, curves, key sizes,
+ * certificate signature algorithms, protocol version and so on. For example,
+ * level 1 rejects parameters offering below 80 bits of security, such as
+ * ciphersuites using MD5 for the MAC or RSA keys shorter than 1024 bits.
+ *
+ * Note that attempts to set such parameters with insufficient security are
+ * also blocked. You need to lower the level first.
+ *
+ * This feature is not supported in OpenSSL < 1.1.0, and setting the level to
+ * other than 0 will raise NotImplementedError. Level 0 means everything is
+ * permitted, the same behavior as previous versions of OpenSSL.
+ *
+ * See the manpage of SSL_CTX_set_security_level(3) for details.
+ */
+static VALUE
+ossl_sslctx_set_security_level(VALUE self, VALUE value)
+{
+    SSL_CTX *ctx;
+
+    rb_check_frozen(self);
+    GetSSLCTX(self, ctx);
+
+#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
+    SSL_CTX_set_security_level(ctx, NUM2INT(value));
+#else
+    (void)ctx;
+    if (NUM2INT(value) != 0)
+	ossl_raise(rb_eNotImpError, "setting security level to other than 0 is "
+		   "not supported in this version of OpenSSL");
+#endif
+
+    return value;
+}
+
+/*
  *  call-seq:
  *     ctx.session_add(session) -> true | false
  *
@@ -2387,6 +2449,8 @@ Init_ossl_ssl(void) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L2449
     rb_define_method(cSSLContext, "ciphers",     ossl_sslctx_get_ciphers, 0);
     rb_define_method(cSSLContext, "ciphers=",    ossl_sslctx_set_ciphers, 1);
     rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 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);
 
Index: test/openssl/test_ssl.rb
===================================================================
--- test/openssl/test_ssl.rb	(revision 55308)
+++ test/openssl/test_ssl.rb	(revision 55309)
@@ -1218,6 +1218,22 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1218
     end
   end
 
+  def test_security_level
+    ctx = OpenSSL::SSL::SSLContext.new
+    begin
+      ctx.security_level = 1
+    rescue NotImplementedError
+      assert_equal(0, ctx.security_level)
+      return
+    end
+    assert_equal(1, ctx.security_level)
+    # assert_raise(OpenSSL::SSL::SSLError) { ctx.key = OpenSSL::TestUtils::TEST_KEY_DSA512 }
+    # ctx.key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+    # ctx.security_level = 2
+    # assert_raise(OpenSSL::SSL::SSLError) { ctx.key = OpenSSL::TestUtils::TEST_KEY_RSA1024 }
+    skip "FIXME: SSLContext#key= currently does not raise because SSL_CTX_use_certificate() is delayed"
+  end
+
   private
 
   def start_server_version(version, ctx_proc=nil, server_proc=nil, &blk)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]