Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: net/third_party/nss/patches/cachedinfo.patch

Issue 9558017: Update net/third_party/nss to NSS 3.13.3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Upload before checkin Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 From 1c425d479c495d266c23876887198a54e82e7078 Mon Sep 17 00:00:00 2001
2 From: Adam Langley <agl@chromium.org>
3 Date: Mon, 3 Oct 2011 12:22:24 -0400
4 Subject: [PATCH] cachedinfo.patch
5
6 ---
7 mozilla/security/nss/lib/ssl/fnv1a64.c | 72 +++++++++
8 mozilla/security/nss/lib/ssl/manifest.mn | 1 +
9 mozilla/security/nss/lib/ssl/ssl.h | 26 +++
10 mozilla/security/nss/lib/ssl/ssl3con.c | 221 +++++++++++++++++++------
11 mozilla/security/nss/lib/ssl/ssl3ext.c | 258 ++++++++++++++++++++++++++++++
12 mozilla/security/nss/lib/ssl/sslauth.c | 40 +++++
13 mozilla/security/nss/lib/ssl/sslimpl.h | 33 ++++-
14 mozilla/security/nss/lib/ssl/sslsock.c | 11 ++
15 mozilla/security/nss/lib/ssl/sslt.h | 3 +-
16 9 files changed, 611 insertions(+), 54 deletions(-)
17 create mode 100644 mozilla/security/nss/lib/ssl/fnv1a64.c
18
19 diff --git a/mozilla/security/nss/lib/ssl/fnv1a64.c b/mozilla/security/nss/lib/s sl/fnv1a64.c
20 new file mode 100644
21 index 0000000..c7c4b08
22 --- /dev/null
23 +++ b/mozilla/security/nss/lib/ssl/fnv1a64.c
24 @@ -0,0 +1,72 @@
25 +/*
26 + * FNV1A64 Hash
27 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
28 + *
29 + * ***** BEGIN LICENSE BLOCK *****
30 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
31 + *
32 + * The contents of this file are subject to the Mozilla Public License Version
33 + * 1.1 (the "License"); you may not use this file except in compliance with
34 + * the License. You may obtain a copy of the License at
35 + * http://www.mozilla.org/MPL/
36 + *
37 + * Software distributed under the License is distributed on an "AS IS" basis,
38 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
39 + * for the specific language governing rights and limitations under the
40 + * License.
41 + *
42 + * The Original Code is the Netscape security libraries.
43 + *
44 + * The Initial Developer of the Original Code is
45 + * Netscape Communications Corporation.
46 + * Portions created by the Initial Developer are Copyright (C) 1994-2000
47 + * the Initial Developer. All Rights Reserved.
48 + *
49 + * Contributor(s):
50 + * Adam Langley, Google Inc.
51 + *
52 + * Alternatively, the contents of this file may be used under the terms of
53 + * either the GNU General Public License Version 2 or later (the "GPL"), or
54 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
55 + * in which case the provisions of the GPL or the LGPL are applicable instead
56 + * of those above. If you wish to allow use of your version of this file only
57 + * under the terms of either the GPL or the LGPL, and not to allow others to
58 + * use your version of this file under the terms of the MPL, indicate your
59 + * decision by deleting the provisions above and replace them with the notice
60 + * and other provisions required by the GPL or the LGPL. If you do not delete
61 + * the provisions above, a recipient may use your version of this file under
62 + * the terms of any one of the MPL, the GPL or the LGPL.
63 + *
64 + * ***** END LICENSE BLOCK ***** */
65 +
66 +/* $Id: fnv1a64.c,v 1.0 2010/08/09 13:00:00 agl%google.com Exp $ */
67 +
68 +#include "prtypes.h"
69 +#include "prnetdb.h"
70 +
71 +/* Older versions of Visual C++ don't support the 'ull' suffix. */
72 +#ifdef _MSC_VER
73 +static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ui64;
74 +static const PRUint64 FNV1A64_PRIME = 1099511628211ui64;
75 +#else
76 +static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ull;
77 +static const PRUint64 FNV1A64_PRIME = 1099511628211ull;
78 +#endif
79 +
80 +void FNV1A64_Init(PRUint64* digest) {
81 + *digest = FNV1A64_OFFSET_BASIS;
82 +}
83 +
84 +void FNV1A64_Update(PRUint64* digest, const unsigned char *data,
85 + unsigned int length) {
86 + unsigned int i;
87 +
88 + for (i = 0; i < length; i++) {
89 + *digest ^= data[i];
90 + *digest *= FNV1A64_PRIME;
91 + }
92 +}
93 +
94 +void FNV1A64_Final(PRUint64 *digest) {
95 + *digest = PR_htonll(*digest);
96 +}
97 diff --git a/mozilla/security/nss/lib/ssl/manifest.mn b/mozilla/security/nss/lib /ssl/manifest.mn
98 index 8451229..f09d770 100644
99 --- a/mozilla/security/nss/lib/ssl/manifest.mn
100 +++ b/mozilla/security/nss/lib/ssl/manifest.mn
101 @@ -51,6 +51,7 @@ MAPFILE = $(OBJDIR)/ssl.def
102
103 CSRCS = \
104 derive.c \
105 + fnv1a64.c \
106 prelib.c \
107 ssl3con.c \
108 ssl3gthr.c \
109 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s sl.h
110 index 221fe2d..3a22b45 100644
111 --- a/mozilla/security/nss/lib/ssl/ssl.h
112 +++ b/mozilla/security/nss/lib/ssl/ssl.h
113 @@ -140,6 +140,8 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFil eDesc *fd);
114 /* bits. The advantage of False Start is that it saves a round trip for */
115 /* client-speaks-first protocols when performing a full handshake. */
116 #define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */
117 +#define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */
118 + /* extension, off by default. */
119
120 #ifdef SSL_DEPRECATED_FUNCTION
121 /* Old deprecated function names */
122 @@ -256,6 +258,12 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
123 #define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */
124
125 /*
126 +** Returns true if the server's Certificate message contained a hash of the
127 +** certificate chain due to the TLS cached info extension.
128 +*/
129 +SSL_IMPORT PRBool SSL_CertChainDigestReceived(PRFileDesc *fd);
130 +
131 +/*
132 ** Return the certificate for our SSL peer. If the client calls this
133 ** it will always return the server's certificate. If the server calls
134 ** this, it may return NULL if client authentication is not enabled or
135 @@ -275,6 +283,13 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
136 SSL_IMPORT SECStatus SSL_PeerCertificateChain(
137 PRFileDesc *fd, CERTCertificate **certs, unsigned int *certs_size);
138
139 +/*
140 +** Set the predicted cert chain to be used in the cached info extension.
141 +*/
142 +SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(PRFileDesc *fd,
143 + CERTCertificate **certs,
144 + unsigned int len);
145 +
146 /* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by
147 * the TLS server. The resulting data is copied to |out_data|. On entry, |*len|
148 * must contain the size of |out_data|. On exit, |*len| will contain the size
149 @@ -405,6 +420,17 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBad CertHandler f,
150 void *arg);
151
152 /*
153 + ** Set the predicted chain of certificates for the peer. This is used for the
154 + ** TLS Cached Info extension. Note that the SSL_ENABLE_CACHED_INFO option must
155 + ** be set for this to occur.
156 + **
157 + ** This function takes a reference to each of the given certificates.
158 + */
159 + SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(
160 + PRFileDesc *fd, CERTCertificate **certs,
161 + unsigned int numCerts);
162 +
163 +/*
164 ** Configure SSL socket for running a secure server. Needs the
165 ** certificate for the server and the servers private key. The arguments
166 ** are copied.
167 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s sl/ssl3con.c
168 index ca2793f..dd99962 100644
169 --- a/mozilla/security/nss/lib/ssl/ssl3con.c
170 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c
171 @@ -5145,7 +5145,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUin t32 length)
172 ssl3_CopyPeerCertsFromSID(ss, sid);
173 }
174
175 -
176 /* NULL value for PMS signifies re-use of the old MS */
177 rv = ssl3_InitPendingCipherSpec(ss, NULL);
178 if (rv != SECSuccess) {
179 @@ -7715,6 +7714,69 @@ ssl3_SendCertificate(sslSocket *ss)
180 }
181 }
182
183 + if (ss->ssl3.cachedInfoCertChainDigestReceived) {
184 + /* Compute hash. */
185 + PRUint64 certChainHash;
186 + int i;
187 + FNV1A64_Init(&certChainHash);
188 + for (i = 0; i < certChain->len; i++) {
189 + unsigned int certLen = certChain->certs[i].len;
190 + unsigned char certLenArray[3] = {
191 + certLen >> 16,
192 + certLen >> 8,
193 + certLen
194 + };
195 + FNV1A64_Update(&certChainHash, certLenArray, sizeof(certLenArray));
196 + FNV1A64_Update(&certChainHash, certChain->certs[i].data, certLen);
197 + }
198 + FNV1A64_Final(&certChainHash);
199 +
200 + /* Both |&certChainHash| and |ss->ssl3.certChainDigest| should be in
201 + * network byte order since both are computed with the FNV1A64 hash,
202 + * which calls the function htonll.
203 + */
204 + if (memcmp(&certChainHash, ss->ssl3.certChainDigest,
205 + sizeof(certChainHash)) == 0) {
206 + /* The client correctly predicted the certificate chain. */
207 +
208 + /* Handshake type: certificate. */
209 + rv = ssl3_AppendHandshakeNumber(ss, certificate, 1);
210 + if (rv != SECSuccess) {
211 + return rv; /* err set by AppendHandshake. */
212 + }
213 + /* Handshake message length. */
214 + rv = ssl3_AppendHandshakeNumber(ss, 15, 3);
215 + if (rv != SECSuccess) {
216 + return rv; /* err set by AppendHandshake. */
217 + }
218 + /* CertChainLen(3) + ASN.1CertLen(3) + DigestLen(1) + Digest(8) */
219 + rv = ssl3_AppendHandshakeNumber(ss, 12, 3);
220 + if (rv != SECSuccess) {
221 + return rv; /* err set by AppendHandshake. */
222 + }
223 + /* ASN.1CertLen(3) + DigestLen(1) + Digest(8) */
224 + rv = ssl3_AppendHandshakeNumber(ss, 9, 3);
225 + if (rv != SECSuccess) {
226 + return rv; /* err set by AppendHandshake. */
227 + }
228 + /* Digest Length Byte */
229 + rv = ssl3_AppendHandshakeNumber(ss, sizeof(certChainHash), 1);
230 + if (rv != SECSuccess) {
231 + return rv; /* err set by AppendHandshake. */
232 + }
233 + /* Digest */
234 + rv = ssl3_AppendHandshake(ss, &certChainHash,
235 + sizeof(certChainHash));
236 + if (rv != SECSuccess) {
237 + return rv; /* err set by AppendHandshake. */
238 + }
239 +
240 + return SECSuccess;
241 + }
242 + }
243 +
244 + /* Send the entire certificate as usual. */
245 +
246 rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
247 if (rv != SECSuccess) {
248 return rv; /* err set by AppendHandshake. */
249 @@ -7869,7 +7931,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUin t32 length)
250 PRInt32 size;
251 SECStatus rv;
252 PRBool isServer = (PRBool)(!!ss->sec.isServer);
253 - PRBool trusted = PR_FALSE;
254 PRBool isTLS;
255 SSL3AlertDescription desc = bad_certificate;
256 int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
257 @@ -7929,35 +7990,46 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRU int32 length)
258 goto loser; /* don't send alerts on memory errors */
259 }
260
261 - /* First get the peer cert. */
262 - remaining -= 3;
263 - if (remaining < 0)
264 - goto decode_loser;
265 + if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) {
266 + /* We are dealing with a certificate_chain digest */
267 + int i;
268
269 - size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
270 - if (size <= 0)
271 - goto loser; /* fatal alert already sent by ConsumeHandshake. */
272 + ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE;
273
274 - if (remaining < size)
275 - goto decode_loser;
276 + /* Make sure the digests match. */
277 + if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) {
278 + desc = handshake_failure;
279 + goto alert_loser;
280 + }
281
282 - certItem.data = b;
283 - certItem.len = size;
284 - b += size;
285 - length -= size;
286 - remaining -= size;
287 + /* First get the peer cert. */
288 + if (ss->ssl3.predictedCertChain[0] == NULL) {
289 + desc = handshake_failure;
290 + goto alert_loser;
291 + }
292 + ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]);
293
294 - ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
295 - PR_FALSE, PR_TRUE);
296 - if (ss->sec.peerCert == NULL) {
297 - /* We should report an alert if the cert was bad, but not if the
298 - * problem was just some local problem, like memory error.
299 - */
300 - goto ambiguous_err;
301 - }
302 + /* Now get all of the CA certs. */
303 + ss->ssl3.peerCertChain = NULL;
304 + for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) {
305 + c = PORT_ArenaNew(arena, ssl3CertNode);
306 + if (c == NULL) {
307 + goto loser; /* don't send alerts on memory errors */
308 + }
309 + c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]);
310 + c->next = NULL;
311 + if (lastCert) {
312 + lastCert->next = c;
313 + } else {
314 + ss->ssl3.peerCertChain = c;
315 + }
316 + lastCert = c;
317 + }
318 + } else {
319 + /* We are dealing with a regular certificate message */
320 + ss->ssl3.cachedInfoCertChainDigestReceived = PR_FALSE;
321
322 - /* Now get all of the CA certs. */
323 - while (remaining > 0) {
324 + /* First get the peer cert. */
325 remaining -= 3;
326 if (remaining < 0)
327 goto decode_loser;
328 @@ -7971,35 +8043,63 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRU int32 length)
329
330 certItem.data = b;
331 certItem.len = size;
332 - b += size;
333 + b += size;
334 length -= size;
335 remaining -= size;
336
337 - c = PORT_ArenaNew(arena, ssl3CertNode);
338 - if (c == NULL) {
339 - goto loser; /* don't send alerts on memory errors */
340 - }
341 -
342 - c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
343 - PR_FALSE, PR_TRUE);
344 - if (c->cert == NULL) {
345 + ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem,
346 + NULL, PR_FALSE, PR_TRUE);
347 + if (ss->sec.peerCert == NULL) {
348 + /* We should report an alert if the cert was bad, but not if the
349 + * problem was just some local problem, like memory error.
350 + */
351 goto ambiguous_err;
352 }
353
354 - if (c->cert->trust)
355 - trusted = PR_TRUE;
356 + /* Now get all of the CA certs. */
357 + while (remaining > 0) {
358 + remaining -= 3;
359 + if (remaining < 0)
360 + goto decode_loser;
361
362 - c->next = NULL;
363 - if (lastCert) {
364 - lastCert->next = c;
365 - } else {
366 - certs = c;
367 + size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
368 + if (size <= 0)
369 + goto loser; /* fatal alert already sent by ConsumeHandshake. */
370 +
371 + if (remaining < size)
372 + goto decode_loser;
373 +
374 + certItem.data = b;
375 + certItem.len = size;
376 + b += size;
377 + length -= size;
378 + remaining -= size;
379 +
380 + c = PORT_ArenaNew(arena, ssl3CertNode);
381 + if (c == NULL) {
382 + goto loser; /* don't send alerts on memory errors */
383 + }
384 +
385 + c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
386 + PR_FALSE, PR_TRUE);
387 + if (c->cert == NULL) {
388 + goto ambiguous_err;
389 + }
390 +
391 + c->next = NULL;
392 + if (lastCert) {
393 + lastCert->next = c;
394 + } else {
395 + certs = c;
396 + }
397 + lastCert = c;
398 }
399 - lastCert = c;
400 - }
401
402 - if (remaining != 0)
403 - goto decode_loser;
404 + if (remaining != 0)
405 + goto decode_loser;
406 +
407 + ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
408 + }
409
410 SECKEY_UpdateCertPQG(ss->sec.peerCert);
411
412 @@ -8019,8 +8119,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUin t32 length)
413 /* someone will handle this connection asynchronously*/
414 SSL_DBG(("%d: SSL3[%d]: go to async cert handler",
415 SSL_GETPID(), ss->fd));
416 - ss->ssl3.peerCertChain = certs;
417 - certs = NULL;
418 ssl_SetAlwaysBlock(ss);
419 goto cert_block;
420 }
421 @@ -8045,7 +8143,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUin t32 length)
422 }
423
424 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
425 - ssl3_CopyPeerCertsToSID(certs, ss->sec.ci.sid);
426 + ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);
427
428 if (!ss->sec.isServer) {
429 /* set the server authentication and key exchange types and sizes
430 @@ -8090,8 +8188,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUin t32 length)
431 }
432 }
433
434 - ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
435 -
436 cert_block:
437 if (ss->sec.isServer) {
438 ss->ssl3.hs.ws = wait_client_key;
439 @@ -8161,7 +8257,10 @@ alert_loser:
440 (void)SSL3_SendAlert(ss, alert_fatal, desc);
441
442 loser:
443 - ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
444 + if (ss->ssl3.peerCertChain == NULL) {
445 + ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
446 + }
447 + PORT_Assert(certs == NULL);
448 ssl3_CleanupPeerCerts(ss);
449
450 if (ss->sec.peerCert != NULL) {
451 @@ -9647,6 +9746,21 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
452 return rv;
453 }
454
455 +static void
456 +ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) {
457 + unsigned int i;
458 +
459 + if (!ss->ssl3.predictedCertChain)
460 + return;
461 +
462 + for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
463 + CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]);
464 + }
465 +
466 + PORT_Free(ss->ssl3.predictedCertChain);
467 + ss->ssl3.predictedCertChain = NULL;
468 +}
469 +
470 /* Called from ssl_DestroySocketContents() in sslsock.c */
471 void
472 ssl3_DestroySSL3Info(sslSocket *ss)
473 @@ -9666,6 +9780,9 @@ ssl3_DestroySSL3Info(sslSocket *ss)
474 ss->ssl3.clientCertChain = NULL;
475 }
476
477 + if (ss->ssl3.predictedCertChain != NULL)
478 + ssl3_CleanupPredictedPeerCertificates(ss);
479 +
480 /* clean up handshake */
481 if (ss->opt.bypassPKCS11) {
482 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
483 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s sl/ssl3ext.c
484 index 4e3d9cc..17898fb 100644
485 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c
486 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
487 @@ -236,6 +236,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
488 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
489 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
490 { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
491 + { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn },
492 { -1, NULL }
493 };
494
495 @@ -247,6 +248,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL S[] = {
496 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
497 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
498 { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
499 + { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn },
500 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
501 { -1, NULL }
502 };
503 @@ -272,6 +274,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN SIONS] = {
504 #endif
505 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
506 { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
507 + { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn },
508 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
509 /* any extra entries will appear as { 0, NULL } */
510 };
511 @@ -676,6 +679,261 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
512 return SECSuccess;
513 }
514
515 +/* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the
516 + * client side. */
517 +PRInt32
518 +ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append,
519 + PRUint32 maxBytes)
520 +{
521 + PRInt32 extension_length;
522 + PRBool send_empty;
523 + CERTCertificate ** predictedCertChain;
524 +
525 + if (!ss->opt.enableCachedInfo)
526 + return 0;
527 +
528 + predictedCertChain = ss->ssl3.predictedCertChain;
529 + send_empty = (predictedCertChain == NULL);
530 +
531 + /* minimum extension:
532 + * extension_type (2-bytes) +
533 + * length(extension_data) (2-bytes) +
534 + * length(cached_info) (2-bytes) +
535 + */
536 + extension_length = send_empty ? 6 : 16;
537 +
538 + if (append && maxBytes >= extension_length) {
539 + SECStatus rv;
540 +
541 + /* ExtensionType */
542 + rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2);
543 + if (rv != SECSuccess)
544 + return -1;
545 + /* Extension Length */
546 + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
547 + if (rv != SECSuccess)
548 + return -1;
549 + if (send_empty) {
550 + /* Cached Information Length */
551 + rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
552 + if (rv != SECSuccess)
553 + return -1;
554 + } else {
555 + PRUint64 certChainHash;
556 + int i;
557 + PRUint8* digestPtr = (PRUint8*) &certChainHash;
558 +
559 + /* Cached Information Length */
560 + rv = ssl3_AppendHandshakeNumber(ss, 10, 2);
561 + if (rv != SECSuccess)
562 + return -1;
563 + /* Cached Information Type */
564 + rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1);
565 + if (rv != SECSuccess)
566 + return -1;
567 + /* hash length */
568 + rv = ssl3_AppendHandshakeNumber(ss, 8, 1);
569 + if (rv != SECSuccess)
570 + return -1;
571 + /* hash */
572 + FNV1A64_Init(&certChainHash);
573 + for (i = 0; predictedCertChain[i] != NULL; i++) {
574 + unsigned int certLen = predictedCertChain[i]->derCert.len;
575 + unsigned char certLenArray[3] = {
576 + certLen >> 16,
577 + certLen >> 8,
578 + certLen
579 + };
580 + FNV1A64_Update(&certChainHash, certLenArray, 3);
581 + FNV1A64_Update(&certChainHash,
582 + predictedCertChain[i]->derCert.data, certLen);
583 + }
584 + FNV1A64_Final(&certChainHash);
585 + rv = ssl3_AppendHandshake(ss, &certChainHash, 8);
586 + if (rv != SECSuccess)
587 + return -1;
588 + for (i = 0; i < 8; i++) {
589 + ss->ssl3.certChainDigest[i] = digestPtr[i];
590 + }
591 + }
592 +
593 + } else if (maxBytes < extension_length) {
594 + PORT_Assert(0);
595 + return 0;
596 + }
597 + ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
598 + ssl_cached_info_xtn;
599 + return extension_length;
600 +}
601 +
602 +SECStatus
603 +ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
604 + SECItem *data)
605 +{
606 + SECStatus rv;
607 + unsigned char *cached_info = data->data;
608 + unsigned int remaining_len;
609 +
610 + /* Ignore the extension if it isn't enabled. */
611 + if (!ss->opt.enableCachedInfo)
612 + return SECSuccess;
613 +
614 + if (data->len < 2)
615 + return SECFailure;
616 + remaining_len = (cached_info[0] << 8) | cached_info[1];
617 + if (remaining_len > 2048 || remaining_len != data->len - 2)
618 + return SECFailure;
619 + cached_info += 2;
620 +
621 + /* Handle reconnaissance case. */
622 + if (remaining_len == 0) {
623 + /* The client supports information caching, but provides no information
624 + * about what information types it supports */
625 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
626 + rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
627 + ssl3_ServerSendCachedInfoXtn);
628 + return rv;
629 + }
630 +
631 + /* Iterate over the CachedObjects and pick the first item of type
632 + * certificate_chain, while ignoring everything else. */
633 + while (remaining_len >= 2) {
634 + unsigned char cached_object_type = *cached_info++;
635 + unsigned int cached_object_length = *cached_info++;
636 + remaining_len -= 2;
637 + if (remaining_len < cached_object_length)
638 + return SECFailure;
639 + if (cached_object_length != 8) /* The digest must be present. */
640 + return SECFailure;
641 + if (cached_object_type == cached_info_certificate_chain &&
642 + !ss->ssl3.cachedInfoCertChainDigestReceived) {
643 + ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE;
644 + memcpy(ss->ssl3.certChainDigest, cached_info, 8);
645 + }
646 + remaining_len -= cached_object_length;
647 + cached_info += cached_object_length;
648 + }
649 +
650 + if (remaining_len != 0)
651 + return SECFailure;
652 +
653 + if (ss->ssl3.cachedInfoCertChainDigestReceived) {
654 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
655 + rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
656 + ssl3_ServerSendCachedInfoXtn);
657 + return SECSuccess;
658 + }
659 +
660 + return SECSuccess;
661 +}
662 +
663 +/* ssl3_ServerSendCachedInfoXtn builds the cached_info extension on the
664 + * server side. */
665 +PRInt32
666 +ssl3_ServerSendCachedInfoXtn(sslSocket * ss, PRBool append,
667 + PRUint32 maxBytes)
668 +{
669 + PRInt32 extension_length = 2 /* extension type */ +
670 + 2 /* extension length */ +
671 + 2 /* cached_info length */ +
672 + 1 /* CachedInformationType */ +
673 + 1 /* hash value length (0) */;
674 + SECStatus rv;
675 +
676 + PORT_Assert(ss->opt.enableCachedInfo);
677 +
678 + if (append && maxBytes >= extension_length) {
679 + /* ExtensionType */
680 + rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2);
681 + if (rv != SECSuccess)
682 + return -1;
683 + /* Extension Length */
684 + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
685 + if (rv != SECSuccess)
686 + return -1;
687 + /* Cached Information Length */
688 + rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
689 + if (rv != SECSuccess)
690 + return -1;
691 + /* Cached Information Type */
692 + rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1);
693 + if (rv != SECSuccess)
694 + return -1;
695 + /* hash length */
696 + rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
697 + if (rv != SECSuccess)
698 + return -1;
699 + } else if (maxBytes < extension_length) {
700 + PORT_Assert(0);
701 + return 0;
702 + }
703 +
704 + return extension_length;
705 +}
706 +
707 +SECStatus
708 +ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
709 + SECItem *data)
710 +{
711 + unsigned char * cached_info = data->data;
712 + unsigned int remaining_cached_info_length;
713 + PRBool has_correct_cert_chain = PR_FALSE;
714 +
715 + /* If we didn't request this extension, then the server may not echo it. */
716 + if (!ss->opt.enableCachedInfo)
717 + return SECFailure;
718 +
719 + if (data->len == 0) {
720 + /* The server supports information caching, but provides no information
721 + * about what information types it supports */
722 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
723 + return SECSuccess;
724 + }
725 +
726 + if (data->len < 2)
727 + return SECFailure;
728 + remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1];
729 + if (remaining_cached_info_length != data->len - 2)
730 + return SECFailure;
731 + cached_info += 2;
732 + while (remaining_cached_info_length >= 2) {
733 + /* The server supports only those CachedInformationType types that are
734 + * identified by a present CachedObject */
735 + unsigned char cached_object_type;
736 + unsigned int cached_object_length;
737 + unsigned char cached_object_digest[8];
738 + cached_object_type = *cached_info++;
739 + cached_object_length = *cached_info++;
740 + remaining_cached_info_length -= 2;
741 + if (remaining_cached_info_length < cached_object_length)
742 + return SECFailure;
743 + if (cached_object_length != 0 && cached_object_length != 8)
744 + return SECFailure;
745 + remaining_cached_info_length -= cached_object_length;
746 + if (cached_object_type == cached_info_certificate_chain) {
747 + if (cached_object_length == 0)
748 + has_correct_cert_chain = PR_TRUE;
749 + else { /* Hashes must match */
750 + int i;
751 + for (i = 0; i < 8; i++)
752 + cached_object_digest[i] = *cached_info++;
753 + if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8))
754 + has_correct_cert_chain = PR_TRUE;
755 + }
756 + }
757 + }
758 +
759 + if (remaining_cached_info_length != 0)
760 + return SECFailure;
761 +
762 + if (has_correct_cert_chain) {
763 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
764 + return SECSuccess;
765 + }
766 +
767 + return SECFailure;
768 +}
769 +
770 /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
771 * client side. See RFC 4366 section 3.6. */
772 PRInt32
773 diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/s sl/sslauth.c
774 index df40f30..fcd15ca 100644
775 --- a/mozilla/security/nss/lib/ssl/sslauth.c
776 +++ b/mozilla/security/nss/lib/ssl/sslauth.c
777 @@ -95,6 +95,46 @@ SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **ce rts,
778 return SECSuccess;
779 }
780
781 +SECStatus
782 +SSL_SetPredictedPeerCertificates(PRFileDesc *fd, CERTCertificate **certs,
783 + unsigned int numCerts)
784 +{
785 + sslSocket *ss;
786 + unsigned int i;
787 +
788 + ss = ssl_FindSocket(fd);
789 + if (!ss) {
790 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedPeerCertificates",
791 + SSL_GETPID(), fd));
792 + return SECFailure;
793 + }
794 +
795 + ss->ssl3.predictedCertChain =
796 + PORT_NewArray(CERTCertificate*, numCerts + 1);
797 + if (!ss->ssl3.predictedCertChain)
798 + return SECFailure; /* error code was set */
799 + for (i = 0; i < numCerts; i++)
800 + ss->ssl3.predictedCertChain[i] = CERT_DupCertificate(certs[i]);
801 + ss->ssl3.predictedCertChain[numCerts] = NULL;
802 +
803 + return SECSuccess;
804 +}
805 +
806 +PRBool
807 +SSL_CertChainDigestReceived(PRFileDesc *fd)
808 +{
809 + sslSocket *ss;
810 +
811 + ss = ssl_FindSocket(fd);
812 + if (!ss) {
813 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_CertChainDigestReceived",
814 + SSL_GETPID(), fd));
815 + return SECFailure;
816 + }
817 +
818 + return ss->ssl3.cachedInfoCertChainDigestReceived;
819 +}
820 +
821 /* NEED LOCKS IN HERE. */
822 CERTCertificate *
823 SSL_LocalCertificate(PRFileDesc *fd)
824 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s sl/sslimpl.h
825 index 8e2bd14..f1e9a3e 100644
826 --- a/mozilla/security/nss/lib/ssl/sslimpl.h
827 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h
828 @@ -340,6 +340,7 @@ typedef struct sslOptionsStr {
829 unsigned int requireSafeNegotiation : 1; /* 22 */
830 unsigned int enableFalseStart : 1; /* 23 */
831 unsigned int enableOCSPStapling : 1; /* 24 */
832 + unsigned int enableCachedInfo : 1; /* 25 */
833 } sslOptions;
834
835 typedef enum { sslHandshakingUndetermined = 0,
836 @@ -754,6 +755,11 @@ struct TLSExtensionDataStr {
837 PRUint32 sniNameArrSize;
838 };
839
840 +typedef enum {
841 + cached_info_certificate_chain = 1,
842 + cached_info_trusted_cas = 2
843 +} TLSCachedInfoType;
844 +
845 /*
846 ** This is the "hs" member of the "ssl3" struct.
847 ** This entire struct is protected by ssl3HandshakeLock
848 @@ -832,6 +838,14 @@ struct ssl3StateStr {
849 CERTCertificateList *clientCertChain; /* used by client */
850 PRBool sendEmptyCert; /* used by client */
851
852 + /* TLS Cached Info Extension */
853 + CERTCertificate ** predictedCertChain;
854 + /* An array terminated with a NULL. */
855 + PRUint8 certChainDigest[8];
856 + /* Used in cached info extension. Stored in network
857 + * byte order. */
858 + PRBool cachedInfoCertChainDigestReceived;
859 +
860 int policy;
861 /* This says what cipher suites we can do, and should
862 * be either SSL_ALLOWED or SSL_RESTRICTED
863 @@ -839,7 +853,10 @@ struct ssl3StateStr {
864 PRArenaPool * peerCertArena;
865 /* These are used to keep track of the peer CA */
866 void * peerCertChain;
867 - /* chain while we are trying to validate it. */
868 + /* Chain while we are trying to validate it. This
869 + * does not include the leaf cert. It is actually a
870 + * linked list of ssl3CertNode structs.
871 + */
872 CERTDistNames * ca_list;
873 /* used by server. trusted CAs for this socket. */
874 PRBool initialized;
875 @@ -1524,6 +1541,10 @@ extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSoc ket *ss,
876 PRUint16 ex_type, SECItem *data);
877 extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
878 PRUint16 ex_type, SECItem *data);
879 +extern SECStatus ssl3_ServerHandleCachedInfoXtn(sslSocket *ss,
880 + PRUint16 ex_type, SECItem *data);
881 +extern SECStatus ssl3_ClientHandleCachedInfoXtn(sslSocket *ss,
882 + PRUint16 ex_type, SECItem *data);
883 extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
884 PRUint16 ex_type, SECItem *data);
885 extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
886 @@ -1545,6 +1566,10 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append,
887 */
888 extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append,
889 PRUint32 maxBytes);
890 +extern PRInt32 ssl3_ClientSendCachedInfoXtn(sslSocket *ss, PRBool append,
891 + PRUint32 maxBytes);
892 +extern PRInt32 ssl3_ServerSendCachedInfoXtn(sslSocket *ss, PRBool append,
893 + PRUint32 maxBytes);
894
895 /* Assigns new cert, cert chain and keys to ss->serverCerts
896 * struct. If certChain is NULL, tries to find one. Aborts if
897 @@ -1648,6 +1673,12 @@ SECStatus SSL_DisableDefaultExportCipherSuites(void);
898 SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd);
899 PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite);
900
901 +/********************** FNV hash *********************/
902 +
903 +void FNV1A64_Init(PRUint64 *digest);
904 +void FNV1A64_Update(PRUint64 *digest, const unsigned char *data,
905 + unsigned int length);
906 +void FNV1A64_Final(PRUint64 *digest);
907
908 #ifdef TRACE
909 #define SSL_TRACE(msg) ssl_Trace msg
910 diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/s sl/sslsock.c
911 index 4c4df3f..3d89d86 100644
912 --- a/mozilla/security/nss/lib/ssl/sslsock.c
913 +++ b/mozilla/security/nss/lib/ssl/sslsock.c
914 @@ -186,6 +186,7 @@ static sslOptions ssl_defaults = {
915 PR_FALSE, /* requireSafeNegotiation */
916 PR_FALSE, /* enableFalseStart */
917 PR_FALSE, /* enableOCSPStapling */
918 + PR_FALSE, /* enableCachedInfo */
919 };
920
921 sslSessionIDLookupFunc ssl_sid_lookup;
922 @@ -743,6 +744,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
923 ss->opt.enableOCSPStapling = on;
924 break;
925
926 + case SSL_ENABLE_CACHED_INFO:
927 + ss->opt.enableCachedInfo = on;
928 + break;
929 +
930 default:
931 PORT_SetError(SEC_ERROR_INVALID_ARGS);
932 rv = SECFailure;
933 @@ -808,6 +813,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
934 on = ss->opt.requireSafeNegotiation; break;
935 case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break;
936 case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
937 + case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break;
938
939 default:
940 PORT_SetError(SEC_ERROR_INVALID_ARGS);
941 @@ -862,6 +868,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
942 case SSL_ENABLE_OCSP_STAPLING:
943 on = ssl_defaults.enableOCSPStapling;
944 break;
945 + case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break;
946
947 default:
948 PORT_SetError(SEC_ERROR_INVALID_ARGS);
949 @@ -1013,6 +1020,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
950 ssl_defaults.enableOCSPStapling = on;
951 break;
952
953 + case SSL_ENABLE_CACHED_INFO:
954 + ssl_defaults.enableCachedInfo = on;
955 + break;
956 +
957 default:
958 PORT_SetError(SEC_ERROR_INVALID_ARGS);
959 return SECFailure;
960 diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/ sslt.h
961 index 917c093..bca7496 100644
962 --- a/mozilla/security/nss/lib/ssl/sslt.h
963 +++ b/mozilla/security/nss/lib/ssl/sslt.h
964 @@ -205,9 +205,10 @@ typedef enum {
965 #endif
966 ssl_session_ticket_xtn = 35,
967 ssl_next_proto_neg_xtn = 13172,
968 + ssl_cached_info_xtn = 13173,
969 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
970 } SSLExtensionType;
971
972 -#define SSL_MAX_EXTENSIONS 7
973 +#define SSL_MAX_EXTENSIONS 8
974
975 #endif /* __sslt_h_ */
OLDNEW
« no previous file with comments | « net/third_party/nss/patches/cachecerts.patch ('k') | net/third_party/nss/patches/cbcrandomiv.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698