summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 13:12:34 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 13:12:34 +0000
commitc4984e39044533c41e629d1dc9aa5527eba872ea (patch)
treea3f1fcfb4dc4067ad103384b138bfef576b913ec /net
parent6c51eb0d8c35554465e13613a229d526e598cf43 (diff)
downloadchromium_src-c4984e39044533c41e629d1dc9aa5527eba872ea.zip
chromium_src-c4984e39044533c41e629d1dc9aa5527eba872ea.tar.gz
chromium_src-c4984e39044533c41e629d1dc9aa5527eba872ea.tar.bz2
net: update NSS patches to reflect recent changes.
This updates the cached info patch to reflect: Merge upstream NSS changes from the cached info extension (r93119) And adds a patch for the origin bound certs work in: Add client-side support for the origin bound certificate TLS extension. (r92576) No code changes. BUG=84920,88782 TEST=none Review URL: http://codereview.chromium.org/7464028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93615 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.patch336
-rw-r--r--net/third_party/nss/patches/cbcrandomiv.patch4
-rw-r--r--net/third_party/nss/patches/didhandshakeresume.patch6
-rw-r--r--net/third_party/nss/patches/origin_bound_certs.patch252
6 files changed, 573 insertions, 30 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index 02793ef..7e241a1 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -56,6 +56,9 @@ Patches:
record in order to randomize the IV in a backwards compatible manner.
patches/cbcrandomiv.patch
+ * Support origin bound certificates (http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.txt)
+ patches/origin_bound_certs.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 9aafb92..c32b9a7 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -24,3 +24,5 @@ patch -p6 < $patches_dir/cachedinfo.patch
patch -p6 < $patches_dir/didhandshakeresume.patch
patch -p6 < $patches_dir/cbcrandomiv.patch
+
+patch -p6 < $patches_dir/origin_bound_certs.patch
diff --git a/net/third_party/nss/patches/cachedinfo.patch b/net/third_party/nss/patches/cachedinfo.patch
index f57ad6d..dac852a 100644
--- a/net/third_party/nss/patches/cachedinfo.patch
+++ b/net/third_party/nss/patches/cachedinfo.patch
@@ -1,4 +1,4 @@
-commit d4212da54db71bcf4e1232a9692cbdafa3cecb0f
+commit 070963bde0a9c474733f19fbd525ff14e3f15803
Author: Adam Langley <agl@chromium.org>
Date: Fri Jun 24 13:10:38 2011 -0400
@@ -82,8 +82,20 @@ index 0000000..c7c4b08
+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 563cfd5..7357d9f 100644
+index 563cfd5..e7d6c54 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);
@@ -95,7 +107,34 @@ index 563cfd5..7357d9f 100644
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
-@@ -438,6 +440,17 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
+@@ -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
+@@ -438,6 +453,17 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
void *arg);
/*
@@ -114,7 +153,7 @@ index 563cfd5..7357d9f 100644
** 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
+index 0997e18..f7064ef 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)
@@ -125,7 +164,77 @@ index 0997e18..2cc1e05 100644
/* 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)
+@@ -7804,6 +7803,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. */
+@@ -7958,7 +8020,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
PRInt32 size;
SECStatus rv;
PRBool isServer = (PRBool)(!!ss->sec.isServer);
@@ -133,7 +242,7 @@ index 0997e18..2cc1e05 100644
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)
+@@ -8018,35 +8079,46 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto loser; /* don't send alerts on memory errors */
}
@@ -148,7 +257,7 @@ index 0997e18..2cc1e05 100644
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size <= 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-+ ss->ssl3.digestReceived = PR_TRUE;
++ ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE;
- if (remaining < size)
- goto decode_loser;
@@ -196,7 +305,7 @@ index 0997e18..2cc1e05 100644
+ }
+ } else {
+ /* We are dealing with a regular certificate message */
-+ ss->ssl3.digestReceived = PR_FALSE;
++ ss->ssl3.cachedInfoCertChainDigestReceived = PR_FALSE;
- /* Now get all of the CA certs. */
- while (remaining > 0) {
@@ -204,7 +313,7 @@ index 0997e18..2cc1e05 100644
remaining -= 3;
if (remaining < 0)
goto decode_loser;
-@@ -8060,35 +8069,61 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -8060,35 +8132,63 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
certItem.data = b;
certItem.len = size;
@@ -282,11 +391,31 @@ index 0997e18..2cc1e05 100644
- goto decode_loser;
+ if (remaining != 0)
+ goto decode_loser;
++
++ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
+ }
SECKEY_UpdateCertPQG(ss->sec.peerCert);
-@@ -8250,7 +8285,10 @@ alert_loser:
+@@ -8108,8 +8208,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;
+ }
+@@ -8179,8 +8277,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;
+@@ -8250,7 +8346,10 @@ alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
@@ -298,7 +427,7 @@ index 0997e18..2cc1e05 100644
ssl3_CleanupPeerCerts(ss);
if (ss->sec.peerCert != NULL) {
-@@ -9736,6 +9774,21 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
+@@ -9736,6 +9835,21 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
return rv;
}
@@ -320,7 +449,7 @@ index 0997e18..2cc1e05 100644
/* Called from ssl_DestroySocketContents() in sslsock.c */
void
ssl3_DestroySSL3Info(sslSocket *ss)
-@@ -9759,6 +9812,9 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -9759,6 +9873,9 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ss->ssl3.clientCertChain = NULL;
}
@@ -331,10 +460,18 @@ index 0997e18..2cc1e05 100644
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
+index 94dab58..79ed9e3 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[] = {
+@@ -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 },
@@ -342,7 +479,7 @@ index 94dab58..b68d2fd 100644
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
{ -1, NULL }
};
-@@ -272,6 +273,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+@@ -272,6 +274,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
#endif
{ ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
{ ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
@@ -350,7 +487,7 @@ index 94dab58..b68d2fd 100644
{ 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,
+@@ -676,6 +679,261 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
return SECSuccess;
}
@@ -415,9 +552,9 @@ index 94dab58..b68d2fd 100644
+ 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
++ certLen >> 16,
++ certLen >> 8,
++ certLen
+ };
+ FNV1A64_Update(&certChainHash, certLenArray, 3);
+ FNV1A64_Update(&certChainHash,
@@ -442,6 +579,111 @@ index 94dab58..b68d2fd 100644
+}
+
+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)
+{
@@ -508,10 +750,10 @@ index 94dab58..b68d2fd 100644
* 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
+index 447aaf8..8da5c66 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,
+@@ -95,6 +95,46 @@ SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs,
return SECSuccess;
}
@@ -540,11 +782,26 @@ index 447aaf8..6313603 100644
+ 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 2e1364e..bf47dc2 100644
+index 2e1364e..95a1eee 100644
--- a/mozilla/security/nss/lib/ssl/sslimpl.h
+++ b/mozilla/security/nss/lib/ssl/sslimpl.h
@@ -349,6 +349,7 @@ typedef struct sslOptionsStr {
@@ -577,29 +834,58 @@ index 2e1364e..bf47dc2 100644
+ PRUint8 certChainDigest[8];
+ /* Used in cached info extension. Stored in network
+ * byte order. */
-+ PRBool digestReceived;
++ PRBool cachedInfoCertChainDigestReceived;
+
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,
+@@ -861,7 +875,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;
+@@ -1550,6 +1567,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,
-@@ -1571,6 +1587,8 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append,
+@@ -1571,6 +1592,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
+@@ -1694,6 +1719,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 1bb211e..f00f8f4 100644
--- a/mozilla/security/nss/lib/ssl/sslsock.c
diff --git a/net/third_party/nss/patches/cbcrandomiv.patch b/net/third_party/nss/patches/cbcrandomiv.patch
index 9f1b57a..1edc04a 100644
--- a/net/third_party/nss/patches/cbcrandomiv.patch
+++ b/net/third_party/nss/patches/cbcrandomiv.patch
@@ -1,11 +1,11 @@
-commit 36840201a321147d9c33a944784ff56980aae5d8
+commit 95cc0cf361c92681803e7ee5d4afe5e40673a4b8
Author: Adam Langley <agl@chromium.org>
Date: Wed Jun 22 13:36:50 2011 -0400
cbcrandomiv.patch
diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
-index 2cc1e05..eb7d63e 100644
+index f7064ef..c39b8f8 100644
--- a/mozilla/security/nss/lib/ssl/ssl3con.c
+++ b/mozilla/security/nss/lib/ssl/ssl3con.c
@@ -2229,7 +2229,7 @@ ssl3_SendRecord( sslSocket * ss,
diff --git a/net/third_party/nss/patches/didhandshakeresume.patch b/net/third_party/nss/patches/didhandshakeresume.patch
index cfd2540..8c2a5a5 100644
--- a/net/third_party/nss/patches/didhandshakeresume.patch
+++ b/net/third_party/nss/patches/didhandshakeresume.patch
@@ -1,4 +1,4 @@
-commit 1b8c2b2242f6d6868d97c7915f84808134bc68a3
+commit c1b34e0cdaed8eef92aa268a442965eb60828c7b
Author: Adam Langley <agl@chromium.org>
Date: Tue Jun 21 11:41:12 2011 -0400
@@ -17,10 +17,10 @@ index 35cc1e3..7ef15db 100644
SSL_SetNextProtoNego;
;+ local:
diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
-index 7357d9f..20a5167 100644
+index e7d6c54..5682d0a 100644
--- a/mozilla/security/nss/lib/ssl/ssl.h
+++ b/mozilla/security/nss/lib/ssl/ssl.h
-@@ -717,6 +717,10 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
+@@ -730,6 +730,10 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
SSLExtensionType extId,
PRBool *yes);
diff --git a/net/third_party/nss/patches/origin_bound_certs.patch b/net/third_party/nss/patches/origin_bound_certs.patch
new file mode 100644
index 0000000..825c4b1
--- /dev/null
+++ b/net/third_party/nss/patches/origin_bound_certs.patch
@@ -0,0 +1,252 @@
+commit b5f89535668edebf59ac8186457d117572c05f2b
+Author: Adam Langley <agl@chromium.org>
+Date: Thu Jul 21 10:26:36 2011 -0400
+
+ obcerts
+
+diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
+index 5682d0a..53ca301 100644
+--- a/mozilla/security/nss/lib/ssl/ssl.h
++++ b/mozilla/security/nss/lib/ssl/ssl.h
+@@ -142,6 +142,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
+ #define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */
+ #define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */
+ /* extension, off by default. */
++#define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */
+
+ #ifdef SSL_DEPRECATED_FUNCTION
+ /* Old deprecated function names */
+diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
+index c39b8f8..66071d2 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3con.c
++++ b/mozilla/security/nss/lib/ssl/ssl3con.c
+@@ -2352,9 +2352,10 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
+ ssl_ReleaseSpecReadLock(ss);
+
+ if (isBlockCipher && len > 0) {
+- // We assume that block ciphers are used in CBC mode and prepend an
+- // empty record. This effectively randomizes the IV in a backwards
+- // compatible way.
++ /* We assume that block ciphers are used in CBC mode and prepend an
++ * empty record. This effectively randomizes the IV in a backwards
++ * compatible way.
++ */
+ PRInt32 sent = ssl3_SendRecord(ss, content_application_data,
+ in, 0 /* no payload */, flags);
+ if (sent < 0) {
+diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c
+index 79ed9e3..e54b4fd 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3ext.c
++++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
+@@ -237,6 +237,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
+ { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
+ { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
+ { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn },
++ { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn },
+ { -1, NULL }
+ };
+
+@@ -250,6 +251,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
+ { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
+ { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
++ { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn },
+ { -1, NULL }
+ };
+
+@@ -275,7 +277,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+ { 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 }
++ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
++ { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn }
+ /* any extra entries will appear as { 0, NULL } */
+ };
+
+@@ -1973,3 +1976,80 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
+ return rv;
+ }
+
++/* This sender is used by both the client and server. */
++PRInt32
++ssl3_SendOBCertXtn(sslSocket * ss, PRBool append,
++ PRUint32 maxBytes)
++{
++ SECStatus rv;
++ PRUint32 extension_length;
++
++ if (!ss)
++ return 0;
++
++ if (!ss->opt.enableOBCerts)
++ return 0;
++
++ /* extension length = extension_type (2-bytes) +
++ * length(extension_data) (2-bytes) +
++ */
++
++ extension_length = 4;
++
++ if (append && maxBytes >= extension_length) {
++ /* extension_type */
++ rv = ssl3_AppendHandshakeNumber(ss, ssl_ob_cert_xtn, 2);
++ if (rv != SECSuccess) return -1;
++ /* length of extension_data */
++ rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
++ if (rv != SECSuccess) return -1;
++
++ if (!ss->sec.isServer) {
++ TLSExtensionData *xtnData = &ss->xtnData;
++ xtnData->advertised[xtnData->numAdvertised++] = ssl_ob_cert_xtn;
++ }
++ }
++
++ return extension_length;
++}
++
++SECStatus
++ssl3_ServerHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type,
++ SECItem *data)
++{
++ SECStatus rv;
++
++ /* Ignore the OBCert extension if it is disabled. */
++ if (!ss->opt.enableOBCerts)
++ return SECSuccess;
++
++ /* The echoed extension must be empty. */
++ if (data->len != 0)
++ return SECFailure;
++
++ /* Keep track of negotiated extensions. */
++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
++
++ rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
++ ssl3_SendOBCertXtn);
++
++ return SECSuccess;
++}
++
++SECStatus
++ssl3_ClientHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type,
++ SECItem *data)
++{
++ /* If we didn't request this extension, then the server may not echo it. */
++ if (!ss->opt.enableOBCerts)
++ return SECFailure;
++
++ /* The echoed extension must be empty. */
++ if (data->len != 0)
++ return SECFailure;
++
++ /* Keep track of negotiated extensions. */
++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
++
++ return SECSuccess;
++}
+diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
+index 95a1eee..df30029 100644
+--- a/mozilla/security/nss/lib/ssl/sslimpl.h
++++ b/mozilla/security/nss/lib/ssl/sslimpl.h
+@@ -350,6 +350,7 @@ typedef struct sslOptionsStr {
+ unsigned int enableFalseStart : 1; /* 23 */
+ unsigned int enableOCSPStapling : 1; /* 24 */
+ unsigned int enableCachedInfo : 1; /* 25 */
++ unsigned int enableOBCerts : 1; /* 26 */
+ } sslOptions;
+
+ typedef enum { sslHandshakingUndetermined = 0,
+@@ -1573,10 +1574,14 @@ 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_ClientHandleOBCertXtn(sslSocket *ss,
++ PRUint16 ex_type, SECItem *data);
+ extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
+ extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
++extern SECStatus ssl3_ServerHandleOBCertXtn(sslSocket *ss,
++ PRUint16 ex_type, SECItem *data);
+
+ /* ClientHello and ServerHello extension senders.
+ * Note that not all extension senders are exposed here; only those that
+@@ -1596,6 +1601,8 @@ extern PRInt32 ssl3_ClientSendCachedInfoXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes);
+ extern PRInt32 ssl3_ServerSendCachedInfoXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes);
++extern PRInt32 ssl3_SendOBCertXtn(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 340d17c..68fd3cb 100644
+--- a/mozilla/security/nss/lib/ssl/sslsock.c
++++ b/mozilla/security/nss/lib/ssl/sslsock.c
+@@ -187,6 +187,7 @@ static sslOptions ssl_defaults = {
+ PR_FALSE, /* enableFalseStart */
+ PR_FALSE, /* enableOCSPStapling */
+ PR_FALSE, /* enableCachedInfo */
++ PR_TRUE, /* enableOBCerts */
+ };
+
+ sslSessionIDLookupFunc ssl_sid_lookup;
+@@ -752,6 +753,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
+ ss->opt.enableCachedInfo = on;
+ break;
+
++ case SSL_ENABLE_OB_CERTS:
++ ss->opt.enableOBCerts = on;
++ break;
++
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+@@ -817,7 +822,8 @@ 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;
++ case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break;
++ case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+@@ -873,6 +879,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
+ on = ssl_defaults.enableOCSPStapling;
+ break;
+ case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break;
++ case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+@@ -1028,6 +1035,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
+ ssl_defaults.enableCachedInfo = on;
+ break;
+
++ case SSL_ENABLE_OB_CERTS:
++ ssl_defaults.enableOBCerts = 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 bca7496..907c1dc 100644
+--- a/mozilla/security/nss/lib/ssl/sslt.h
++++ b/mozilla/security/nss/lib/ssl/sslt.h
+@@ -206,9 +206,10 @@ typedef enum {
+ ssl_session_ticket_xtn = 35,
+ ssl_next_proto_neg_xtn = 13172,
+ ssl_cached_info_xtn = 13173,
+- ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
++ ssl_renegotiation_info_xtn = 0xff01, /* experimental number */
++ ssl_ob_cert_xtn = 0xff0f /* experimental number */
+ } SSLExtensionType;
+
+-#define SSL_MAX_EXTENSIONS 8
++#define SSL_MAX_EXTENSIONS 9
+
+ #endif /* __sslt_h_ */