summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-07 22:10:06 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-07 22:10:06 +0000
commitef21c83524b111067f2d8b175d034fd08a51583a (patch)
treea821c67de1fe830576887b5c962130deedf3ac7d /net
parent793d3a3c7137f9df125322b9c7b342000cc4ad52 (diff)
downloadchromium_src-ef21c83524b111067f2d8b175d034fd08a51583a.zip
chromium_src-ef21c83524b111067f2d8b175d034fd08a51583a.tar.gz
chromium_src-ef21c83524b111067f2d8b175d034fd08a51583a.tar.bz2
net: Precede each CBC encrypted application data record with an empty one.
Precede each CBC encrypted application data record with an empty application data record in order to randomize the IV in a backwards compatible manner. (This is a reland of r90632 which was reverted in r90643 because it tickled a bug in remoting unittests.) http://codereview.chromium.org/7239002 BUG=87159 TEST=HTTPS sites continue to work. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91768 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/socket/ssl_client_socket_unittest.cc2
-rw-r--r--net/third_party/nss/README.chromium5
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh2
-rw-r--r--net/third_party/nss/patches/cbcrandomiv.patch73
-rw-r--r--net/third_party/nss/ssl/ssl3con.c28
5 files changed, 107 insertions, 3 deletions
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 49c9191..9946c90 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -396,7 +396,7 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) {
// memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
// This tests the fix for http://crbug.com/29815.
std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
- for (int i = 0; i < 3800; ++i)
+ for (int i = 0; i < 3768; ++i)
request_text.push_back('*');
request_text.append("\r\n\r\n");
scoped_refptr<net::IOBuffer> request_buffer(
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index 4960c63..02793ef 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -51,6 +51,11 @@ Patches:
previous session.
patches/didhandshakeresume.patch
+ * Precede each set of CBC encrypted application data records, resulting from
+ a single call to ssl3_SendApplicationData, with an empty application data
+ record in order to randomize the IV in a backwards compatible manner.
+ patches/cbcrandomiv.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 3fd7993..9aafb92 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -22,3 +22,5 @@ patch -p6 < $patches_dir/clientauth.patch
patch -p6 < $patches_dir/cachedinfo.patch
patch -p6 < $patches_dir/didhandshakeresume.patch
+
+patch -p6 < $patches_dir/cbcrandomiv.patch
diff --git a/net/third_party/nss/patches/cbcrandomiv.patch b/net/third_party/nss/patches/cbcrandomiv.patch
new file mode 100644
index 0000000..9f1b57a
--- /dev/null
+++ b/net/third_party/nss/patches/cbcrandomiv.patch
@@ -0,0 +1,73 @@
+commit 36840201a321147d9c33a944784ff56980aae5d8
+Author: Adam Langley <agl@chromium.org>
+Date: Wed Jun 22 13:36:50 2011 -0400
+
+ cbcrandomiv.patch
+
+diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
+index 2cc1e05..eb7d63e 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3con.c
++++ b/mozilla/security/nss/lib/ssl/ssl3con.c
+@@ -2229,7 +2229,7 @@ ssl3_SendRecord( sslSocket * ss,
+ return SECFailure;
+ }
+
+- while (nIn > 0) {
++ do {
+ PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
+
+ if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
+@@ -2306,7 +2306,7 @@ ssl3_SendRecord( sslSocket * ss,
+ }
+ }
+ totalSent += contentLen;
+- }
++ } while (nIn > 0);
+ return totalSent;
+ }
+
+@@ -2321,6 +2321,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
+ {
+ PRInt32 totalSent = 0;
+ PRInt32 discarded = 0;
++ PRBool isBlockCipher;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ if (len < 0 || !in) {
+@@ -2345,6 +2346,28 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
+ len--;
+ discarded = 1;
+ }
++
++ ssl_GetSpecReadLock(ss);
++ isBlockCipher = ss->ssl3.cwSpec->cipher_def->type == type_block;
++ ssl_ReleaseSpecReadLock(ss);
++
++ if (isBlockCipher && len > 0) {
++ // We assume that block ciphers are used in CBC mode and prepend an
++ // empty record. This effectively randomizes the IV in a backwards
++ // compatible way.
++ PRInt32 sent = ssl3_SendRecord(ss, content_application_data,
++ in, 0 /* no payload */, flags);
++ if (sent < 0) {
++ return SECFailure; /* error code set by ssl3_SendRecord */
++ }
++ if (ss->pendingBuf.len) {
++ /* must be a non-blocking socket */
++ PORT_Assert(!ssl_SocketIsBlocking(ss));
++ PORT_Assert(ss->lastWriteBlocked);
++ return SECFailure;
++ }
++ }
++
+ while (len > totalSent) {
+ PRInt32 sent, toSend;
+
+@@ -2377,6 +2400,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
+ break;
+ }
+ }
++
+ if (ss->pendingBuf.len) {
+ /* Must be non-blocking. */
+ PORT_Assert(!ssl_SocketIsBlocking(ss));
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index 2cc1e05..eb7d63e 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -2229,7 +2229,7 @@ ssl3_SendRecord( sslSocket * ss,
return SECFailure;
}
- while (nIn > 0) {
+ do {
PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
@@ -2306,7 +2306,7 @@ ssl3_SendRecord( sslSocket * ss,
}
}
totalSent += contentLen;
- }
+ } while (nIn > 0);
return totalSent;
}
@@ -2321,6 +2321,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
{
PRInt32 totalSent = 0;
PRInt32 discarded = 0;
+ PRBool isBlockCipher;
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
if (len < 0 || !in) {
@@ -2345,6 +2346,28 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
len--;
discarded = 1;
}
+
+ ssl_GetSpecReadLock(ss);
+ isBlockCipher = ss->ssl3.cwSpec->cipher_def->type == type_block;
+ ssl_ReleaseSpecReadLock(ss);
+
+ if (isBlockCipher && len > 0) {
+ // We assume that block ciphers are used in CBC mode and prepend an
+ // empty record. This effectively randomizes the IV in a backwards
+ // compatible way.
+ PRInt32 sent = ssl3_SendRecord(ss, content_application_data,
+ in, 0 /* no payload */, flags);
+ if (sent < 0) {
+ return SECFailure; /* error code set by ssl3_SendRecord */
+ }
+ if (ss->pendingBuf.len) {
+ /* must be a non-blocking socket */
+ PORT_Assert(!ssl_SocketIsBlocking(ss));
+ PORT_Assert(ss->lastWriteBlocked);
+ return SECFailure;
+ }
+ }
+
while (len > totalSent) {
PRInt32 sent, toSend;
@@ -2377,6 +2400,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
break;
}
}
+
if (ss->pendingBuf.len) {
/* Must be non-blocking. */
PORT_Assert(!ssl_SocketIsBlocking(ss));