diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-08 23:38:11 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-08 23:38:11 +0000 |
commit | 7389cfda10273fb2007a2c6161f8fabd0ed0be9d (patch) | |
tree | 922e9f40ec89aa8b95544928d4e6b3ac931da3fb /net/third_party | |
parent | 1461bbdafb1268fc789ed3fc02415b3fe09668c8 (diff) | |
download | chromium_src-7389cfda10273fb2007a2c6161f8fabd0ed0be9d.zip chromium_src-7389cfda10273fb2007a2c6161f8fabd0ed0be9d.tar.gz chromium_src-7389cfda10273fb2007a2c6161f8fabd0ed0be9d.tar.bz2 |
NSS: add `padding' extension when we might hit the F5 bug.
In the case that a ClientHello record is between 256 and 511 bytes long, add an
extension to make it at least 512 bytes. This works around a bug in F5 terminators.
BUG=315828
Review URL: https://codereview.chromium.org/62103003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234040 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party')
-rw-r--r-- | net/third_party/nss/README.chromium | 5 | ||||
-rwxr-xr-x | net/third_party/nss/patches/applypatches.sh | 2 | ||||
-rw-r--r-- | net/third_party/nss/patches/paddingextension.patch | 142 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl3con.c | 22 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl3ext.c | 53 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslimpl.h | 7 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslt.h | 3 |
7 files changed, 233 insertions, 1 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index 4a0f2d3..98f209f 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium @@ -139,6 +139,11 @@ Patches: https://bugzilla.mozilla.org/show_bug.cgi?id=934016 patches/nullcipher_934016.patch + * In the case that a ClientHello record is between 256 and 511 bytes long, + add an extension to make it 512 bytes. This works around a bug in F5 + terminators. + patches/paddingextension.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 947cf5e..f19776e 100755 --- a/net/third_party/nss/patches/applypatches.sh +++ b/net/third_party/nss/patches/applypatches.sh @@ -65,3 +65,5 @@ patch -p4 < $patches_dir/peercertchain2.patch patch -p4 < $patches_dir/canfalsestart.patch patch -p4 < $patches_dir/nullcipher_934016.patch + +patch -p4 < $patches_dir/paddingextension.patch diff --git a/net/third_party/nss/patches/paddingextension.patch b/net/third_party/nss/patches/paddingextension.patch new file mode 100644 index 0000000..8ea388c --- /dev/null +++ b/net/third_party/nss/patches/paddingextension.patch @@ -0,0 +1,142 @@ +diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c +index 8b8b758..567d481 100644 +--- a/nss/lib/ssl/ssl3con.c ++++ b/nss/lib/ssl/ssl3con.c +@@ -4975,6 +4975,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + PRBool isTLS = PR_FALSE; + PRBool requestingResume = PR_FALSE; + PRInt32 total_exten_len = 0; ++ unsigned paddingExtensionLen; + unsigned numCompressionMethods; + PRInt32 flags; + +@@ -5241,6 +5242,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + length += 1 + ss->ssl3.hs.cookieLen; + } + ++ /* A padding extension may be included to ensure that the record containing ++ * the ClientHello doesn't have a length between 256 and 511 bytes ++ * (inclusive). Initial, ClientHello records with such lengths trigger bugs ++ * in F5 devices. ++ * ++ * This is not done for DTLS nor for renegotiation. */ ++ if (!IS_DTLS(ss) && !ss->firstHsDone) { ++ paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length); ++ total_exten_len += paddingExtensionLen; ++ length += paddingExtensionLen; ++ } else { ++ paddingExtensionLen = 0; ++ } ++ + rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); + if (rv != SECSuccess) { + return rv; /* err set by ssl3_AppendHandshake* */ +@@ -5360,6 +5375,13 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) + return SECFailure; + } + maxBytes -= extLen; ++ ++ extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes); ++ if (extLen < 0) { ++ return SECFailure; ++ } ++ maxBytes -= extLen; ++ + PORT_Assert(!maxBytes); + } + if (ss->ssl3.hs.sendingSCSV) { +diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c +index 0415770..8be042e 100644 +--- a/nss/lib/ssl/ssl3ext.c ++++ b/nss/lib/ssl/ssl3ext.c +@@ -2297,3 +2297,56 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) + loser: + return -1; + } ++ ++unsigned int ++ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) ++{ ++ unsigned int recordLength = 1 /* handshake message type */ + ++ 3 /* handshake message length */ + ++ clientHelloLength; ++ unsigned int extensionLength; ++ ++ if (recordLength < 256 || recordLength >= 512) { ++ return 0; ++ } ++ ++ extensionLength = 512 - recordLength; ++ /* Extensions take at least four bytes to encode. */ ++ if (extensionLength < 4) { ++ extensionLength = 4; ++ } ++ ++ return extensionLength; ++} ++ ++/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a ++ * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures ++ * that we don't trigger bugs in F5 products. */ ++unsigned int ++ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, ++ PRUint32 maxBytes) ++{ ++ unsigned int paddingLen = extensionLen - 4; ++ unsigned char padding[256]; ++ ++ if (extensionLen == 0) { ++ return 0; ++ } ++ ++ if (extensionLen < 4 || ++ extensionLen > maxBytes || ++ paddingLen > sizeof(padding)) { ++ PORT_Assert(0); ++ return 0; ++ } ++ ++ if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2)) ++ return -1; ++ if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2)) ++ return -1; ++ memset(padding, ' ', paddingLen); ++ if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen)) ++ return -1; ++ ++ return extensionLen; ++} +diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h +index 614eed1..621f25e 100644 +--- a/nss/lib/ssl/sslimpl.h ++++ b/nss/lib/ssl/sslimpl.h +@@ -237,6 +237,13 @@ extern PRInt32 + ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, + const ssl3HelloExtensionSender *sender); + ++extern unsigned int ++ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength); ++ ++extern unsigned int ++ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, ++ PRUint32 maxBytes); ++ + /* Socket ops */ + struct sslSocketOpsStr { + int (*connect) (sslSocket *, const PRNetAddr *); +diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h +index a8007d8..e4d188f 100644 +--- a/nss/lib/ssl/sslt.h ++++ b/nss/lib/ssl/sslt.h +@@ -205,9 +205,10 @@ typedef enum { + ssl_session_ticket_xtn = 35, + ssl_next_proto_nego_xtn = 13172, + ssl_channel_id_xtn = 30031, ++ ssl_padding_xtn = 35655, + ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ + } SSLExtensionType; + +-#define SSL_MAX_EXTENSIONS 11 ++#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */ + + #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index 8b8b758..567d481 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -4975,6 +4975,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) PRBool isTLS = PR_FALSE; PRBool requestingResume = PR_FALSE; PRInt32 total_exten_len = 0; + unsigned paddingExtensionLen; unsigned numCompressionMethods; PRInt32 flags; @@ -5241,6 +5242,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) length += 1 + ss->ssl3.hs.cookieLen; } + /* A padding extension may be included to ensure that the record containing + * the ClientHello doesn't have a length between 256 and 511 bytes + * (inclusive). Initial, ClientHello records with such lengths trigger bugs + * in F5 devices. + * + * This is not done for DTLS nor for renegotiation. */ + if (!IS_DTLS(ss) && !ss->firstHsDone) { + paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length); + total_exten_len += paddingExtensionLen; + length += paddingExtensionLen; + } else { + paddingExtensionLen = 0; + } + rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); if (rv != SECSuccess) { return rv; /* err set by ssl3_AppendHandshake* */ @@ -5360,6 +5375,13 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) return SECFailure; } maxBytes -= extLen; + + extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes); + if (extLen < 0) { + return SECFailure; + } + maxBytes -= extLen; + PORT_Assert(!maxBytes); } if (ss->ssl3.hs.sendingSCSV) { diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c index 0415770..8be042e 100644 --- a/net/third_party/nss/ssl/ssl3ext.c +++ b/net/third_party/nss/ssl/ssl3ext.c @@ -2297,3 +2297,56 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) loser: return -1; } + +unsigned int +ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) +{ + unsigned int recordLength = 1 /* handshake message type */ + + 3 /* handshake message length */ + + clientHelloLength; + unsigned int extensionLength; + + if (recordLength < 256 || recordLength >= 512) { + return 0; + } + + extensionLength = 512 - recordLength; + /* Extensions take at least four bytes to encode. */ + if (extensionLength < 4) { + extensionLength = 4; + } + + return extensionLength; +} + +/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a + * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures + * that we don't trigger bugs in F5 products. */ +unsigned int +ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, + PRUint32 maxBytes) +{ + unsigned int paddingLen = extensionLen - 4; + unsigned char padding[256]; + + if (extensionLen == 0) { + return 0; + } + + if (extensionLen < 4 || + extensionLen > maxBytes || + paddingLen > sizeof(padding)) { + PORT_Assert(0); + return 0; + } + + if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2)) + return -1; + if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2)) + return -1; + memset(padding, ' ', paddingLen); + if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen)) + return -1; + + return extensionLen; +} diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h index 614eed1..621f25e 100644 --- a/net/third_party/nss/ssl/sslimpl.h +++ b/net/third_party/nss/ssl/sslimpl.h @@ -237,6 +237,13 @@ extern PRInt32 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, const ssl3HelloExtensionSender *sender); +extern unsigned int +ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength); + +extern unsigned int +ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, + PRUint32 maxBytes); + /* Socket ops */ struct sslSocketOpsStr { int (*connect) (sslSocket *, const PRNetAddr *); diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h index a8007d8..e4d188f 100644 --- a/net/third_party/nss/ssl/sslt.h +++ b/net/third_party/nss/ssl/sslt.h @@ -205,9 +205,10 @@ typedef enum { ssl_session_ticket_xtn = 35, ssl_next_proto_nego_xtn = 13172, ssl_channel_id_xtn = 30031, + ssl_padding_xtn = 35655, ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ } SSLExtensionType; -#define SSL_MAX_EXTENSIONS 11 +#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */ #endif /* __sslt_h_ */ |