Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: net/third_party/nss/patches/cachedinfo.patch

Issue 9558017: Update net/third_party/nss to NSS 3.13.3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Upload before checkin Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/patches/cachecerts.patch ('k') | net/third_party/nss/patches/cbcrandomiv.patch » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/patches/cachedinfo.patch
===================================================================
--- net/third_party/nss/patches/cachedinfo.patch (revision 124804)
+++ net/third_party/nss/patches/cachedinfo.patch (working copy)
@@ -1,975 +0,0 @@
-From 1c425d479c495d266c23876887198a54e82e7078 Mon Sep 17 00:00:00 2001
-From: Adam Langley <agl@chromium.org>
-Date: Mon, 3 Oct 2011 12:22:24 -0400
-Subject: [PATCH] cachedinfo.patch
-
----
- mozilla/security/nss/lib/ssl/fnv1a64.c | 72 +++++++++
- mozilla/security/nss/lib/ssl/manifest.mn | 1 +
- mozilla/security/nss/lib/ssl/ssl.h | 26 +++
- mozilla/security/nss/lib/ssl/ssl3con.c | 221 +++++++++++++++++++------
- mozilla/security/nss/lib/ssl/ssl3ext.c | 258 ++++++++++++++++++++++++++++++
- mozilla/security/nss/lib/ssl/sslauth.c | 40 +++++
- mozilla/security/nss/lib/ssl/sslimpl.h | 33 ++++-
- mozilla/security/nss/lib/ssl/sslsock.c | 11 ++
- mozilla/security/nss/lib/ssl/sslt.h | 3 +-
- 9 files changed, 611 insertions(+), 54 deletions(-)
- create mode 100644 mozilla/security/nss/lib/ssl/fnv1a64.c
-
-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/manifest.mn b/mozilla/security/nss/lib/ssl/manifest.mn
-index 8451229..f09d770 100644
---- a/mozilla/security/nss/lib/ssl/manifest.mn
-+++ b/mozilla/security/nss/lib/ssl/manifest.mn
-@@ -51,6 +51,7 @@ MAPFILE = $(OBJDIR)/ssl.def
-
- CSRCS = \
- derive.c \
-+ fnv1a64.c \
- prelib.c \
- ssl3con.c \
- ssl3gthr.c \
-diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
-index 221fe2d..3a22b45 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 */
-@@ -256,6 +258,12 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
- #define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */
-
- /*
-+** Returns true if the server's Certificate message contained a hash of the
-+** certificate chain due to the TLS cached info extension.
-+*/
-+SSL_IMPORT PRBool SSL_CertChainDigestReceived(PRFileDesc *fd);
-+
-+/*
- ** Return the certificate for our SSL peer. If the client calls this
- ** it will always return the server's certificate. If the server calls
- ** this, it may return NULL if client authentication is not enabled or
-@@ -275,6 +283,13 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
- SSL_IMPORT SECStatus SSL_PeerCertificateChain(
- PRFileDesc *fd, CERTCertificate **certs, unsigned int *certs_size);
-
-+/*
-+** Set the predicted cert chain to be used in the cached info extension.
-+*/
-+SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(PRFileDesc *fd,
-+ CERTCertificate **certs,
-+ unsigned int len);
-+
- /* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by
- * the TLS server. The resulting data is copied to |out_data|. On entry, |*len|
- * must contain the size of |out_data|. On exit, |*len| will contain the size
-@@ -405,6 +420,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 ca2793f..dd99962 100644
---- a/mozilla/security/nss/lib/ssl/ssl3con.c
-+++ b/mozilla/security/nss/lib/ssl/ssl3con.c
-@@ -5145,7 +5145,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) {
-@@ -7715,6 +7714,69 @@ ssl3_SendCertificate(sslSocket *ss)
- }
- }
-
-+ if (ss->ssl3.cachedInfoCertChainDigestReceived) {
-+ /* Compute hash. */
-+ PRUint64 certChainHash;
-+ int i;
-+ FNV1A64_Init(&certChainHash);
-+ for (i = 0; i < certChain->len; i++) {
-+ unsigned int certLen = certChain->certs[i].len;
-+ unsigned char certLenArray[3] = {
-+ certLen >> 16,
-+ certLen >> 8,
-+ certLen
-+ };
-+ FNV1A64_Update(&certChainHash, certLenArray, sizeof(certLenArray));
-+ FNV1A64_Update(&certChainHash, certChain->certs[i].data, certLen);
-+ }
-+ FNV1A64_Final(&certChainHash);
-+
-+ /* Both |&certChainHash| and |ss->ssl3.certChainDigest| should be in
-+ * network byte order since both are computed with the FNV1A64 hash,
-+ * which calls the function htonll.
-+ */
-+ if (memcmp(&certChainHash, ss->ssl3.certChainDigest,
-+ sizeof(certChainHash)) == 0) {
-+ /* The client correctly predicted the certificate chain. */
-+
-+ /* Handshake type: certificate. */
-+ rv = ssl3_AppendHandshakeNumber(ss, certificate, 1);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by AppendHandshake. */
-+ }
-+ /* Handshake message length. */
-+ rv = ssl3_AppendHandshakeNumber(ss, 15, 3);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by AppendHandshake. */
-+ }
-+ /* CertChainLen(3) + ASN.1CertLen(3) + DigestLen(1) + Digest(8) */
-+ rv = ssl3_AppendHandshakeNumber(ss, 12, 3);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by AppendHandshake. */
-+ }
-+ /* ASN.1CertLen(3) + DigestLen(1) + Digest(8) */
-+ rv = ssl3_AppendHandshakeNumber(ss, 9, 3);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by AppendHandshake. */
-+ }
-+ /* Digest Length Byte */
-+ rv = ssl3_AppendHandshakeNumber(ss, sizeof(certChainHash), 1);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by AppendHandshake. */
-+ }
-+ /* Digest */
-+ rv = ssl3_AppendHandshake(ss, &certChainHash,
-+ sizeof(certChainHash));
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by AppendHandshake. */
-+ }
-+
-+ return SECSuccess;
-+ }
-+ }
-+
-+ /* Send the entire certificate as usual. */
-+
- rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
-@@ -7869,7 +7931,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;
-@@ -7929,35 +7990,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.cachedInfoCertChainDigestReceived = 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.cachedInfoCertChainDigestReceived = 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;
-@@ -7971,35 +8043,63 @@ 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;
-+
-+ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
-+ }
-
- SECKEY_UpdateCertPQG(ss->sec.peerCert);
-
-@@ -8019,8 +8119,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- /* someone will handle this connection asynchronously*/
- SSL_DBG(("%d: SSL3[%d]: go to async cert handler",
- SSL_GETPID(), ss->fd));
-- ss->ssl3.peerCertChain = certs;
-- certs = NULL;
- ssl_SetAlwaysBlock(ss);
- goto cert_block;
- }
-@@ -8045,7 +8143,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- }
-
- ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
-- ssl3_CopyPeerCertsToSID(certs, ss->sec.ci.sid);
-+ ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);
-
- if (!ss->sec.isServer) {
- /* set the server authentication and key exchange types and sizes
-@@ -8090,8 +8188,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- }
- }
-
-- ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
--
- cert_block:
- if (ss->sec.isServer) {
- ss->ssl3.hs.ws = wait_client_key;
-@@ -8161,7 +8257,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) {
-@@ -9647,6 +9746,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)
-@@ -9666,6 +9780,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 4e3d9cc..17898fb 100644
---- a/mozilla/security/nss/lib/ssl/ssl3ext.c
-+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
-@@ -236,6 +236,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
- { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
-+ { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn },
- { -1, NULL }
- };
-
-@@ -247,6 +248,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 +274,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 +679,261 @@ 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 >> 16,
-+ certLen >> 8,
-+ certLen
-+ };
-+ 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_ServerHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
-+ SECItem *data)
-+{
-+ SECStatus rv;
-+ unsigned char *cached_info = data->data;
-+ unsigned int remaining_len;
-+
-+ /* Ignore the extension if it isn't enabled. */
-+ if (!ss->opt.enableCachedInfo)
-+ return SECSuccess;
-+
-+ if (data->len < 2)
-+ return SECFailure;
-+ remaining_len = (cached_info[0] << 8) | cached_info[1];
-+ if (remaining_len > 2048 || remaining_len != data->len - 2)
-+ return SECFailure;
-+ cached_info += 2;
-+
-+ /* Handle reconnaissance case. */
-+ if (remaining_len == 0) {
-+ /* The client supports information caching, but provides no information
-+ * about what information types it supports */
-+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-+ rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
-+ ssl3_ServerSendCachedInfoXtn);
-+ return rv;
-+ }
-+
-+ /* Iterate over the CachedObjects and pick the first item of type
-+ * certificate_chain, while ignoring everything else. */
-+ while (remaining_len >= 2) {
-+ unsigned char cached_object_type = *cached_info++;
-+ unsigned int cached_object_length = *cached_info++;
-+ remaining_len -= 2;
-+ if (remaining_len < cached_object_length)
-+ return SECFailure;
-+ if (cached_object_length != 8) /* The digest must be present. */
-+ return SECFailure;
-+ if (cached_object_type == cached_info_certificate_chain &&
-+ !ss->ssl3.cachedInfoCertChainDigestReceived) {
-+ ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE;
-+ memcpy(ss->ssl3.certChainDigest, cached_info, 8);
-+ }
-+ remaining_len -= cached_object_length;
-+ cached_info += cached_object_length;
-+ }
-+
-+ if (remaining_len != 0)
-+ return SECFailure;
-+
-+ if (ss->ssl3.cachedInfoCertChainDigestReceived) {
-+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-+ rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
-+ ssl3_ServerSendCachedInfoXtn);
-+ return SECSuccess;
-+ }
-+
-+ return SECSuccess;
-+}
-+
-+/* ssl3_ServerSendCachedInfoXtn builds the cached_info extension on the
-+ * server side. */
-+PRInt32
-+ssl3_ServerSendCachedInfoXtn(sslSocket * ss, PRBool append,
-+ PRUint32 maxBytes)
-+{
-+ PRInt32 extension_length = 2 /* extension type */ +
-+ 2 /* extension length */ +
-+ 2 /* cached_info length */ +
-+ 1 /* CachedInformationType */ +
-+ 1 /* hash value length (0) */;
-+ SECStatus rv;
-+
-+ PORT_Assert(ss->opt.enableCachedInfo);
-+
-+ if (append && maxBytes >= extension_length) {
-+ /* 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;
-+ /* Cached Information Length */
-+ rv = ssl3_AppendHandshakeNumber(ss, 2, 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, 0, 1);
-+ if (rv != SECSuccess)
-+ return -1;
-+ } else if (maxBytes < extension_length) {
-+ PORT_Assert(0);
-+ return 0;
-+ }
-+
-+ 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 df40f30..fcd15ca 100644
---- a/mozilla/security/nss/lib/ssl/sslauth.c
-+++ b/mozilla/security/nss/lib/ssl/sslauth.c
-@@ -95,6 +95,46 @@ 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;
-+}
-+
-+PRBool
-+SSL_CertChainDigestReceived(PRFileDesc *fd)
-+{
-+ sslSocket *ss;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_CertChainDigestReceived",
-+ SSL_GETPID(), fd));
-+ return SECFailure;
-+ }
-+
-+ return ss->ssl3.cachedInfoCertChainDigestReceived;
-+}
-+
- /* 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 8e2bd14..f1e9a3e 100644
---- a/mozilla/security/nss/lib/ssl/sslimpl.h
-+++ b/mozilla/security/nss/lib/ssl/sslimpl.h
-@@ -340,6 +340,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,
-@@ -754,6 +755,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
-@@ -832,6 +838,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 cachedInfoCertChainDigestReceived;
-+
- int policy;
- /* This says what cipher suites we can do, and should
- * be either SSL_ALLOWED or SSL_RESTRICTED
-@@ -839,7 +853,10 @@ struct ssl3StateStr {
- PRArenaPool * peerCertArena;
- /* These are used to keep track of the peer CA */
- void * peerCertChain;
-- /* chain while we are trying to validate it. */
-+ /* Chain while we are trying to validate it. This
-+ * does not include the leaf cert. It is actually a
-+ * linked list of ssl3CertNode structs.
-+ */
- CERTDistNames * ca_list;
- /* used by server. trusted CAs for this socket. */
- PRBool initialized;
-@@ -1524,6 +1541,10 @@ 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_ServerHandleCachedInfoXtn(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,
-@@ -1545,6 +1566,10 @@ 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);
-+extern PRInt32 ssl3_ServerSendCachedInfoXtn(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
-@@ -1648,6 +1673,12 @@ SECStatus SSL_DisableDefaultExportCipherSuites(void);
- SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd);
- PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite);
-
-+/********************** FNV hash *********************/
-+
-+void FNV1A64_Init(PRUint64 *digest);
-+void FNV1A64_Update(PRUint64 *digest, const unsigned char *data,
-+ unsigned int length);
-+void FNV1A64_Final(PRUint64 *digest);
-
- #ifdef TRACE
- #define SSL_TRACE(msg) ssl_Trace msg
-diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c
-index 4c4df3f..3d89d86 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;
-@@ -743,6 +744,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;
-@@ -808,6 +813,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);
-@@ -862,6 +868,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);
-@@ -1013,6 +1020,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_ */
« no previous file with comments | « net/third_party/nss/patches/cachecerts.patch ('k') | net/third_party/nss/patches/cbcrandomiv.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698