Date: Sat, 7 Nov 2009 16:43:47 +0300 (MSK) From: Eygene Ryabinkin <rea-fbsd@codelabs.ru> To: FreeBSD-gnats-submit@FreeBSD.org Cc: freebsd-security@FreeBSD.org, secteam@FreeBSD.org, simon@FreeBSD.org, miwi@FreeBSD.org Subject: bin/140356: [patch] OpenSSL in base: fix CVE-2009-3555 Message-ID: <20091107134347.418A4B8035@phoenix.codelabs.ru> Resent-Message-ID: <200911071350.nA7Do1wE063389@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 140356 >Category: bin >Synopsis: [patch] OpenSSL in base: fix CVE-2009-3555 >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Nov 07 13:50:00 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Eygene Ryabinkin >Release: FreeBSD 8.0-BETA2 amd64 >Organization: Code Labs >Environment: System: FreeBSD 8.0-BETA2 amd64 >Description: See [1] (not much information just now) and [2]. >How-To-Repeat: [1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555 [2] http://cvs.openssl.org/fileview?f=openssl-web/news/announce.txt&v=1.52 >Fix: The following patch applies to OpenSSL both from HEAD and 8-STABLE. It completely disables renegotiation inside TLS/SSL sessions and I had verified that no renegotiations will take place with s_client and s_server. --- fix-cve-2009-3555.diff begins here --- >From 01c641ca1a88d08fea282f79ff0f1a86d5319ba7 Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin <rea-fbsd@codelabs.ru> Date: Sat, 7 Nov 2009 15:45:32 +0300 Obtained-From: http://cvs.openssl.org/chngview?cn=18791 Obtained-From: http://cvs.openssl.org/chngview?cn=18794 Signed-off-by: Eygene Ryabinkin <rea-fbsd@codelabs.ru> --- crypto/openssl/CHANGES | 9 +++++++++ crypto/openssl/ssl/s3_lib.c | 3 +++ crypto/openssl/ssl/s3_pkt.c | 4 +++- crypto/openssl/ssl/s3_srvr.c | 8 ++++++++ crypto/openssl/ssl/ssl.h | 1 + crypto/openssl/ssl/ssl3.h | 9 +++++---- crypto/openssl/ssl/ssl_err.c | 1 + 7 files changed, 30 insertions(+), 5 deletions(-) diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES index 04d332e..cd445c9 100644 --- a/crypto/openssl/CHANGES +++ b/crypto/openssl/CHANGES @@ -2,6 +2,15 @@ OpenSSL CHANGES _______________ + Changes between 0.9.8k and 0.9.8l [5 Nov 2009] + + *) Disable renegotiation completely - this fixes a severe security + problem at the cost of breaking all renegotiation. Renegotiation + can be re-enabled by setting + OPENSSL_ENABLE_UNSAFE_LEGACY_SESSION_RENEGOTATION at + compile-time. This is really not recommended. + [Ben Laurie] + Changes between 0.9.8j and 0.9.8k [25 Mar 2009] *) Don't set val to NULL when freeing up structures, it is freed up by diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c index 8916a0b..5aa7bb2 100644 --- a/crypto/openssl/ssl/s3_lib.c +++ b/crypto/openssl/ssl/s3_lib.c @@ -2592,6 +2592,9 @@ int ssl3_renegotiate(SSL *s) if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) return(0); + if (!(s->s3->flags & SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) + return(0); + s->s3->renegotiate=1; return(1); } diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c index 9476dcd..b98b840 100644 --- a/crypto/openssl/ssl/s3_pkt.c +++ b/crypto/openssl/ssl/s3_pkt.c @@ -985,6 +985,7 @@ start: if (SSL_is_init_finished(s) && !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + (s->s3->flags & SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && !s->s3->renegotiate) { ssl3_renegotiate(s); @@ -1117,7 +1118,8 @@ start: if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + (s->s3->flags & SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { #if 0 /* worked only because C operator preferences are not as expected (and * because this is not really needed for clients except for detecting diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c index 80b45eb..79f3706 100644 --- a/crypto/openssl/ssl/s3_srvr.c +++ b/crypto/openssl/ssl/s3_srvr.c @@ -718,6 +718,14 @@ int ssl3_get_client_hello(SSL *s) #endif STACK_OF(SSL_CIPHER) *ciphers=NULL; + if (s->new_session + && !(s->s3->flags&SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto f_err; + } + /* We do this so that we will respond with our native type. * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, * This down switching should be handled by a different method. diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h index ff8a128..5ef11a3 100644 --- a/crypto/openssl/ssl/ssl.h +++ b/crypto/openssl/ssl/ssl.h @@ -1952,6 +1952,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 #define SSL_R_NO_PROTOCOLS_AVAILABLE 191 #define SSL_R_NO_PUBLICKEY 192 +#define SSL_R_NO_RENEGOTIATION 318 #define SSL_R_NO_SHARED_CIPHER 193 #define SSL_R_NO_VERIFY_CALLBACK 194 #define SSL_R_NULL_SSL_CTX 195 diff --git a/crypto/openssl/ssl/ssl3.h b/crypto/openssl/ssl/ssl3.h index 4b1e2e9..a1a19cb 100644 --- a/crypto/openssl/ssl/ssl3.h +++ b/crypto/openssl/ssl/ssl3.h @@ -326,10 +326,11 @@ typedef struct ssl3_buffer_st #define SSL3_CT_NUMBER 7 -#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 -#define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 -#define SSL3_FLAGS_POP_BUFFER 0x0004 -#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +#define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 +#define SSL3_FLAGS_POP_BUFFER 0x0004 +#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0010 typedef struct ssl3_state_st { diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c index 24a994f..ce2a555 100644 --- a/crypto/openssl/ssl/ssl_err.c +++ b/crypto/openssl/ssl/ssl_err.c @@ -384,6 +384,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"}, {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"}, {ERR_REASON(SSL_R_NO_PUBLICKEY) ,"no publickey"}, +{ERR_REASON(SSL_R_NO_RENEGOTIATION) ,"no renegotiation"}, {ERR_REASON(SSL_R_NO_SHARED_CIPHER) ,"no shared cipher"}, {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) ,"no verify callback"}, {ERR_REASON(SSL_R_NULL_SSL_CTX) ,"null ssl ctx"}, -- 1.6.3.1 --- fix-cve-2009-3555.diff ends here --- It will be very good if __FreeBSD_version will be bumped after this update, because there are some fixes for the ports that use OpenSSL, but disable renegotiation by themselves. These fixes shouldn't be applied when system OpenSSL will be updated (port was already updated to 0.9.8k). >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091107134347.418A4B8035>