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