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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55309 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
rhe 2016-06-07 07:52:24 +00:00
Родитель 53a3e3ddd9
Коммит 1f5784ecaf
3 изменённых файлов: 81 добавлений и 0 удалений

Просмотреть файл

@ -146,6 +146,7 @@ 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")
have_func("SSL_CTX_get_security_level")
Logging::message "=== Checking done. ===\n"

Просмотреть файл

@ -1072,6 +1072,68 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
#define ossl_sslctx_set_ecdh_curves rb_f_notimplement
#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)
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);

Просмотреть файл

@ -1218,6 +1218,22 @@ end
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)