| Index: net/third_party/nss/patches/cachedinfo.patch
|
| ===================================================================
|
| --- net/third_party/nss/patches/cachedinfo.patch (revision 123842)
|
| +++ 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_ */
|
|
|