| OLD | NEW |
| 1 diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c | 1 diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c |
| 2 index 8f1c547..9aaf601 100644 | 2 index c3698f3..b8d4784 100644 |
| 3 --- a/lib/ssl/ssl3con.c | 3 --- a/lib/ssl/ssl3con.c |
| 4 +++ b/lib/ssl/ssl3con.c | 4 +++ b/lib/ssl/ssl3con.c |
| 5 @@ -45,6 +45,7 @@ | 5 @@ -47,6 +47,7 @@ |
| 6 | 6 |
| 7 static SECStatus ssl3_AuthCertificate(sslSocket *ss); | 7 static SECStatus ssl3_AuthCertificate(sslSocket *ss); |
| 8 static void ssl3_CleanupPeerCerts(sslSocket *ss); | 8 static void ssl3_CleanupPeerCerts(sslSocket *ss); |
| 9 +static void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid); | 9 +static void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid); |
| 10 static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, | 10 static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, |
| 11 PK11SlotInfo * serverKeySlot); | 11 PK11SlotInfo *serverKeySlot); |
| 12 static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); | 12 static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); |
| 13 @@ -6751,6 +6752,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUin
t32 length) | 13 @@ -7102,6 +7103,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUin
t32 length) |
| 14 » /* copy the peer cert from the SID */ | 14 /* copy the peer cert from the SID */ |
| 15 » if (sid->peerCert != NULL) { | 15 if (sid->peerCert != NULL) { |
| 16 » ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); | 16 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
| 17 +» ssl3_CopyPeerCertsFromSID(ss, sid); | 17 + ssl3_CopyPeerCertsFromSID(ss, sid); |
| 18 » } | 18 } |
| 19 | 19 |
| 20 » /* NULL value for PMS because we are reusing the old MS */ | 20 /* NULL value for PMS because we are reusing the old MS */ |
| 21 @@ -8405,6 +8407,7 @@ compression_found: | 21 @@ -8266,6 +8268,44 @@ ssl3_KEAAllowsSessionTicket(SSL3KeyExchangeAlgorithm kea) |
| 22 » ss->sec.ci.sid = sid; | 22 }; |
| 23 » if (sid->peerCert != NULL) { | |
| 24 » ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); | |
| 25 +» ssl3_CopyPeerCertsFromSID(ss, sid); | |
| 26 » } | |
| 27 | |
| 28 » /* | |
| 29 @@ -10389,6 +10392,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss) | |
| 30 ss->ssl3.peerCertChain = NULL; | |
| 31 } | 23 } |
| 32 | 24 |
| 33 +static void | 25 +static void |
| 34 +ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid) | 26 +ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid) |
| 35 +{ | 27 +{ |
| 36 + PLArenaPool *arena; | 28 + PLArenaPool *arena; |
| 37 + ssl3CertNode *lastCert = NULL; | 29 + ssl3CertNode *lastCert = NULL; |
| 38 + ssl3CertNode *certs = NULL; | 30 + ssl3CertNode *certs = NULL; |
| 39 + int i; | 31 + int i; |
| 40 + | 32 + |
| 41 + if (!sid->peerCertChain[0]) | 33 + if (!sid->peerCertChain[0]) |
| 42 +» return; | 34 + return; |
| 43 + PORT_Assert(!ss->ssl3.peerCertArena); | 35 + PORT_Assert(!ss->ssl3.peerCertArena); |
| 44 + PORT_Assert(!ss->ssl3.peerCertChain); | 36 + PORT_Assert(!ss->ssl3.peerCertChain); |
| 45 + ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 37 + ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 46 + for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) { | 38 + for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) { |
| 47 +» ssl3CertNode *c = PORT_ArenaNew(arena, ssl3CertNode); | 39 + ssl3CertNode *c = PORT_ArenaNew(arena, ssl3CertNode); |
| 48 +» c->cert = CERT_DupCertificate(sid->peerCertChain[i]); | 40 + c->cert = CERT_DupCertificate(sid->peerCertChain[i]); |
| 49 +» c->next = NULL; | 41 + c->next = NULL; |
| 50 +» if (lastCert) { | 42 + if (lastCert) { |
| 51 +» lastCert->next = c; | 43 + lastCert->next = c; |
| 52 +» } else { | 44 + } else { |
| 53 +» certs = c; | 45 + certs = c; |
| 54 +» } | 46 + } |
| 55 +» lastCert = c; | 47 + lastCert = c; |
| 56 + } | 48 + } |
| 57 + ss->ssl3.peerCertChain = certs; | 49 + ss->ssl3.peerCertChain = certs; |
| 58 +} | 50 +} |
| 59 + | 51 + |
| 60 +static void | 52 +static void |
| 61 +ssl3_CopyPeerCertsToSID(ssl3CertNode *certs, sslSessionID *sid) | 53 +ssl3_CopyPeerCertsToSID(ssl3CertNode *certs, sslSessionID *sid) |
| 62 +{ | 54 +{ |
| 63 + int i = 0; | 55 + int i = 0; |
| 64 + ssl3CertNode *c = certs; | 56 + ssl3CertNode *c = certs; |
| 65 + for (; i < MAX_PEER_CERT_CHAIN_SIZE && c; i++, c = c->next) { | 57 + for (; i < MAX_PEER_CERT_CHAIN_SIZE && c; i++, c = c->next) { |
| 66 +» PORT_Assert(!sid->peerCertChain[i]); | 58 + PORT_Assert(!sid->peerCertChain[i]); |
| 67 +» sid->peerCertChain[i] = CERT_DupCertificate(c->cert); | 59 + sid->peerCertChain[i] = CERT_DupCertificate(c->cert); |
| 68 + } | 60 + } |
| 69 +} | 61 +} |
| 70 + | 62 + |
| 71 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete | 63 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
| 72 * ssl3 CertificateStatus message. | 64 * ssl3 Client Hello message. |
| 73 * Caller must hold Handshake and RecvBuf locks. | 65 * Caller must hold Handshake and RecvBuf locks. |
| 74 @@ -10669,6 +10710,7 @@ ssl3_AuthCertificate(sslSocket *ss) | 66 @@ -8886,6 +8926,7 @@ compression_found: |
| 67 ss->sec.ci.sid = sid; |
| 68 if (sid->peerCert != NULL) { |
| 69 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
| 70 + ssl3_CopyPeerCertsFromSID(ss, sid); |
| 71 } |
| 72 |
| 73 /* |
| 74 @@ -11240,6 +11281,7 @@ ssl3_AuthCertificate(sslSocket *ss) |
| 75 } | 75 } |
| 76 | 76 |
| 77 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); | 77 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); |
| 78 + ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); | 78 + ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); |
| 79 | 79 |
| 80 if (!ss->sec.isServer) { | 80 if (!ss->sec.isServer) { |
| 81 CERTCertificate *cert = ss->sec.peerCert; | 81 CERTCertificate *cert = ss->sec.peerCert; |
| 82 diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h | 82 diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h |
| 83 index ad31aae..9dcc29e 100644 | 83 index bce9437..10361a0 100644 |
| 84 --- a/lib/ssl/sslimpl.h | 84 --- a/lib/ssl/sslimpl.h |
| 85 +++ b/lib/ssl/sslimpl.h | 85 +++ b/lib/ssl/sslimpl.h |
| 86 @@ -608,6 +608,8 @@ typedef enum {» never_cached, | 86 @@ -614,6 +614,8 @@ typedef enum { never_cached, |
| 87 » » invalid_cache» » /* no longer in any cache. */ | 87 invalid_cache /* no longer in any cache. */ |
| 88 } Cached; | 88 } Cached; |
| 89 | 89 |
| 90 +#define MAX_PEER_CERT_CHAIN_SIZE 8 | 90 +#define MAX_PEER_CERT_CHAIN_SIZE 8 |
| 91 + | 91 + |
| 92 struct sslSessionIDStr { | 92 struct sslSessionIDStr { |
| 93 /* The global cache lock must be held when accessing these members when the | 93 /* The global cache lock must be held when accessing these members when the |
| 94 * sid is in any cache. | 94 * sid is in any cache. |
| 95 @@ -622,6 +624,7 @@ struct sslSessionIDStr { | 95 @@ -628,6 +630,7 @@ struct sslSessionIDStr { |
| 96 */ | 96 */ |
| 97 | 97 |
| 98 CERTCertificate * peerCert; | 98 CERTCertificate *peerCert; |
| 99 + CERTCertificate * peerCertChain[MAX_PEER_CERT_CHAIN_SIZE]; | 99 + CERTCertificate *peerCertChain[MAX_PEER_CERT_CHAIN_SIZE]; |
| 100 SECItemArray peerCertStatus; /* client only */ | 100 SECItemArray peerCertStatus; /* client only */ |
| 101 const char * peerID; /* client only */ | 101 const char *peerID; /* client only */ |
| 102 const char * urlSvrName; /* client only */ | 102 const char *urlSvrName; /* client only */ |
| 103 diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c | 103 diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c |
| 104 index 2e861f1..be11008 100644 | 104 index 85031c4..3216892 100644 |
| 105 --- a/lib/ssl/sslnonce.c | 105 --- a/lib/ssl/sslnonce.c |
| 106 +++ b/lib/ssl/sslnonce.c | 106 +++ b/lib/ssl/sslnonce.c |
| 107 @@ -164,6 +164,7 @@ lock_cache(void) | 107 @@ -167,6 +167,7 @@ lock_cache(void) |
| 108 static void | 108 static void |
| 109 ssl_DestroySID(sslSessionID *sid) | 109 ssl_DestroySID(sslSessionID *sid) |
| 110 { | 110 { |
| 111 + int i; | 111 + int i; |
| 112 SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached)); | 112 SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached)); |
| 113 PORT_Assert(sid->references == 0); | 113 PORT_Assert(sid->references == 0); |
| 114 PORT_Assert(sid->cached != in_client_cache); | 114 PORT_Assert(sid->cached != in_client_cache); |
| 115 @@ -194,6 +195,9 @@ ssl_DestroySID(sslSessionID *sid) | 115 @@ -200,6 +201,9 @@ ssl_DestroySID(sslSessionID *sid) |
| 116 if ( sid->peerCert ) { | 116 if (sid->peerCert) { |
| 117 » CERT_DestroyCertificate(sid->peerCert); | 117 CERT_DestroyCertificate(sid->peerCert); |
| 118 } | 118 } |
| 119 + for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) { | 119 + for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) { |
| 120 + CERT_DestroyCertificate(sid->peerCertChain[i]); | 120 + CERT_DestroyCertificate(sid->peerCertChain[i]); |
| 121 + } | 121 + } |
| 122 if (sid->peerCertStatus.items) { | 122 if (sid->peerCertStatus.items) { |
| 123 SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE); | 123 SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE); |
| 124 } | 124 } |
| OLD | NEW |