| OLD | NEW |
| (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_ */ | |
| OLD | NEW |