summaryrefslogtreecommitdiffstats
path: root/net/third_party
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-17 18:52:27 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-17 18:52:27 +0000
commit513276f41ca989762139ccf87852be28d4f54dcc (patch)
treed70b8a76448023905ab11cd98782766a3765c5b2 /net/third_party
parentc1190589fd6d6b77bf11f1d321d0524ba18a7e89 (diff)
downloadchromium_src-513276f41ca989762139ccf87852be28d4f54dcc.zip
chromium_src-513276f41ca989762139ccf87852be28d4f54dcc.tar.gz
chromium_src-513276f41ca989762139ccf87852be28d4f54dcc.tar.bz2
Cap the record layer version number of TLS ClientHello to TLS 1.0
if we don't know what TLS version the server supports. Fix the -p option for the patch commands in applypatches.sh. R=agl@chromium.org,rsleevi@chromium.org BUG=136666 TEST=manual: visit https://cybozulive.com/, https://www.billpaysite.com/, and https://members.mh-frontier.jp/mypage/ on Linux or Mac. The connection should succeed. Review URL: https://chromiumcodereview.appspot.com/10777021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147056 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party')
-rw-r--r--net/third_party/nss/README.chromium5
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh14
-rw-r--r--net/third_party/nss/patches/getchannelinfo.patch6
-rw-r--r--net/third_party/nss/patches/recordlayerversion.patch186
-rw-r--r--net/third_party/nss/ssl/dtls1con.c3
-rw-r--r--net/third_party/nss/ssl/ssl3con.c54
-rw-r--r--net/third_party/nss/ssl/sslimpl.h3
7 files changed, 252 insertions, 19 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index fd4238f..95e7973 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -85,6 +85,11 @@ Patches:
* Don't crash when the SSL keylog file cannot be opened.
patches/sslkeylogerror.patch
+ * Sets the record layer version number of ClientHello to at most TLS 1.0
+ if we don't know what protocol version the server supports.
+ https://bugzilla.mozilla.org/show_bug.cgi?id=774547
+ patches/recordlayerversion.patch
+
Apply the patches to NSS by running the patches/applypatches.sh script. Read
the comments at the top of patches/applypatches.sh for instructions.
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index b586613..b5736ad9 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -3,8 +3,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-# Run this script in the mozilla/security/nss/lib directory in a NSS source
-# tree.
+# Run this script in the mozilla/security/nss/lib/ssl directory in a NSS
+# source tree.
#
# Point patches_dir to the src/net/third_party/nss/patches directory in a
# chromium source tree.
@@ -36,14 +36,16 @@ patch -p5 < $patches_dir/falsestartnpn.patch
patch -p5 < $patches_dir/dhvalues.patch
-patch -p4 < $patches_dir/channelid.patch
+patch -p5 < $patches_dir/channelid.patch
patch -p4 < $patches_dir/dtlssrtp.patch
-patch -p4 < $patches_dir/keylog.patch
+patch -p5 < $patches_dir/keylog.patch
patch -p4 < $patches_dir/getchannelinfo.patch
-patch -p4 < $patches_dir/tlsunique.patch
+patch -p5 < $patches_dir/tlsunique.patch
-patch -p4 < $patches_dir/sslkeylogerror.patch
+patch -p5 < $patches_dir/sslkeylogerror.patch
+
+patch -p4 < $patches_dir/recordlayerversion.patch
diff --git a/net/third_party/nss/patches/getchannelinfo.patch b/net/third_party/nss/patches/getchannelinfo.patch
index 530b7fe..f6bd0e0 100644
--- a/net/third_party/nss/patches/getchannelinfo.patch
+++ b/net/third_party/nss/patches/getchannelinfo.patch
@@ -1,7 +1,7 @@
-Index: ssl/sslinfo.c
+Index: net/third_party/nss/ssl/sslinfo.c
===================================================================
---- ssl/sslinfo.c (revision 142907)
-+++ ssl/sslinfo.c (working copy)
+--- net/third_party/nss/ssl/sslinfo.c (revision 143014)
++++ net/third_party/nss/ssl/sslinfo.c (revision 143015)
@@ -97,11 +97,11 @@
} else if (ss->ssl3.initialized) { /* SSL3 and TLS */
ssl_GetSpecReadLock(ss);
diff --git a/net/third_party/nss/patches/recordlayerversion.patch b/net/third_party/nss/patches/recordlayerversion.patch
new file mode 100644
index 0000000..f43241c
--- /dev/null
+++ b/net/third_party/nss/patches/recordlayerversion.patch
@@ -0,0 +1,186 @@
+Index: net/third_party/nss/ssl/sslimpl.h
+===================================================================
+--- net/third_party/nss/ssl/sslimpl.h (revision 146623)
++++ net/third_party/nss/ssl/sslimpl.h (working copy)
+@@ -294,6 +294,8 @@
+ #define ssl_SEND_FLAG_NO_BUFFER 0x20000000
+ #define ssl_SEND_FLAG_USE_EPOCH 0x10000000 /* DTLS only */
+ #define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
++#define ssl_SEND_FLAG_CAP_RECORD_VERSION \
++ 0x04000000 /* TLS only */
+ #define ssl_SEND_FLAG_MASK 0x7f000000
+
+ /*
+@@ -1414,6 +1416,7 @@
+ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
+ PRBool isServer,
+ PRBool isDTLS,
++ PRBool capRecordVersion,
+ SSL3ContentType type,
+ const SSL3Opaque * pIn,
+ PRUint32 contentLen,
+Index: net/third_party/nss/ssl/ssl3con.c
+===================================================================
+--- net/third_party/nss/ssl/ssl3con.c (revision 146623)
++++ net/third_party/nss/ssl/ssl3con.c (working copy)
+@@ -2057,6 +2057,7 @@
+ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
+ PRBool isServer,
+ PRBool isDTLS,
++ PRBool capRecordVersion,
+ SSL3ContentType type,
+ const SSL3Opaque * pIn,
+ PRUint32 contentLen,
+@@ -2216,8 +2217,13 @@
+ wrBuf->buf[11] = MSB(cipherBytes);
+ wrBuf->buf[12] = LSB(cipherBytes);
+ } else {
+- wrBuf->buf[1] = MSB(cwSpec->version);
+- wrBuf->buf[2] = LSB(cwSpec->version);
++ SSL3ProtocolVersion version = cwSpec->version;
++
++ if (capRecordVersion) {
++ version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
++ }
++ wrBuf->buf[1] = MSB(version);
++ wrBuf->buf[2] = LSB(version);
+ wrBuf->buf[3] = MSB(cipherBytes);
+ wrBuf->buf[4] = LSB(cipherBytes);
+ }
+@@ -2247,7 +2253,14 @@
+ * all ciphertext into the pending ciphertext buffer.
+ * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
+ * Forces the use of the provided epoch
+- *
++ * ssl_SEND_FLAG_CAP_RECORD_VERSION
++ * Caps the record layer version number of TLS ClientHello to { 3, 1 }
++ * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
++ * ClientHello.client_version and use the record layer version number
++ * (TLSPlaintext.version) instead when negotiating protocol versions. In
++ * addition, if the record layer version number of ClientHello is { 3, 2 }
++ * (TLS 1.1) or higher, these servers reset the TCP connections. Set this
++ * flag to work around such servers.
+ */
+ PRInt32
+ ssl3_SendRecord( sslSocket * ss,
+@@ -2260,6 +2273,7 @@
+ sslBuffer * wrBuf = &ss->sec.writeBuf;
+ SECStatus rv;
+ PRInt32 totalSent = 0;
++ PRBool capRecordVersion;
+
+ SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
+ SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
+@@ -2268,6 +2282,16 @@
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+
++ capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
++
++ if (capRecordVersion) {
++ /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with
++ * TLS ClientHello. */
++ PORT_Assert(!IS_DTLS(ss));
++ PORT_Assert(type == content_handshake);
++ PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
++ }
++
+ if (ss->ssl3.initialized == PR_FALSE) {
+ /* This can happen on a server if the very first incoming record
+ ** looks like a defective ssl3 record (e.g. too long), and we're
+@@ -2324,7 +2348,8 @@
+
+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+ ss->sec.isServer, IS_DTLS(ss),
+- type, pIn, 1, wrBuf);
++ capRecordVersion, type, pIn,
++ 1, wrBuf);
+ if (rv != SECSuccess)
+ goto spec_locked_loser;
+
+@@ -2337,7 +2362,8 @@
+
+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+ ss->sec.isServer, IS_DTLS(ss),
+- type, pIn + 1, contentLen - 1,
++ capRecordVersion, type,
++ pIn + 1, contentLen - 1,
+ &secondRecord);
+ if (rv == SECSuccess) {
+ PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
+@@ -2349,6 +2375,7 @@
+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+ ss->sec.isServer,
+ IS_DTLS(ss),
++ capRecordVersion,
+ type, pIn,
+ contentLen, wrBuf);
+ } else {
+@@ -2560,6 +2587,8 @@
+ static SECStatus
+ ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
+ {
++ static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
++ ssl_SEND_FLAG_CAP_RECORD_VERSION;
+ PRInt32 rv = SECSuccess;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+@@ -2568,9 +2597,9 @@
+ if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
+ return rv;
+
+- /* only this flag is allowed */
+- PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER));
+- if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) {
++ /* only these flags are allowed */
++ PORT_Assert(!(flags & ~allowedFlags));
++ if ((flags & ~allowedFlags) != 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ } else {
+@@ -3981,8 +4010,10 @@
+ int num_suites;
+ int actual_count = 0;
+ PRBool isTLS = PR_FALSE;
++ PRBool serverVersionKnown = PR_FALSE;
+ PRInt32 total_exten_len = 0;
+ unsigned numCompressionMethods;
++ PRInt32 flags;
+
+ SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
+ ss->fd));
+@@ -4070,6 +4101,7 @@
+ }
+
+ if (sid) {
++ serverVersionKnown = PR_TRUE;
+ SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
+
+ /* Are we attempting a stateless session resume? */
+@@ -4305,7 +4337,11 @@
+ ssl_renegotiation_info_xtn;
+ }
+
+- rv = ssl3_FlushHandshake(ss, 0);
++ flags = 0;
++ if (!serverVersionKnown && !IS_DTLS(ss)) {
++ flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
++ }
++ rv = ssl3_FlushHandshake(ss, flags);
+ if (rv != SECSuccess) {
+ return rv; /* error code set by ssl3_FlushHandshake */
+ }
+Index: net/third_party/nss/ssl/dtls1con.c
+===================================================================
+--- net/third_party/nss/ssl/dtls1con.c (revision 146623)
++++ net/third_party/nss/ssl/dtls1con.c (working copy)
+@@ -834,7 +834,8 @@
+
+ if (cwSpec) {
+ rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
+- type, pIn, contentLen, wrBuf);
++ PR_FALSE, type, pIn, contentLen,
++ wrBuf);
+ } else {
+ PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
diff --git a/net/third_party/nss/ssl/dtls1con.c b/net/third_party/nss/ssl/dtls1con.c
index a020416..a0d4318 100644
--- a/net/third_party/nss/ssl/dtls1con.c
+++ b/net/third_party/nss/ssl/dtls1con.c
@@ -834,7 +834,8 @@ dtls_CompressMACEncryptRecord(sslSocket * ss,
if (cwSpec) {
rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
- type, pIn, contentLen, wrBuf);
+ PR_FALSE, type, pIn, contentLen,
+ wrBuf);
} else {
PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index 1f6def2..e7741a0 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -2057,6 +2057,7 @@ SECStatus
ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
PRBool isServer,
PRBool isDTLS,
+ PRBool capRecordVersion,
SSL3ContentType type,
const SSL3Opaque * pIn,
PRUint32 contentLen,
@@ -2216,8 +2217,13 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
wrBuf->buf[11] = MSB(cipherBytes);
wrBuf->buf[12] = LSB(cipherBytes);
} else {
- wrBuf->buf[1] = MSB(cwSpec->version);
- wrBuf->buf[2] = LSB(cwSpec->version);
+ SSL3ProtocolVersion version = cwSpec->version;
+
+ if (capRecordVersion) {
+ version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
+ }
+ wrBuf->buf[1] = MSB(version);
+ wrBuf->buf[2] = LSB(version);
wrBuf->buf[3] = MSB(cipherBytes);
wrBuf->buf[4] = LSB(cipherBytes);
}
@@ -2247,7 +2253,14 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
* all ciphertext into the pending ciphertext buffer.
* ssl_SEND_FLAG_USE_EPOCH (for DTLS)
* Forces the use of the provided epoch
- *
+ * ssl_SEND_FLAG_CAP_RECORD_VERSION
+ * Caps the record layer version number of TLS ClientHello to { 3, 1 }
+ * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
+ * ClientHello.client_version and use the record layer version number
+ * (TLSPlaintext.version) instead when negotiating protocol versions. In
+ * addition, if the record layer version number of ClientHello is { 3, 2 }
+ * (TLS 1.1) or higher, these servers reset the TCP connections. Set this
+ * flag to work around such servers.
*/
PRInt32
ssl3_SendRecord( sslSocket * ss,
@@ -2260,6 +2273,7 @@ ssl3_SendRecord( sslSocket * ss,
sslBuffer * wrBuf = &ss->sec.writeBuf;
SECStatus rv;
PRInt32 totalSent = 0;
+ PRBool capRecordVersion;
SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
@@ -2268,6 +2282,16 @@ ssl3_SendRecord( sslSocket * ss,
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
+
+ if (capRecordVersion) {
+ /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with
+ * TLS ClientHello. */
+ PORT_Assert(!IS_DTLS(ss));
+ PORT_Assert(type == content_handshake);
+ PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
+ }
+
if (ss->ssl3.initialized == PR_FALSE) {
/* This can happen on a server if the very first incoming record
** looks like a defective ssl3 record (e.g. too long), and we're
@@ -2324,7 +2348,8 @@ ssl3_SendRecord( sslSocket * ss,
rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
ss->sec.isServer, IS_DTLS(ss),
- type, pIn, 1, wrBuf);
+ capRecordVersion, type, pIn,
+ 1, wrBuf);
if (rv != SECSuccess)
goto spec_locked_loser;
@@ -2337,7 +2362,8 @@ ssl3_SendRecord( sslSocket * ss,
rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
ss->sec.isServer, IS_DTLS(ss),
- type, pIn + 1, contentLen - 1,
+ capRecordVersion, type,
+ pIn + 1, contentLen - 1,
&secondRecord);
if (rv == SECSuccess) {
PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
@@ -2349,6 +2375,7 @@ ssl3_SendRecord( sslSocket * ss,
rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
ss->sec.isServer,
IS_DTLS(ss),
+ capRecordVersion,
type, pIn,
contentLen, wrBuf);
} else {
@@ -2560,6 +2587,8 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
static SECStatus
ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
{
+ static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
+ ssl_SEND_FLAG_CAP_RECORD_VERSION;
PRInt32 rv = SECSuccess;
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
@@ -2568,9 +2597,9 @@ ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
return rv;
- /* only this flag is allowed */
- PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER));
- if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) {
+ /* only these flags are allowed */
+ PORT_Assert(!(flags & ~allowedFlags));
+ if ((flags & ~allowedFlags) != 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
} else {
@@ -3981,8 +4010,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
int num_suites;
int actual_count = 0;
PRBool isTLS = PR_FALSE;
+ PRBool serverVersionKnown = PR_FALSE;
PRInt32 total_exten_len = 0;
unsigned numCompressionMethods;
+ PRInt32 flags;
SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
ss->fd));
@@ -4070,6 +4101,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
}
if (sid) {
+ serverVersionKnown = PR_TRUE;
SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
/* Are we attempting a stateless session resume? */
@@ -4305,7 +4337,11 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
ssl_renegotiation_info_xtn;
}
- rv = ssl3_FlushHandshake(ss, 0);
+ flags = 0;
+ if (!serverVersionKnown && !IS_DTLS(ss)) {
+ flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
+ }
+ rv = ssl3_FlushHandshake(ss, flags);
if (rv != SECSuccess) {
return rv; /* error code set by ssl3_FlushHandshake */
}
diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
index eda1885..e482ae5 100644
--- a/net/third_party/nss/ssl/sslimpl.h
+++ b/net/third_party/nss/ssl/sslimpl.h
@@ -294,6 +294,8 @@ struct sslSocketOpsStr {
#define ssl_SEND_FLAG_NO_BUFFER 0x20000000
#define ssl_SEND_FLAG_USE_EPOCH 0x10000000 /* DTLS only */
#define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
+#define ssl_SEND_FLAG_CAP_RECORD_VERSION \
+ 0x04000000 /* TLS only */
#define ssl_SEND_FLAG_MASK 0x7f000000
/*
@@ -1414,6 +1416,7 @@ extern SECStatus
ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
PRBool isServer,
PRBool isDTLS,
+ PRBool capRecordVersion,
SSL3ContentType type,
const SSL3Opaque * pIn,
PRUint32 contentLen,