summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-24 17:30:37 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-24 17:30:37 +0000
commit1141e92b442fa8fbdad6858597d38e41a17beee9 (patch)
treedd1807659d37379e25236424e684bb211106b05e /net
parent81cc5aa7ab33668800d01059ed74eb41e1712f8b (diff)
downloadchromium_src-1141e92b442fa8fbdad6858597d38e41a17beee9.zip
chromium_src-1141e92b442fa8fbdad6858597d38e41a17beee9.tar.gz
chromium_src-1141e92b442fa8fbdad6858597d38e41a17beee9.tar.bz2
net: include patch for cached info and fix whitespace.
No code changes. TBR=wtc BUG=none TEST=no code changes. http://codereview.chromium.org/7236036/ git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90377 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/third_party/nss/README.chromium3
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh2
-rw-r--r--net/third_party/nss/patches/cachedinfo.patch668
-rw-r--r--net/third_party/nss/ssl/ssl.h18
-rw-r--r--net/third_party/nss/ssl/ssl3con.c117
-rw-r--r--net/third_party/nss/ssl/ssl3ext.c52
-rw-r--r--net/third_party/nss/ssl/sslauth.c14
-rw-r--r--net/third_party/nss/ssl/sslimpl.h4
8 files changed, 775 insertions, 103 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index 193fef0..1cca89a 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -43,6 +43,9 @@ Patches:
patches/clientauth.patch
https://bugzilla.mozilla.org/show_bug.cgi?id=616757
+ * Add support for TLS cached info extension.
+ patches/cachedinfo.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 b7948ed..c6609ca 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -18,3 +18,5 @@ patch -p6 < $patches_dir/peercertchain.patch
patch -p6 < $patches_dir/ocspstapling.patch
patch -p6 < $patches_dir/clientauth.patch
+
+patch -p6 < $patches_dir/cachedinfo.patch
diff --git a/net/third_party/nss/patches/cachedinfo.patch b/net/third_party/nss/patches/cachedinfo.patch
new file mode 100644
index 0000000..f57ad6d
--- /dev/null
+++ b/net/third_party/nss/patches/cachedinfo.patch
@@ -0,0 +1,668 @@
+commit d4212da54db71bcf4e1232a9692cbdafa3cecb0f
+Author: Adam Langley <agl@chromium.org>
+Date: Fri Jun 24 13:10:38 2011 -0400
+
+ cachedinfo.patch
+
+diff --git a/mozilla/security/nss/lib/ssl/fnv1a64.c b/mozilla/security/nss/lib/ssl/fnv1a64.c
+new file mode 100644
+index 0000000..c7c4b08
+--- /dev/null
++++ b/mozilla/security/nss/lib/ssl/fnv1a64.c
+@@ -0,0 +1,72 @@
++/*
++ * FNV1A64 Hash
++ * http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
++ *
++ * ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is the Netscape security libraries.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 1994-2000
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Adam Langley, Google Inc.
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++/* $Id: fnv1a64.c,v 1.0 2010/08/09 13:00:00 agl%google.com Exp $ */
++
++#include "prtypes.h"
++#include "prnetdb.h"
++
++/* Older versions of Visual C++ don't support the 'ull' suffix. */
++#ifdef _MSC_VER
++static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ui64;
++static const PRUint64 FNV1A64_PRIME = 1099511628211ui64;
++#else
++static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ull;
++static const PRUint64 FNV1A64_PRIME = 1099511628211ull;
++#endif
++
++void FNV1A64_Init(PRUint64* digest) {
++ *digest = FNV1A64_OFFSET_BASIS;
++}
++
++void FNV1A64_Update(PRUint64* digest, const unsigned char *data,
++ unsigned int length) {
++ unsigned int i;
++
++ for (i = 0; i < length; i++) {
++ *digest ^= data[i];
++ *digest *= FNV1A64_PRIME;
++ }
++}
++
++void FNV1A64_Final(PRUint64 *digest) {
++ *digest = PR_htonll(*digest);
++}
+diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
+index 563cfd5..7357d9f 100644
+--- a/mozilla/security/nss/lib/ssl/ssl.h
++++ b/mozilla/security/nss/lib/ssl/ssl.h
+@@ -140,6 +140,8 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
+ /* bits. The advantage of False Start is that it saves a round trip for */
+ /* client-speaks-first protocols when performing a full handshake. */
+ #define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */
++#define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */
++ /* extension, off by default. */
+
+ #ifdef SSL_DEPRECATED_FUNCTION
+ /* Old deprecated function names */
+@@ -438,6 +440,17 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
+ void *arg);
+
+ /*
++ ** Set the predicted chain of certificates for the peer. This is used for the
++ ** TLS Cached Info extension. Note that the SSL_ENABLE_CACHED_INFO option must
++ ** be set for this to occur.
++ **
++ ** This function takes a reference to each of the given certificates.
++ */
++ SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(
++ PRFileDesc *fd, CERTCertificate **certs,
++ unsigned int numCerts);
++
++/*
+ ** Configure SSL socket for running a secure server. Needs the
+ ** certificate for the server and the servers private key. The arguments
+ ** are copied.
+diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
+index 0997e18..2cc1e05 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3con.c
++++ b/mozilla/security/nss/lib/ssl/ssl3con.c
+@@ -5170,7 +5170,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ ssl3_CopyPeerCertsFromSID(ss, sid);
+ }
+
+-
+ /* NULL value for PMS signifies re-use of the old MS */
+ rv = ssl3_InitPendingCipherSpec(ss, NULL);
+ if (rv != SECSuccess) {
+@@ -7958,7 +7957,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ PRInt32 size;
+ SECStatus rv;
+ PRBool isServer = (PRBool)(!!ss->sec.isServer);
+- PRBool trusted = PR_FALSE;
+ PRBool isTLS;
+ SSL3AlertDescription desc = bad_certificate;
+ int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
+@@ -8018,35 +8016,46 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ goto loser; /* don't send alerts on memory errors */
+ }
+
+- /* First get the peer cert. */
+- remaining -= 3;
+- if (remaining < 0)
+- goto decode_loser;
++ if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) {
++ /* We are dealing with a certificate_chain digest */
++ int i;
+
+- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
+- if (size <= 0)
+- goto loser; /* fatal alert already sent by ConsumeHandshake. */
++ ss->ssl3.digestReceived = PR_TRUE;
+
+- if (remaining < size)
+- goto decode_loser;
++ /* Make sure the digests match. */
++ if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) {
++ desc = handshake_failure;
++ goto alert_loser;
++ }
+
+- certItem.data = b;
+- certItem.len = size;
+- b += size;
+- length -= size;
+- remaining -= size;
++ /* First get the peer cert. */
++ if (ss->ssl3.predictedCertChain[0] == NULL) {
++ desc = handshake_failure;
++ goto alert_loser;
++ }
++ ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]);
+
+- ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
+- PR_FALSE, PR_TRUE);
+- if (ss->sec.peerCert == NULL) {
+- /* We should report an alert if the cert was bad, but not if the
+- * problem was just some local problem, like memory error.
+- */
+- goto ambiguous_err;
+- }
++ /* Now get all of the CA certs. */
++ ss->ssl3.peerCertChain = NULL;
++ for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) {
++ c = PORT_ArenaNew(arena, ssl3CertNode);
++ if (c == NULL) {
++ goto loser; /* don't send alerts on memory errors */
++ }
++ c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]);
++ c->next = NULL;
++ if (lastCert) {
++ lastCert->next = c;
++ } else {
++ ss->ssl3.peerCertChain = c;
++ }
++ lastCert = c;
++ }
++ } else {
++ /* We are dealing with a regular certificate message */
++ ss->ssl3.digestReceived = PR_FALSE;
+
+- /* Now get all of the CA certs. */
+- while (remaining > 0) {
++ /* First get the peer cert. */
+ remaining -= 3;
+ if (remaining < 0)
+ goto decode_loser;
+@@ -8060,35 +8069,61 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+
+ certItem.data = b;
+ certItem.len = size;
+- b += size;
++ b += size;
+ length -= size;
+ remaining -= size;
+
+- c = PORT_ArenaNew(arena, ssl3CertNode);
+- if (c == NULL) {
+- goto loser; /* don't send alerts on memory errors */
+- }
+-
+- c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
+- PR_FALSE, PR_TRUE);
+- if (c->cert == NULL) {
++ ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem,
++ NULL, PR_FALSE, PR_TRUE);
++ if (ss->sec.peerCert == NULL) {
++ /* We should report an alert if the cert was bad, but not if the
++ * problem was just some local problem, like memory error.
++ */
+ goto ambiguous_err;
+ }
+
+- if (c->cert->trust)
+- trusted = PR_TRUE;
++ /* Now get all of the CA certs. */
++ while (remaining > 0) {
++ remaining -= 3;
++ if (remaining < 0)
++ goto decode_loser;
+
+- c->next = NULL;
+- if (lastCert) {
+- lastCert->next = c;
+- } else {
+- certs = c;
++ size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
++ if (size <= 0)
++ goto loser; /* fatal alert already sent by ConsumeHandshake. */
++
++ if (remaining < size)
++ goto decode_loser;
++
++ certItem.data = b;
++ certItem.len = size;
++ b += size;
++ length -= size;
++ remaining -= size;
++
++ c = PORT_ArenaNew(arena, ssl3CertNode);
++ if (c == NULL) {
++ goto loser; /* don't send alerts on memory errors */
++ }
++
++ c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
++ PR_FALSE, PR_TRUE);
++ if (c->cert == NULL) {
++ goto ambiguous_err;
++ }
++
++ c->next = NULL;
++ if (lastCert) {
++ lastCert->next = c;
++ } else {
++ certs = c;
++ }
++ lastCert = c;
+ }
+- lastCert = c;
+- }
+
+- if (remaining != 0)
+- goto decode_loser;
++ if (remaining != 0)
++ goto decode_loser;
++ }
+
+ SECKEY_UpdateCertPQG(ss->sec.peerCert);
+
+@@ -8250,7 +8285,10 @@ alert_loser:
+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
+
+ loser:
+- ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
++ if (ss->ssl3.peerCertChain == NULL) {
++ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
++ }
++ PORT_Assert(certs == NULL);
+ ssl3_CleanupPeerCerts(ss);
+
+ if (ss->sec.peerCert != NULL) {
+@@ -9736,6 +9774,21 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
+ return rv;
+ }
+
++static void
++ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) {
++ unsigned int i;
++
++ if (!ss->ssl3.predictedCertChain)
++ return;
++
++ for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
++ CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]);
++ }
++
++ PORT_Free(ss->ssl3.predictedCertChain);
++ ss->ssl3.predictedCertChain = NULL;
++}
++
+ /* Called from ssl_DestroySocketContents() in sslsock.c */
+ void
+ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -9759,6 +9812,9 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+ ss->ssl3.clientCertChain = NULL;
+ }
+
++ if (ss->ssl3.predictedCertChain != NULL)
++ ssl3_CleanupPredictedPeerCertificates(ss);
++
+ /* clean up handshake */
+ if (ss->opt.bypassPKCS11) {
+ SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
+diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c
+index 94dab58..b68d2fd 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3ext.c
++++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
+@@ -247,6 +247,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
+ { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
+ { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
+ { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
++ { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { -1, NULL }
+ };
+@@ -272,6 +273,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+ #endif
+ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
+ { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
++ { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
+ /* any extra entries will appear as { 0, NULL } */
+ };
+@@ -676,6 +678,156 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
+ return SECSuccess;
+ }
+
++/* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the
++ * client side. */
++PRInt32
++ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append,
++ PRUint32 maxBytes)
++{
++ PRInt32 extension_length;
++ PRBool send_empty;
++ CERTCertificate ** predictedCertChain;
++
++ if (!ss->opt.enableCachedInfo)
++ return 0;
++
++ predictedCertChain = ss->ssl3.predictedCertChain;
++ send_empty = (predictedCertChain == NULL);
++
++ /* minimum extension:
++ * extension_type (2-bytes) +
++ * length(extension_data) (2-bytes) +
++ * length(cached_info) (2-bytes) +
++ */
++ extension_length = send_empty ? 6 : 16;
++
++ if (append && maxBytes >= extension_length) {
++ SECStatus rv;
++
++ /* ExtensionType */
++ rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2);
++ if (rv != SECSuccess)
++ return -1;
++ /* Extension Length */
++ rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
++ if (rv != SECSuccess)
++ return -1;
++ if (send_empty) {
++ /* Cached Information Length */
++ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
++ if (rv != SECSuccess)
++ return -1;
++ } else {
++ PRUint64 certChainHash;
++ int i;
++ PRUint8* digestPtr = (PRUint8*) &certChainHash;
++
++ /* Cached Information Length */
++ rv = ssl3_AppendHandshakeNumber(ss, 10, 2);
++ if (rv != SECSuccess)
++ return -1;
++ /* Cached Information Type */
++ rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1);
++ if (rv != SECSuccess)
++ return -1;
++ /* hash length */
++ rv = ssl3_AppendHandshakeNumber(ss, 8, 1);
++ if (rv != SECSuccess)
++ return -1;
++ /* hash */
++ FNV1A64_Init(&certChainHash);
++ for (i = 0; predictedCertChain[i] != NULL; i++) {
++ unsigned int certLen = predictedCertChain[i]->derCert.len;
++ unsigned char certLenArray[3] = {
++ (certLen & 0xff0000) >> 16,
++ (certLen & 0xff00) >> 8,
++ certLen & 0xff
++ };
++ FNV1A64_Update(&certChainHash, certLenArray, 3);
++ FNV1A64_Update(&certChainHash,
++ predictedCertChain[i]->derCert.data, certLen);
++ }
++ FNV1A64_Final(&certChainHash);
++ rv = ssl3_AppendHandshake(ss, &certChainHash, 8);
++ if (rv != SECSuccess)
++ return -1;
++ for (i = 0; i < 8; i++) {
++ ss->ssl3.certChainDigest[i] = digestPtr[i];
++ }
++ }
++
++ } else if (maxBytes < extension_length) {
++ PORT_Assert(0);
++ return 0;
++ }
++ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
++ ssl_cached_info_xtn;
++ return extension_length;
++}
++
++SECStatus
++ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
++ SECItem *data)
++{
++ unsigned char * cached_info = data->data;
++ unsigned int remaining_cached_info_length;
++ PRBool has_correct_cert_chain = PR_FALSE;
++
++ /* If we didn't request this extension, then the server may not echo it. */
++ if (!ss->opt.enableCachedInfo)
++ return SECFailure;
++
++ if (data->len == 0) {
++ /* The server supports information caching, but provides no information
++ * about what information types it supports */
++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
++ return SECSuccess;
++ }
++
++ if (data->len < 2)
++ return SECFailure;
++ remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1];
++ if (remaining_cached_info_length != data->len - 2)
++ return SECFailure;
++ cached_info += 2;
++ while (remaining_cached_info_length >= 2) {
++ /* The server supports only those CachedInformationType types that are
++ * identified by a present CachedObject */
++ unsigned char cached_object_type;
++ unsigned int cached_object_length;
++ unsigned char cached_object_digest[8];
++ cached_object_type = *cached_info++;
++ cached_object_length = *cached_info++;
++ remaining_cached_info_length -= 2;
++ if (remaining_cached_info_length < cached_object_length)
++ return SECFailure;
++ if (cached_object_length != 0 && cached_object_length != 8)
++ return SECFailure;
++ remaining_cached_info_length -= cached_object_length;
++ if (cached_object_type == cached_info_certificate_chain) {
++ if (cached_object_length == 0)
++ has_correct_cert_chain = PR_TRUE;
++ else { /* Hashes must match */
++ int i;
++ for (i = 0; i < 8; i++)
++ cached_object_digest[i] = *cached_info++;
++ if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8))
++ has_correct_cert_chain = PR_TRUE;
++ }
++ }
++ }
++
++ if (remaining_cached_info_length != 0)
++ return SECFailure;
++
++ if (has_correct_cert_chain) {
++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
++ return SECSuccess;
++ }
++
++ return SECFailure;
++}
++
+ /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
+ * client side. See RFC 4366 section 3.6. */
+ PRInt32
+diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/ssl/sslauth.c
+index 447aaf8..6313603 100644
+--- a/mozilla/security/nss/lib/ssl/sslauth.c
++++ b/mozilla/security/nss/lib/ssl/sslauth.c
+@@ -95,6 +95,31 @@ SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs,
+ return SECSuccess;
+ }
+
++SECStatus
++SSL_SetPredictedPeerCertificates(PRFileDesc *fd, CERTCertificate **certs,
++ unsigned int numCerts)
++{
++ sslSocket *ss;
++ unsigned int i;
++
++ ss = ssl_FindSocket(fd);
++ if (!ss) {
++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedPeerCertificates",
++ SSL_GETPID(), fd));
++ return SECFailure;
++ }
++
++ ss->ssl3.predictedCertChain =
++ PORT_NewArray(CERTCertificate*, numCerts + 1);
++ if (!ss->ssl3.predictedCertChain)
++ return SECFailure; /* error code was set */
++ for (i = 0; i < numCerts; i++)
++ ss->ssl3.predictedCertChain[i] = CERT_DupCertificate(certs[i]);
++ ss->ssl3.predictedCertChain[numCerts] = NULL;
++
++ return SECSuccess;
++}
++
+ /* NEED LOCKS IN HERE. */
+ CERTCertificate *
+ SSL_LocalCertificate(PRFileDesc *fd)
+diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
+index 2e1364e..bf47dc2 100644
+--- a/mozilla/security/nss/lib/ssl/sslimpl.h
++++ b/mozilla/security/nss/lib/ssl/sslimpl.h
+@@ -349,6 +349,7 @@ typedef struct sslOptionsStr {
+ unsigned int requireSafeNegotiation : 1; /* 22 */
+ unsigned int enableFalseStart : 1; /* 23 */
+ unsigned int enableOCSPStapling : 1; /* 24 */
++ unsigned int enableCachedInfo : 1; /* 25 */
+ } sslOptions;
+
+ typedef enum { sslHandshakingUndetermined = 0,
+@@ -773,6 +774,11 @@ struct TLSExtensionDataStr {
+ PRUint32 sniNameArrSize;
+ };
+
++typedef enum {
++ cached_info_certificate_chain = 1,
++ cached_info_trusted_cas = 2
++} TLSCachedInfoType;
++
+ /*
+ ** This is the "hs" member of the "ssl3" struct.
+ ** This entire struct is protected by ssl3HandshakeLock
+@@ -854,6 +860,14 @@ struct ssl3StateStr {
+ CERTCertificateList *clientCertChain; /* used by client */
+ PRBool sendEmptyCert; /* used by client */
+
++ /* TLS Cached Info Extension */
++ CERTCertificate ** predictedCertChain;
++ /* An array terminated with a NULL. */
++ PRUint8 certChainDigest[8];
++ /* Used in cached info extension. Stored in network
++ * byte order. */
++ PRBool digestReceived;
++
+ int policy;
+ /* This says what cipher suites we can do, and should
+ * be either SSL_ALLOWED or SSL_RESTRICTED
+@@ -1550,6 +1564,8 @@ extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
+ extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
++extern SECStatus ssl3_ClientHandleCachedInfoXtn(sslSocket *ss,
++ PRUint16 ex_type, SECItem *data);
+ extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
+ extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
+@@ -1571,6 +1587,8 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append,
+ */
+ extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes);
++extern PRInt32 ssl3_ClientSendCachedInfoXtn(sslSocket *ss, PRBool append,
++ PRUint32 maxBytes);
+
+ /* Assigns new cert, cert chain and keys to ss->serverCerts
+ * struct. If certChain is NULL, tries to find one. Aborts if
+diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c
+index 1bb211e..f00f8f4 100644
+--- a/mozilla/security/nss/lib/ssl/sslsock.c
++++ b/mozilla/security/nss/lib/ssl/sslsock.c
+@@ -186,6 +186,7 @@ static sslOptions ssl_defaults = {
+ PR_FALSE, /* requireSafeNegotiation */
+ PR_FALSE, /* enableFalseStart */
+ PR_FALSE, /* enableOCSPStapling */
++ PR_FALSE, /* enableCachedInfo */
+ };
+
+ sslSessionIDLookupFunc ssl_sid_lookup;
+@@ -747,6 +748,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
+ ss->opt.enableOCSPStapling = on;
+ break;
+
++ case SSL_ENABLE_CACHED_INFO:
++ ss->opt.enableCachedInfo = on;
++ break;
++
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+@@ -812,6 +817,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
+ on = ss->opt.requireSafeNegotiation; break;
+ case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break;
+ case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
++ case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+@@ -866,6 +872,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
+ case SSL_ENABLE_OCSP_STAPLING:
+ on = ssl_defaults.enableOCSPStapling;
+ break;
++ case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+@@ -1017,6 +1024,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
+ ssl_defaults.enableOCSPStapling = on;
+ break;
+
++ case SSL_ENABLE_CACHED_INFO:
++ ssl_defaults.enableCachedInfo = on;
++ break;
++
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h
+index 917c093..bca7496 100644
+--- a/mozilla/security/nss/lib/ssl/sslt.h
++++ b/mozilla/security/nss/lib/ssl/sslt.h
+@@ -205,9 +205,10 @@ typedef enum {
+ #endif
+ ssl_session_ticket_xtn = 35,
+ ssl_next_proto_neg_xtn = 13172,
++ ssl_cached_info_xtn = 13173,
+ ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
+ } SSLExtensionType;
+
+-#define SSL_MAX_EXTENSIONS 7
++#define SSL_MAX_EXTENSIONS 8
+
+ #endif /* __sslt_h_ */
diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
index c65287b..7357d9f 100644
--- a/net/third_party/nss/ssl/ssl.h
+++ b/net/third_party/nss/ssl/ssl.h
@@ -439,15 +439,15 @@ typedef SECStatus (PR_CALLBACK *SSLBadCertHandler)(void *arg, PRFileDesc *fd);
SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
void *arg);
-/*
- ** Set the predicted chain of certificates for the peer. This is used for the
- ** TLS Cached Info extension. Note that the SSL_ENABLE_CACHED_INFO option must
- ** be set for this to occur.
- **
- ** This function takes a reference to each of the given certificates.
- */
- SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(
- PRFileDesc *fd, CERTCertificate **certs,
+/*
+ ** Set the predicted chain of certificates for the peer. This is used for the
+ ** TLS Cached Info extension. Note that the SSL_ENABLE_CACHED_INFO option must
+ ** be set for this to occur.
+ **
+ ** This function takes a reference to each of the given certificates.
+ */
+ SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(
+ PRFileDesc *fd, CERTCertificate **certs,
unsigned int numCerts);
/*
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index 2a564ac..2cc1e05 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -5170,7 +5170,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ssl3_CopyPeerCertsFromSID(ss, sid);
}
-
/* NULL value for PMS signifies re-use of the old MS */
rv = ssl3_InitPendingCipherSpec(ss, NULL);
if (rv != SECSuccess) {
@@ -8018,112 +8017,112 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) {
- /* We are dealing with a certificate_chain digest */
+ /* We are dealing with a certificate_chain digest */
int i;
- ss->ssl3.digestReceived = PR_TRUE;
+ ss->ssl3.digestReceived = PR_TRUE;
/* Make sure the digests match. */
if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) {
- desc = handshake_failure;
- goto alert_loser;
+ desc = handshake_failure;
+ goto alert_loser;
}
- /* First get the peer cert. */
- if (ss->ssl3.predictedCertChain[0] == NULL) {
- desc = handshake_failure;
- goto alert_loser;
+ /* First get the peer cert. */
+ if (ss->ssl3.predictedCertChain[0] == NULL) {
+ desc = handshake_failure;
+ goto alert_loser;
}
- ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]);
-
- /* Now get all of the CA certs. */
+ ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]);
+
+ /* Now get all of the CA certs. */
ss->ssl3.peerCertChain = NULL;
for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) {
c = PORT_ArenaNew(arena, ssl3CertNode);
if (c == NULL) {
- goto loser; /* don't send alerts on memory errors */
+ goto loser; /* don't send alerts on memory errors */
}
c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]);
c->next = NULL;
if (lastCert) {
- lastCert->next = c;
+ lastCert->next = c;
} else {
- ss->ssl3.peerCertChain = c;
+ ss->ssl3.peerCertChain = c;
}
lastCert = c;
}
} else {
- /* We are dealing with a regular certificate message */
- ss->ssl3.digestReceived = PR_FALSE;
-
- /* First get the peer cert. */
- remaining -= 3;
- if (remaining < 0)
+ /* We are dealing with a regular certificate message */
+ ss->ssl3.digestReceived = PR_FALSE;
+
+ /* First get the peer cert. */
+ remaining -= 3;
+ if (remaining < 0)
goto decode_loser;
-
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size <= 0)
+
+ size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
+ if (size <= 0)
goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- if (remaining < size)
+
+ if (remaining < size)
goto decode_loser;
-
- certItem.data = b;
- certItem.len = size;
- b += size;
- length -= size;
- remaining -= size;
-
- ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem,
+
+ certItem.data = b;
+ certItem.len = size;
+ b += size;
+ length -= size;
+ remaining -= size;
+
+ ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem,
NULL, PR_FALSE, PR_TRUE);
- if (ss->sec.peerCert == NULL) {
+ if (ss->sec.peerCert == NULL) {
/* We should report an alert if the cert was bad, but not if the
* problem was just some local problem, like memory error.
*/
goto ambiguous_err;
- }
-
- /* Now get all of the CA certs. */
- while (remaining > 0) {
+ }
+
+ /* Now get all of the CA certs. */
+ while (remaining > 0) {
remaining -= 3;
if (remaining < 0)
- goto decode_loser;
-
+ goto decode_loser;
+
size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
if (size <= 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
+ goto loser; /* fatal alert already sent by ConsumeHandshake. */
+
if (remaining < size)
- goto decode_loser;
-
+ goto decode_loser;
+
certItem.data = b;
certItem.len = size;
b += size;
length -= size;
remaining -= size;
-
+
c = PORT_ArenaNew(arena, ssl3CertNode);
if (c == NULL) {
- goto loser; /* don't send alerts on memory errors */
+ goto loser; /* don't send alerts on memory errors */
}
-
+
c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
PR_FALSE, PR_TRUE);
if (c->cert == NULL) {
- goto ambiguous_err;
+ goto ambiguous_err;
}
-
+
c->next = NULL;
if (lastCert) {
- lastCert->next = c;
+ lastCert->next = c;
} else {
- certs = c;
+ certs = c;
}
lastCert = c;
- }
-
- if (remaining != 0)
- goto decode_loser;
+ }
+
+ if (remaining != 0)
+ goto decode_loser;
}
SECKEY_UpdateCertPQG(ss->sec.peerCert);
@@ -8287,7 +8286,7 @@ alert_loser:
loser:
if (ss->ssl3.peerCertChain == NULL) {
- ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
+ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
}
PORT_Assert(certs == NULL);
ssl3_CleanupPeerCerts(ss);
@@ -9780,10 +9779,10 @@ ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) {
unsigned int i;
if (!ss->ssl3.predictedCertChain)
- return;
+ return;
for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
- CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]);
+ CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]);
}
PORT_Free(ss->ssl3.predictedCertChain);
diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
index c2b364e..b68d2fd 100644
--- a/net/third_party/nss/ssl/ssl3ext.c
+++ b/net/third_party/nss/ssl/ssl3ext.c
@@ -693,7 +693,7 @@ ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append,
predictedCertChain = ss->ssl3.predictedCertChain;
send_empty = (predictedCertChain == NULL);
-
+
/* minimum extension:
* extension_type (2-bytes) +
* length(extension_data) (2-bytes) +
@@ -720,40 +720,40 @@ ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append,
} else {
PRUint64 certChainHash;
int i;
- PRUint8* digestPtr = (PRUint8*) &certChainHash;
+ PRUint8* digestPtr = (PRUint8*) &certChainHash;
/* Cached Information Length */
rv = ssl3_AppendHandshakeNumber(ss, 10, 2);
if (rv != SECSuccess)
- return -1;
+ return -1;
/* Cached Information Type */
rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1);
if (rv != SECSuccess)
- return -1;
+ return -1;
/* hash length */
rv = ssl3_AppendHandshakeNumber(ss, 8, 1);
if (rv != SECSuccess)
- return -1;
+ return -1;
/* hash */
FNV1A64_Init(&certChainHash);
for (i = 0; predictedCertChain[i] != NULL; i++) {
- unsigned int certLen = predictedCertChain[i]->derCert.len;
+ unsigned int certLen = predictedCertChain[i]->derCert.len;
unsigned char certLenArray[3] = {
(certLen & 0xff0000) >> 16,
(certLen & 0xff00) >> 8,
certLen & 0xff
};
- FNV1A64_Update(&certChainHash, certLenArray, 3);
- FNV1A64_Update(&certChainHash,
+ FNV1A64_Update(&certChainHash, certLenArray, 3);
+ FNV1A64_Update(&certChainHash,
predictedCertChain[i]->derCert.data, certLen);
}
FNV1A64_Final(&certChainHash);
rv = ssl3_AppendHandshake(ss, &certChainHash, 8);
if (rv != SECSuccess)
- return -1;
- for (i = 0; i < 8; i++) {
- ss->ssl3.certChainDigest[i] = digestPtr[i];
- }
+ return -1;
+ for (i = 0; i < 8; i++) {
+ ss->ssl3.certChainDigest[i] = digestPtr[i];
+ }
}
} else if (maxBytes < extension_length) {
@@ -761,7 +761,7 @@ ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append,
return 0;
}
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_cached_info_xtn;
+ ssl_cached_info_xtn;
return extension_length;
}
@@ -778,37 +778,37 @@ ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
return SECFailure;
if (data->len == 0) {
- /* The server supports information caching, but provides no information
+ /* The server supports information caching, but provides no information
* about what information types it supports */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
return SECSuccess;
}
if (data->len < 2)
- return SECFailure;
+ return SECFailure;
remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1];
if (remaining_cached_info_length != data->len - 2)
- return SECFailure;
+ return SECFailure;
cached_info += 2;
while (remaining_cached_info_length >= 2) {
- /* The server supports only those CachedInformationType types that are
+ /* The server supports only those CachedInformationType types that are
* identified by a present CachedObject */
- unsigned char cached_object_type;
+ unsigned char cached_object_type;
unsigned int cached_object_length;
unsigned char cached_object_digest[8];
- cached_object_type = *cached_info++;
+ cached_object_type = *cached_info++;
cached_object_length = *cached_info++;
remaining_cached_info_length -= 2;
if (remaining_cached_info_length < cached_object_length)
- return SECFailure;
+ return SECFailure;
if (cached_object_length != 0 && cached_object_length != 8)
- return SECFailure;
+ return SECFailure;
remaining_cached_info_length -= cached_object_length;
if (cached_object_type == cached_info_certificate_chain) {
if (cached_object_length == 0)
- has_correct_cert_chain = PR_TRUE;
+ has_correct_cert_chain = PR_TRUE;
else { /* Hashes must match */
- int i;
+ int i;
for (i = 0; i < 8; i++)
cached_object_digest[i] = *cached_info++;
if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8))
@@ -818,10 +818,10 @@ ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
}
if (remaining_cached_info_length != 0)
- return SECFailure;
+ return SECFailure;
if (has_correct_cert_chain) {
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
return SECSuccess;
}
diff --git a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth.c
index 76126ff..6313603 100644
--- a/net/third_party/nss/ssl/sslauth.c
+++ b/net/third_party/nss/ssl/sslauth.c
@@ -97,24 +97,24 @@ SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs,
SECStatus
SSL_SetPredictedPeerCertificates(PRFileDesc *fd, CERTCertificate **certs,
- unsigned int numCerts)
+ unsigned int numCerts)
{
sslSocket *ss;
unsigned int i;
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedPeerCertificates",
- SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedPeerCertificates",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
ss->ssl3.predictedCertChain =
- PORT_NewArray(CERTCertificate*, numCerts + 1);
+ PORT_NewArray(CERTCertificate*, numCerts + 1);
if (!ss->ssl3.predictedCertChain)
- return SECFailure; /* error code was set */
+ return SECFailure; /* error code was set */
for (i = 0; i < numCerts; i++)
- ss->ssl3.predictedCertChain[i] = CERT_DupCertificate(certs[i]);
+ ss->ssl3.predictedCertChain[i] = CERT_DupCertificate(certs[i]);
ss->ssl3.predictedCertChain[numCerts] = NULL;
return SECSuccess;
diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
index 6d6cecc..bf47dc2 100644
--- a/net/third_party/nss/ssl/sslimpl.h
+++ b/net/third_party/nss/ssl/sslimpl.h
@@ -864,8 +864,8 @@ struct ssl3StateStr {
CERTCertificate ** predictedCertChain;
/* An array terminated with a NULL. */
PRUint8 certChainDigest[8];
- /* Used in cached info extension. Stored in network
- * byte order. */
+ /* Used in cached info extension. Stored in network
+ * byte order. */
PRBool digestReceived;
int policy;