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/