summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-08 06:09:40 +0000
committernahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-08 06:09:40 +0000
commit2cb7a6c0569cf2f1da791f21f6af4ff9bfcb97ac (patch)
tree1467ad0000a906cad6bc131eb81263519ffd5478
parente19bd3eaa8bd71cfc9e5bf436527f015b093f31e (diff)
downloadruby-2cb7a6c0569cf2f1da791f21f6af4ff9bfcb97ac.tar.gz
Backport r34482 from trunk. See #5353
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@34486 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog31
-rw-r--r--ext/openssl/ossl_ssl.c31
-rw-r--r--test/openssl/test_ssl.rb15
-rw-r--r--version.h12
4 files changed, 70 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 79cae45dea..a09237e9a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+Wed Feb 8 14:06:59 2012 Hiroshi Nakamura <nahi@ruby-lang.org>
+
+ * ext/openssl/ossl_ssl.c: Add SSL constants and allow to unset SSL
+ option to prevent BEAST attack. See [Bug #5353].
+
+ In OpenSSL, OP_DONT_INSERT_EMPTY_FRAGMENTS is used to prevent
+ TLS-CBC-IV vulunerability described at
+ http://www.openssl.org/~bodo/tls-cbc.txt
+ It's known issue of TLSv1/SSLv3 but it attracts lots of attention
+ these days as BEAST attack. (CVE-2011-3389)
+
+ Until now ossl sets OP_ALL at SSLContext allocation and call
+ SSL_CTX_set_options at connection. SSL_CTX_set_options updates the
+ value by using |= so bits set by OP_ALL cannot be unset afterwards.
+
+ This commit changes to call SSL_CTX_set_options only 1 time for each
+ SSLContext. It sets the specified value if SSLContext#options= are
+ called and sets OP_ALL if not.
+
+ To help users to unset bits in OP_ALL, this commit also adds several
+ constant to SSL such as
+ OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS. These constants were
+ not exposed in Ruby because there's no way to unset bits in OP_ALL
+ before.
+
+ Following is an example to enable 0/n split for BEAST prevention.
+
+ ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
+
+ * test/openssl/test_ssl.rb: Test above option exists.
+
Wed Dec 28 21:34:23 2011 URABE Shyouhei <shyouhei@ruby-lang.org>
* string.c (rb_str_hash): randomize hash to avoid algorithmic
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 668408fd28..00a447d7c1 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -140,7 +140,6 @@ ossl_sslctx_s_alloc(VALUE klass)
ossl_raise(eSSLError, "SSL_CTX_new:");
}
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx);
}
@@ -560,7 +559,11 @@ ossl_sslctx_setup(VALUE self)
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));
val = ossl_sslctx_get_options(self);
- if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val));
+ if(!NIL_P(val)) {
+ SSL_CTX_set_options(ctx, NUM2LONG(val));
+ } else {
+ SSL_CTX_set_options(ctx, SSL_OP_ALL);
+ }
rb_obj_freeze(self);
val = ossl_sslctx_get_sess_id_ctx(self);
@@ -1441,18 +1444,20 @@ Init_ossl_ssl()
ossl_ssl_def_const(VERIFY_PEER);
ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
- /* Not introduce constants included in OP_ALL such as...
- * ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
- * ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
- * ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
- * ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
- * ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
- * ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
- * ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
- * ossl_ssl_def_const(OP_TLS_D5_BUG);
- * ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
- * ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
+ /* Introduce constants included in OP_ALL. These constants are mostly for
+ * unset some bits in OP_ALL such as;
+ * ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
*/
+ ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
+ ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
+ ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
+ ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
+ ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
+ ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
+ ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
+ ossl_ssl_def_const(OP_TLS_D5_BUG);
+ ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
+ ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
ossl_ssl_def_const(OP_ALL);
#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 2caadd1c67..177b684e7f 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -532,6 +532,21 @@ class OpenSSL::TestSSL < Test::Unit::TestCase
end
end
end
+
+ def test_unset_OP_ALL
+ ctx_proc = Proc.new { |ctx|
+ ctx.options = OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
+ }
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true
+ ssl.connect
+ ssl.puts('hello')
+ assert_equal("hello\n", ssl.gets)
+ ssl.close
+ }
+ end
end
end
diff --git a/version.h b/version.h
index 910413eb28..d6f16f5c48 100644
--- a/version.h
+++ b/version.h
@@ -1,15 +1,15 @@
#define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2011-12-28"
+#define RUBY_RELEASE_DATE "2012-02-08"
#define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20111228
-#define RUBY_PATCHLEVEL 357
+#define RUBY_RELEASE_CODE 20120208
+#define RUBY_PATCHLEVEL 358
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 7
-#define RUBY_RELEASE_YEAR 2011
-#define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 28
+#define RUBY_RELEASE_YEAR 2012
+#define RUBY_RELEASE_MONTH 2
+#define RUBY_RELEASE_DAY 8
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];