Skip to content

Commit 2cb7a6c

Browse files
author
nahi
committed
Backport r34482 from trunk. See ruby#5353
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@34486 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent e19bd3e commit 2cb7a6c

File tree

4 files changed

+70
-19
lines changed

4 files changed

+70
-19
lines changed

ChangeLog

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
Wed Feb 8 14:06:59 2012 Hiroshi Nakamura <nahi@ruby-lang.org>
2+
3+
* ext/openssl/ossl_ssl.c: Add SSL constants and allow to unset SSL
4+
option to prevent BEAST attack. See [Bug #5353].
5+
6+
In OpenSSL, OP_DONT_INSERT_EMPTY_FRAGMENTS is used to prevent
7+
TLS-CBC-IV vulunerability described at
8+
http://www.openssl.org/~bodo/tls-cbc.txt
9+
It's known issue of TLSv1/SSLv3 but it attracts lots of attention
10+
these days as BEAST attack. (CVE-2011-3389)
11+
12+
Until now ossl sets OP_ALL at SSLContext allocation and call
13+
SSL_CTX_set_options at connection. SSL_CTX_set_options updates the
14+
value by using |= so bits set by OP_ALL cannot be unset afterwards.
15+
16+
This commit changes to call SSL_CTX_set_options only 1 time for each
17+
SSLContext. It sets the specified value if SSLContext#options= are
18+
called and sets OP_ALL if not.
19+
20+
To help users to unset bits in OP_ALL, this commit also adds several
21+
constant to SSL such as
22+
OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS. These constants were
23+
not exposed in Ruby because there's no way to unset bits in OP_ALL
24+
before.
25+
26+
Following is an example to enable 0/n split for BEAST prevention.
27+
28+
ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
29+
30+
* test/openssl/test_ssl.rb: Test above option exists.
31+
132
Wed Dec 28 21:34:23 2011 URABE Shyouhei <shyouhei@ruby-lang.org>
233

334
* string.c (rb_str_hash): randomize hash to avoid algorithmic

ext/openssl/ossl_ssl.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ ossl_sslctx_s_alloc(VALUE klass)
140140
ossl_raise(eSSLError, "SSL_CTX_new:");
141141
}
142142
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
143-
SSL_CTX_set_options(ctx, SSL_OP_ALL);
144143
return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx);
145144
}
146145

@@ -560,7 +559,11 @@ ossl_sslctx_setup(VALUE self)
560559
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));
561560

562561
val = ossl_sslctx_get_options(self);
563-
if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val));
562+
if(!NIL_P(val)) {
563+
SSL_CTX_set_options(ctx, NUM2LONG(val));
564+
} else {
565+
SSL_CTX_set_options(ctx, SSL_OP_ALL);
566+
}
564567
rb_obj_freeze(self);
565568

566569
val = ossl_sslctx_get_sess_id_ctx(self);
@@ -1441,18 +1444,20 @@ Init_ossl_ssl()
14411444
ossl_ssl_def_const(VERIFY_PEER);
14421445
ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
14431446
ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
1444-
/* Not introduce constants included in OP_ALL such as...
1445-
* ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
1446-
* ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
1447-
* ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
1448-
* ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
1449-
* ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
1450-
* ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
1451-
* ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
1452-
* ossl_ssl_def_const(OP_TLS_D5_BUG);
1453-
* ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
1454-
* ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
1447+
/* Introduce constants included in OP_ALL. These constants are mostly for
1448+
* unset some bits in OP_ALL such as;
1449+
* ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
14551450
*/
1451+
ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
1452+
ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
1453+
ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
1454+
ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
1455+
ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
1456+
ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
1457+
ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
1458+
ossl_ssl_def_const(OP_TLS_D5_BUG);
1459+
ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
1460+
ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
14561461
ossl_ssl_def_const(OP_ALL);
14571462
#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
14581463
ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);

test/openssl/test_ssl.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,21 @@ def test_server_session
532532
end
533533
end
534534
end
535+
536+
def test_unset_OP_ALL
537+
ctx_proc = Proc.new { |ctx|
538+
ctx.options = OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
539+
}
540+
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc){|server, port|
541+
sock = TCPSocket.new("127.0.0.1", port)
542+
ssl = OpenSSL::SSL::SSLSocket.new(sock)
543+
ssl.sync_close = true
544+
ssl.connect
545+
ssl.puts('hello')
546+
assert_equal("hello\n", ssl.gets)
547+
ssl.close
548+
}
549+
end
535550
end
536551

537552
end

version.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#define RUBY_VERSION "1.8.7"
2-
#define RUBY_RELEASE_DATE "2011-12-28"
2+
#define RUBY_RELEASE_DATE "2012-02-08"
33
#define RUBY_VERSION_CODE 187
4-
#define RUBY_RELEASE_CODE 20111228
5-
#define RUBY_PATCHLEVEL 357
4+
#define RUBY_RELEASE_CODE 20120208
5+
#define RUBY_PATCHLEVEL 358
66

77
#define RUBY_VERSION_MAJOR 1
88
#define RUBY_VERSION_MINOR 8
99
#define RUBY_VERSION_TEENY 7
10-
#define RUBY_RELEASE_YEAR 2011
11-
#define RUBY_RELEASE_MONTH 12
12-
#define RUBY_RELEASE_DAY 28
10+
#define RUBY_RELEASE_YEAR 2012
11+
#define RUBY_RELEASE_MONTH 2
12+
#define RUBY_RELEASE_DAY 8
1313

1414
#ifdef RUBY_EXTERN
1515
RUBY_EXTERN const char ruby_version[];

0 commit comments

Comments
 (0)