Home | History | Annotate | Download | only in patches
      1 diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
      2 --- a/nss/lib/ssl/ssl3con.c	2014-01-17 17:49:26.062517203 -0800
      3 +++ b/nss/lib/ssl/ssl3con.c	2014-01-17 17:51:23.974478249 -0800
      4 @@ -43,6 +43,7 @@
      5  
      6  static SECStatus ssl3_AuthCertificate(sslSocket *ss);
      7  static void      ssl3_CleanupPeerCerts(sslSocket *ss);
      8 +static void      ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
      9  static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
     10                                         PK11SlotInfo * serverKeySlot);
     11  static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
     12 @@ -6474,6 +6475,7 @@ ssl3_HandleServerHello(sslSocket *ss, SS
     13  	/* copy the peer cert from the SID */
     14  	if (sid->peerCert != NULL) {
     15  	    ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
     16 +	    ssl3_CopyPeerCertsFromSID(ss, sid);
     17  	}
     18  
     19  	/* NULL value for PMS signifies re-use of the old MS */
     20 @@ -8048,6 +8050,7 @@ compression_found:
     21  	ss->sec.ci.sid = sid;
     22  	if (sid->peerCert != NULL) {
     23  	    ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
     24 +	    ssl3_CopyPeerCertsFromSID(ss, sid);
     25  	}
     26  
     27  	/*
     28 @@ -9662,6 +9665,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
     29      ss->ssl3.peerCertChain = NULL;
     30  }
     31  
     32 +static void
     33 +ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid)
     34 +{
     35 +    PLArenaPool *arena;
     36 +    ssl3CertNode *lastCert = NULL;
     37 +    ssl3CertNode *certs = NULL;
     38 +    int i;
     39 +
     40 +    if (!sid->peerCertChain[0])
     41 +	return;
     42 +    PORT_Assert(!ss->ssl3.peerCertArena);
     43 +    PORT_Assert(!ss->ssl3.peerCertChain);
     44 +    ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     45 +    for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
     46 +	ssl3CertNode *c = PORT_ArenaNew(arena, ssl3CertNode);
     47 +	c->cert = CERT_DupCertificate(sid->peerCertChain[i]);
     48 +	c->next = NULL;
     49 +	if (lastCert) {
     50 +	    lastCert->next = c;
     51 +	} else {
     52 +	    certs = c;
     53 +	}
     54 +	lastCert = c;
     55 +    }
     56 +    ss->ssl3.peerCertChain = certs;
     57 +}
     58 +
     59 +static void
     60 +ssl3_CopyPeerCertsToSID(ssl3CertNode *certs, sslSessionID *sid)
     61 +{
     62 +    int i = 0;
     63 +    ssl3CertNode *c = certs;
     64 +    for (; i < MAX_PEER_CERT_CHAIN_SIZE && c; i++, c = c->next) {
     65 +	PORT_Assert(!sid->peerCertChain[i]);
     66 +	sid->peerCertChain[i] = CERT_DupCertificate(c->cert);
     67 +    }
     68 +}
     69 +
     70  /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
     71   * ssl3 CertificateStatus message.
     72   * Caller must hold Handshake and RecvBuf locks.
     73 @@ -9940,6 +9981,7 @@ ssl3_AuthCertificate(sslSocket *ss)
     74      }
     75  
     76      ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
     77 +    ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);
     78  
     79      if (!ss->sec.isServer) {
     80          CERTCertificate *cert = ss->sec.peerCert;
     81 diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
     82 --- a/nss/lib/ssl/sslimpl.h	2014-01-17 17:49:26.072517368 -0800
     83 +++ b/nss/lib/ssl/sslimpl.h	2014-01-17 17:51:23.984478418 -0800
     84 @@ -595,6 +595,8 @@ typedef enum {	never_cached,
     85  		invalid_cache		/* no longer in any cache. */
     86  } Cached;
     87  
     88 +#define MAX_PEER_CERT_CHAIN_SIZE 8
     89 +
     90  struct sslSessionIDStr {
     91      /* The global cache lock must be held when accessing these members when the
     92       * sid is in any cache.
     93 @@ -609,6 +611,7 @@ struct sslSessionIDStr {
     94       */
     95  
     96      CERTCertificate *     peerCert;
     97 +    CERTCertificate *     peerCertChain[MAX_PEER_CERT_CHAIN_SIZE];
     98      SECItemArray          peerCertStatus; /* client only */
     99      const char *          peerID;     /* client only */
    100      const char *          urlSvrName; /* client only */
    101 diff -pu a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c
    102 --- a/nss/lib/ssl/sslnonce.c	2014-01-17 17:49:26.072517368 -0800
    103 +++ b/nss/lib/ssl/sslnonce.c	2014-01-17 17:51:23.984478418 -0800
    104 @@ -164,6 +164,7 @@ lock_cache(void)
    105  static void
    106  ssl_DestroySID(sslSessionID *sid)
    107  {
    108 +    int i;
    109      SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
    110      PORT_Assert(sid->references == 0);
    111      PORT_Assert(sid->cached != in_client_cache);
    112 @@ -194,6 +195,9 @@ ssl_DestroySID(sslSessionID *sid)
    113      if ( sid->peerCert ) {
    114  	CERT_DestroyCertificate(sid->peerCert);
    115      }
    116 +    for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
    117 +	CERT_DestroyCertificate(sid->peerCertChain[i]);
    118 +    }
    119      if (sid->peerCertStatus.items) {
    120          SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
    121      }
    122