Add SA-14:14.openssl.

This commit is contained in:
Xin LI 2014-06-05 13:03:07 +00:00
parent 7832d2830b
commit 05be27dd8f
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=45011
6 changed files with 493 additions and 0 deletions

View file

@ -0,0 +1,170 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-14:14.openssl Security Advisory
The FreeBSD Project
Topic: OpenSSL multiple vulnerabilities
Category: contrib
Module: openssl
Announced: 2014-06-05
Affects: All supported versions of FreeBSD.
Corrected: 2014-06-05 12:32:38 UTC (stable/10, 10.0-STABLE)
2014-06-05 12:33:23 UTC (releng/10.0, 10.0-RELEASE-p5)
2014-06-05 12:53:06 UTC (stable/9, 9.3-BETA1)
2014-06-05 12:53:06 UTC (stable/9, 9.3-BETA1-p2)
2014-06-05 12:33:23 UTC (releng/9.2, 9.2-RELEASE-p8)
2014-06-05 12:33:23 UTC (releng/9.1, 9.1-RELEASE-p15)
2014-06-05 12:32:38 UTC (stable/8, 8.4-STABLE)
2014-06-05 12:33:23 UTC (releng/8.4, 8.4-RELEASE-p12)
CVE Name: CVE-2014-0195, CVE-2014-0221, CVE-2014-0224, CVE-2014-3470
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:http://security.FreeBSD.org/>.
I. Background
FreeBSD includes software from the OpenSSL Project. The OpenSSL Project is
a collaborative effort to develop a robust, commercial-grade, full-featured
Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3)
and Transport Layer Security (TLS v1) protocols as well as a full-strength
general purpose cryptography library.
II. Problem Description
Receipt of an invalid DTLS fragment on an OpenSSL DTLS client or server can
lead to a buffer overrun. [CVE-2014-0195]
Receipt of an invalid DTLS handshake on an OpenSSL DTLS client can lead the
code to unnecessary recurse. [CVE-2014-0221]
Carefully crafted handshake can force the use of weak keying material in
OpenSSL SSL/TLS clients and servers. [CVE-2014-0224]
Carefully crafted packets can lead to a NULL pointer deference in OpenSSL
TLS client code if anonymous ECDH ciphersuites are enabled. [CVE-2014-3470]
III. Impact
A remote attacker may be able to run arbitrary code on a vulnerable client
or server by sending invalid DTLS fragments to an OpenSSL DTLS client or
server. [CVE-2014-0195]
A remote attacker who can send an invalid DTLS handshake to an OpenSSL DTLS
client can crash the remote OpenSSL DTLS client. [CVE-2014-0221]
A remote attacker who can send a carefully crafted handshake can force the
use of weak keying material between a vulnerable client and a vulnerable
server and decrypt and/or modify traffic from the attacked client and
server in a man-in-the-middle (MITM) attack. [CVE-2014-0224]
A remote attacker who can send carefully crafted packets can cause OpenSSL
TLS client to crash. [CVE-2014-3470]
IV. Workaround
No workaround is available.
V. Solution
Perform one of the following:
1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
[FreeBSD 10.0]
# fetch http://security.FreeBSD.org/patches/SA-14:14/openssl-10.patch
# fetch http://security.FreeBSD.org/patches/SA-14:14/openssl-10.patch.asc
# gpg --verify openssl-10.patch.asc
[FreeBSD 9.x and 8.x]
# fetch http://security.FreeBSD.org/patches/SA-14:14/openssl-9.patch
# fetch http://security.FreeBSD.org/patches/SA-14:14/openssl-9.patch.asc
# gpg --verify openssl-9.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile the operating system using buildworld and installworld as
described in <URL:http://www.FreeBSD.org/handbook/makeworld.html>.
Restart all deamons using the library, or reboot the system.
3) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/8/ r267103
releng/8.4/ r267104
stable/9/ r267106
releng/9.1/ r267104
releng/9.2/ r267104
stable/10/ r267103
releng/10.0/ r267104
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:http://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:www.openssl.org/news/secadv_20140605.txt>
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0195>
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0221>
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224>
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3470>
The latest revision of this advisory is available at
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-14:14.openssl.asc>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAEBCgAGBQJTkGnKAAoJEO1n7NZdz2rnlrgP/RkNkf0qryF34plltoTsy2P9
uxC1fWAwpPcCCmC6hwGMFOCyNPsxgXNTGk8HDJYwEoNyrgyf5l26P/1KZisNaGWf
JFyjR2Fd5N78AxXdkldp6O3hgMSF6HZtYDxMywVC6q9+hEJsFzgd2B/8fihoP9SO
2f1othqvCAxnMZ9Ts0xQxfl+mcj5Zg0XmApakziPQiEbejOj1k5k9wBHo1O3GFF4
kWaFEsArqv+UNSTRZ0m/8oRYgElKwCyVGTPr9mPxG1kIYh9WS44remGYc3kkO77Z
+gbzOSMHwEtf/PvIySl90EAkW8XlUWyd+2gTuVSAdm5WlDWArQaauJVHiUwysiOe
nNEhsdSSQcIKHIyOMu486HzSyHP401AQ7jTlJmMHg4IXtsiM0O8lUigk6nCq/zUr
ywYKm1/PHffAlHx2y1c5vP9F8Bun8wMUxYnHFI7FD++jklEZQ1EGEloqLd5RvLDM
6CP8LYg6+zwpmDVbrAs8MBhdug8m6Xd7lACzwO6P02vYXWZGZM3zAbQqTYGag1kp
YTQl/ix4GFIFtuV4qjg8FOwQyqXBp2n9hHKwtXAv4okDRdk8GcxzOFENFSsxhj6Q
8XuoMaX/9EwNi7jteYUsSLhKin0gE3mjTCvzO+d6DLiPS+o8uMXGrE9kt5ww6NHP
XEFCK00JfXunW1wmkcN3
=o4+e
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,146 @@
Index: crypto/openssl/ssl/d1_both.c
===================================================================
--- crypto/openssl/ssl/d1_both.c (revision 267031)
+++ crypto/openssl/ssl/d1_both.c (working copy)
@@ -627,8 +627,17 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header
frag->msg_header.frag_off = 0;
}
else
+ {
frag = (hm_fragment*) item->data;
+ if (frag->msg_header.msg_len != msg_hdr->msg_len)
+ {
+ item = NULL;
+ frag = NULL;
+ goto err;
+ }
+ }
+
/* If message is already reassembled, this must be a
* retransmit and can be dropped.
*/
@@ -784,6 +793,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int st
int i,al;
struct hm_header_st msg_hdr;
+ redo:
/* see if we have the required fragment already */
if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
{
@@ -842,8 +852,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int st
s->msg_callback_arg);
s->init_num = 0;
- return dtls1_get_message_fragment(s, st1, stn,
- max, ok);
+ goto redo;
}
else /* Incorrectly formated Hello request */
{
Index: crypto/openssl/ssl/s3_clnt.c
===================================================================
--- crypto/openssl/ssl/s3_clnt.c (revision 267031)
+++ crypto/openssl/ssl/s3_clnt.c (working copy)
@@ -559,6 +559,7 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
if (ret <= 0) goto end;
@@ -915,6 +916,7 @@ int ssl3_get_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->hit=1;
}
else /* a miss or crap from the other end */
@@ -2510,6 +2512,13 @@ int ssl3_send_client_key_exchange(SSL *s)
int ecdh_clnt_cert = 0;
int field_size = 0;
+ if (s->session->sess_cert == NULL)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+ goto err;
+ }
+
/* Did we send out the client's
* ECDH share for use in premaster
* computation as part of client certificate?
Index: crypto/openssl/ssl/s3_pkt.c
===================================================================
--- crypto/openssl/ssl/s3_pkt.c (revision 267031)
+++ crypto/openssl/ssl/s3_pkt.c (working copy)
@@ -1301,6 +1301,15 @@ start:
goto f_err;
}
+ if (!(s->s3->flags & SSL3_FLAGS_CCS_OK))
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
+ goto f_err;
+ }
+
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
rr->length=0;
if (s->msg_callback)
@@ -1435,7 +1444,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
if (s->s3->tmp.key_block == NULL)
{
- if (s->session == NULL)
+ if (s->session == NULL || s->session->master_key_length == 0)
{
/* might happen if dtls1_read_bytes() calls this */
SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
Index: crypto/openssl/ssl/s3_srvr.c
===================================================================
--- crypto/openssl/ssl/s3_srvr.c (revision 267031)
+++ crypto/openssl/ssl/s3_srvr.c (working copy)
@@ -673,6 +673,7 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
@@ -700,6 +701,7 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
@@ -770,7 +772,10 @@ int ssl3_accept(SSL *s)
s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
#else
if (s->s3->next_proto_neg_seen)
+ {
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+ }
else
s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
#endif
Index: crypto/openssl/ssl/ssl3.h
===================================================================
--- crypto/openssl/ssl/ssl3.h (revision 267031)
+++ crypto/openssl/ssl/ssl3.h (working copy)
@@ -399,6 +399,7 @@ typedef struct ssl3_buffer_st
* effected, but we can't prevent that.
*/
#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040
+#define SSL3_FLAGS_CCS_OK 0x0080
#ifndef OPENSSL_NO_SSL_INTERN

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAABCgAGBQJTkGnSAAoJEO1n7NZdz2rnnkEQAOu1iaWZHInskbHmwN5bEpSA
66PfKJRO+dT0lfAPzX8NOlgCo/Vy8NR7OMSf5KHhAMz8qBV67FAbj9V8FNra3jp/
u6S9q7ln5HnUhBvia4aLI31vKTINRooPg7fgMXxTG7dWHMa2E9j56q5PXZ5wkTCA
+BsAFKPKpL4ceZ1MXNwm/YQS3HxnEfVWBsPjues9mnNShgZIjz11PlH05zMrJOUB
gi4bru1v7a66ssejz3RQ/zJ0u1IYnVPzVLbAsAyyr8vd71vvzXOLmfgcdvWCcotZ
kPQbIKacAnbtRULyIEFDXHVLGays3u+c33QzQX1M7Pu5QGXymLrpOzpna4aR99Ax
jxB50tT6d0KchOyn3M10bd9MMSyiEv2bCvp3GPdrTM5ouKjYFgsQDoazZubV+Rai
vto2glhQi29oGkj0NuXf13Ijgn0Yu3qJIkJNsTXGzMaEvcIKyHNaGDdDqHOgOiUQ
2EtEmmE79zbnf+3jkT3jjMcU3bxmj1aG+kX/ErK2yWAGVjYsetimCUSu4yT6Pv/+
MKONbGDswMqWAIMWwLUp4kkbDDyQC7eTGB4OFLn1BVg5ol+FRD8VcAHfWasSE1WW
BiAk1TvN9Sp+ZLXZBphNwp8lbm3gwUwTpvs7X81B0RByN7rx7hLBaJ1viW7mMx0K
JV+/Ei2voErvo1J0xd9W
=QTlX
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,135 @@
Index: crypto/openssl/ssl/d1_both.c
===================================================================
--- crypto/openssl/ssl/d1_both.c (revision 267031)
+++ crypto/openssl/ssl/d1_both.c (working copy)
@@ -620,8 +620,17 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header
frag->msg_header.frag_off = 0;
}
else
+ {
frag = (hm_fragment*) item->data;
+ if (frag->msg_header.msg_len != msg_hdr->msg_len)
+ {
+ item = NULL;
+ frag = NULL;
+ goto err;
+ }
+ }
+
/* If message is already reassembled, this must be a
* retransmit and can be dropped.
*/
@@ -777,6 +786,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int st
int i,al;
struct hm_header_st msg_hdr;
+ redo:
/* see if we have the required fragment already */
if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
{
@@ -835,8 +845,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int st
s->msg_callback_arg);
s->init_num = 0;
- return dtls1_get_message_fragment(s, st1, stn,
- max, ok);
+ goto redo;
}
else /* Incorrectly formated Hello request */
{
Index: crypto/openssl/ssl/s3_clnt.c
===================================================================
--- crypto/openssl/ssl/s3_clnt.c (revision 267031)
+++ crypto/openssl/ssl/s3_clnt.c (working copy)
@@ -491,6 +491,7 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
if (ret <= 0) goto end;
@@ -777,6 +778,7 @@ int ssl3_get_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->hit=1;
}
else /* a miss or crap from the other end */
@@ -2170,6 +2172,13 @@ int ssl3_send_client_key_exchange(SSL *s)
int ecdh_clnt_cert = 0;
int field_size = 0;
+ if (s->session->sess_cert == NULL)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+ goto err;
+ }
+
/* Did we send out the client's
* ECDH share for use in premaster
* computation as part of client certificate?
Index: crypto/openssl/ssl/s3_pkt.c
===================================================================
--- crypto/openssl/ssl/s3_pkt.c (revision 267031)
+++ crypto/openssl/ssl/s3_pkt.c (working copy)
@@ -1147,6 +1147,15 @@ start:
goto f_err;
}
+ if (!(s->s3->flags & SSL3_FLAGS_CCS_OK))
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
+ goto f_err;
+ }
+
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
rr->length=0;
if (s->msg_callback)
@@ -1278,7 +1287,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
if (s->s3->tmp.key_block == NULL)
{
- if (s->session == NULL)
+ if (s->session == NULL || s->session->master_key_length == 0)
{
/* might happen if dtls1_read_bytes() calls this */
SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
Index: crypto/openssl/ssl/s3_srvr.c
===================================================================
--- crypto/openssl/ssl/s3_srvr.c (revision 267031)
+++ crypto/openssl/ssl/s3_srvr.c (working copy)
@@ -523,6 +523,7 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
@@ -533,6 +534,7 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
Index: crypto/openssl/ssl/ssl3.h
===================================================================
--- crypto/openssl/ssl/ssl3.h (revision 267031)
+++ crypto/openssl/ssl/ssl3.h (working copy)
@@ -344,6 +344,7 @@ typedef struct ssl3_buffer_st
* effected, but we can't prevent that.
*/
#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040
+#define SSL3_FLAGS_CCS_OK 0x0080
typedef struct ssl3_state_st
{

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAABCgAGBQJTkGnVAAoJEO1n7NZdz2rnaIoP/2bfZoar991IHEBh8Aold0h2
NKG4hfkSwF2wrvewZT0kNaM84XPClx5dWP2AwOMfFgrtzaPzBrVmKCeuUe9yAGNH
GqM+mZfEMdGmqEusYwCLiGz/kcNeXXvrCFhAyQx+bIXa1btDOfQ3F3GVeHG6eihl
kkywL8dBiSYaaVRECeezROnN0+mlXHM//Yt/+QQkPN38fGBfZ1qdxxXo55a9clCT
Iese/UvLp2q/iikMqzXZWcb3uR2y1yvh4RbIfI5kjj3DSMD9QwPr7NDNY37kjC42
2t0xLQFrNX24wrFOqJunQvIG9QE33gYQqAFOjPC2rRGVGD3lqLHsKUN0yWHX7ORx
Bzf6wKqEy3ewI4MquPYbQ/sfMchHQexMu6IrF5CYhcgeMzk5SFGawHS7FtTlnLxT
PrBSdpkr4M7zX0Uv1ztLPyx/iC2MUi9Me7Ic0Sr2nWUyl1wufVRcaqEZhN097nwh
q8FqExzRDOAv+3TdGdf2XIuYKzYNrEFKFs35N23QAvzy0HVYfx3y+y5Ob8SY8Z5d
R8QHhlf/o2mWgJBdbYVbITc9OP5+dyVw/75BgVMemg15PobTSdQUcVfFdR5UDDFY
wy0Vnj/7yAMk/WhRMaZA3aeYWx9J0rgW0CGxNTHbMLttocOk5GmgXUIGmraLlPGR
ETLkxDw92ye270FzKYev
=QENL
-----END PGP SIGNATURE-----

View file

@ -10,6 +10,14 @@
<month>
<name>6</name>
<day>
<name>5</name>
<advisory>
<name>FreeBSD-SA-14:14.openssl</name>
</advisory>
</day>
<day>
<name>3</name>