blob: 8c3e60b5815135b7ac026e71846f43bfb5af948d [file] [log] [blame]
diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:19:29.665155332 -0800
+++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:20:08.835732728 -0800
@@ -42,6 +42,7 @@
#endif
static void ssl3_CleanupPeerCerts(sslSocket *ss);
+static void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo * serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
@@ -5575,6 +5576,7 @@ ssl3_HandleServerHello(sslSocket *ss, SS
/* copy the peer cert from the SID */
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
+ ssl3_CopyPeerCertsFromSID(ss, sid);
}
@@ -6916,6 +6918,7 @@ compression_found:
ss->sec.ci.sid = sid;
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
+ ssl3_CopyPeerCertsFromSID(ss, sid);
}
/*
@@ -8323,6 +8326,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
ss->ssl3.peerCertChain = NULL;
}
+static void
+ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid)
+{
+ PRArenaPool *arena;
+ ssl3CertNode *lastCert = NULL;
+ ssl3CertNode *certs = NULL;
+ int i;
+
+ if (!sid->peerCertChain[0])
+ return;
+ PORT_Assert(!ss->ssl3.peerCertArena);
+ PORT_Assert(!ss->ssl3.peerCertChain);
+ ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
+ ssl3CertNode *c = PORT_ArenaNew(arena, ssl3CertNode);
+ c->cert = CERT_DupCertificate(sid->peerCertChain[i]);
+ c->next = NULL;
+ if (lastCert) {
+ lastCert->next = c;
+ } else {
+ certs = c;
+ }
+ lastCert = c;
+ }
+ ss->ssl3.peerCertChain = certs;
+}
+
+static void
+ssl3_CopyPeerCertsToSID(ssl3CertNode *certs, sslSessionID *sid)
+{
+ int i = 0;
+ ssl3CertNode *c = certs;
+ for (; i < MAX_PEER_CERT_CHAIN_SIZE && c; i++, c = c->next) {
+ PORT_Assert(!sid->peerCertChain[i]);
+ sid->peerCertChain[i] = CERT_DupCertificate(c->cert);
+ }
+}
+
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 Certificate message.
* Caller must hold Handshake and RecvBuf locks.
@@ -8510,6 +8551,7 @@ ssl3_HandleCertificate(sslSocket *ss, SS
}
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
+ ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);
if (!ss->sec.isServer) {
CERTCertificate *cert = ss->sec.peerCert;
diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
--- a/net/third_party/nss/ssl/sslimpl.h 2012-09-27 18:46:45.000000000 -0700
+++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:20:08.835732728 -0800
@@ -571,10 +571,13 @@ typedef enum { never_cached,
invalid_cache /* no longer in any cache. */
} Cached;
+#define MAX_PEER_CERT_CHAIN_SIZE 8
+
struct sslSessionIDStr {
sslSessionID * next; /* chain used for client sockets, only */
CERTCertificate * peerCert;
+ CERTCertificate * peerCertChain[MAX_PEER_CERT_CHAIN_SIZE];
const char * peerID; /* client only */
const char * urlSvrName; /* client only */
CERTCertificate * localCert;
diff -pu -r a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c
--- a/net/third_party/nss/ssl/sslnonce.c 2012-04-25 07:50:12.000000000 -0700
+++ b/net/third_party/nss/ssl/sslnonce.c 2012-11-09 15:20:08.835732728 -0800
@@ -165,6 +165,7 @@ lock_cache(void)
static void
ssl_DestroySID(sslSessionID *sid)
{
+ int i;
SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
PORT_Assert((sid->references == 0));
@@ -184,6 +185,9 @@ ssl_DestroySID(sslSessionID *sid)
if ( sid->peerCert ) {
CERT_DestroyCertificate(sid->peerCert);
}
+ for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
+ CERT_DestroyCertificate(sid->peerCertChain[i]);
+ }
if ( sid->localCert ) {
CERT_DestroyCertificate(sid->localCert);
}