diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-03 15:02:22 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-03 15:02:22 +0000 |
commit | 1b5bcd397cf7e5bfb947be72f06138a2ee4be699 (patch) | |
tree | 6008c21d4c741cccb8a6bc2cd0c3a26414ddfc64 | |
parent | 8cf99c80877e6030417a3c2e0fa7cb46cfcef3d3 (diff) | |
download | chromium_src-1b5bcd397cf7e5bfb947be72f06138a2ee4be699.zip chromium_src-1b5bcd397cf7e5bfb947be72f06138a2ee4be699.tar.gz chromium_src-1b5bcd397cf7e5bfb947be72f06138a2ee4be699.tar.bz2 |
Update net/third_party/nss to NSS 3.13.3.
The following patches have been upstreamed:
- net/third_party/nss/patches/handshakeshortwrite.patch
- net/third_party/nss/patches/cbcrandomiv.patch
- net/third_party/nss/patches/nextproto.patch
- portions of patches/cachecerts.patch that add certificates to
ss->ssl3.peerCertChain in the right order.
- portions of net/third_party/nss/patches/clientauth.patch that
fix NSS bug 616757.
I omitted the net/third_party/nss/patches/cachedinfo.patch because
Chrome isn't using the TLS cached info extension and I wanted to
maintain fewer patches. We can add it back later.
R=rsleevi@chromium.org,agl@chromium.org
BUG=116617
TEST=Unit tests should pass. Manual tests of SSL client auth and
origin-bound certs.
Review URL: http://codereview.chromium.org/9558017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124862 0039d316-1c4b-4281-b951-d872f2087c98
45 files changed, 2281 insertions, 3932 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index aaa8a17..7f9bb4c 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -261,12 +261,13 @@ class PeerCertificateChain { explicit PeerCertificateChain(PRFileDesc* nss_fd) : num_certs_(0), certs_(NULL) { - SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_); + SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_, 0); DCHECK_EQ(rv, SECSuccess); certs_ = new CERTCertificate*[num_certs_]; const unsigned expected_num_certs = num_certs_; - rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_); + rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_, + expected_num_certs); DCHECK_EQ(rv, SECSuccess); DCHECK_EQ(num_certs_, expected_num_certs); } @@ -913,12 +914,12 @@ int SSLClientSocketNSS::InitializeSSLOptions() { LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE"); #endif -#ifdef SSL_ENABLE_FALSE_START - rv = SSL_OptionSet( - nss_fd_, SSL_ENABLE_FALSE_START, + PRBool false_start_enabled = ssl_config_.false_start_enabled && !SSLConfigService::IsKnownFalseStartIncompatibleServer( - host_and_port_.host())); + host_and_port_.host()); +#ifdef SSL_ENABLE_FALSE_START + rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, false_start_enabled); if (rv != SECSuccess) LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); #endif @@ -937,13 +938,17 @@ int SSLClientSocketNSS::InitializeSSLOptions() { } #endif // SSL_ENABLE_RENEGOTIATION -#ifdef SSL_NEXT_PROTO_NEGOTIATED if (!ssl_config_.next_protos.empty()) { rv = SSL_SetNextProtoCallback( nss_fd_, SSLClientSocketNSS::NextProtoCallback, this); if (rv != SECSuccess) LogFailedNSSFunction(net_log_, "SSL_SetNextProtoCallback", ""); } + +#ifdef SSL_CBC_RANDOM_IV + rv = SSL_OptionSet(nss_fd_, SSL_CBC_RANDOM_IV, false_start_enabled); + if (rv != SECSuccess) + LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_CBC_RANDOM_IV"); #endif #ifdef SSL_ENABLE_OCSP_STAPLING @@ -1370,7 +1375,6 @@ bool SSLClientSocketNSS::LoadSSLHostInfo() { if (state.certs.empty()) return true; - SECStatus rv; const std::vector<std::string>& certs_in = state.certs; scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]); @@ -1389,11 +1393,16 @@ bool SSLClientSocketNSS::LoadSSLHostInfo() { } } + SECStatus rv; +#ifdef SSL_ENABLE_CACHED_INFO rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size()); - DestroyCertificates(&certs[0], certs_in.size()); DCHECK_EQ(SECSuccess, rv); +#else + rv = SECFailure; // Not implemented. +#endif + DestroyCertificates(&certs[0], certs_in.size()); - return true; + return rv == SECSuccess; } int SSLClientSocketNSS::DoLoadSSLHostInfo() { @@ -2637,7 +2646,8 @@ SSLClientSocketNSS::NextProtoCallback(void* arg, const unsigned char* protos, unsigned int protos_len, unsigned char* proto_out, - unsigned int* proto_out_len) { + unsigned int* proto_out_len, + unsigned int proto_max_len) { SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); // For each protocol in server preference, see if we support it. @@ -2676,6 +2686,10 @@ SSLClientSocketNSS::NextProtoCallback(void* arg, that->next_proto_ = that->ssl_config_.next_protos[0]; } + if (that->next_proto_.size() > proto_max_len) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + return SECFailure; + } memcpy(proto_out, that->next_proto_.data(), that->next_proto_.size()); *proto_out_len = that->next_proto_.size(); return SECSuccess; diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 3ce5b78..2dc72c5 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -200,7 +200,8 @@ class SSLClientSocketNSS : public SSLClientSocket { const unsigned char* protos, unsigned int protos_len, unsigned char* proto_out, - unsigned int* proto_out_len); + unsigned int* proto_out_len, + unsigned int proto_max_len); // The following methods are for debugging bug 65948. Will remove this code // after fixing bug 65948. diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index e13d950..80ffb89 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium @@ -1,17 +1,15 @@ Name: Network Security Services (NSS) URL: http://www.mozilla.org/projects/security/pki/nss/ +Version: 3.13.3 +Security Critical: Yes This directory includes a copy of NSS's libssl from the CVS repo at: :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot -The snapshot was updated to the CVS tag: NSS_3_12_9_RTM +The snapshot was updated to the CVS tag: NSS_3_13_3_RTM Patches: - * Next protocol negotiation support. - patches/nextproto.patch - http://codereview.chromium.org/415005 - * Commenting out a couple of functions because they need NSS symbols which may not exist in the system NSS library. patches/versionskew.patch @@ -22,13 +20,13 @@ Patches: https://bugzilla.mozilla.org/show_bug.cgi?id=549042 * Cache the peer's intermediate CA certificates in session ID, so that - they're available when we resume a session. Add certificates to - ss->ssl3.peerCertChain in the right order. + they're available when we resume a session. patches/cachecerts.patch - https://bugzilla.mozilla.org/show_bug.cgi?id=606049 + https://bugzilla.mozilla.org/show_bug.cgi?id=731478 * Add the SSL_PeerCertificateChain function patches/peercertchain.patch + https://bugzilla.mozilla.org/show_bug.cgi?id=731485 * Add OCSP stapling support patches/ocspstapling.patch @@ -37,25 +35,10 @@ Patches: patches/clientauth.patch ssl/sslplatf.c - * Don't send a client certificate when renegotiating if the peer does not - request one. This only happened if the previous key exchange algorithm - was non-RSA. - patches/clientauth.patch - https://bugzilla.mozilla.org/show_bug.cgi?id=616757 - - * Add support for TLS cached info extension. - patches/cachedinfo.patch - https://bugzilla.mozilla.org/show_bug.cgi?id=665739 - * Add a function to export whether the last handshake on a socket resumed a previous session. patches/didhandshakeresume.patch - - * Start each set of CBC encrypted application data records, resulting from - a single call to ssl3_SendApplicationData, with a one-byte application - data record in order to randomize the IV in a backward compatible manner. - https://bugzilla.mozilla.org/show_bug.cgi?id=665814 - patches/cbcrandomiv.patch + https://bugzilla.mozilla.org/show_bug.cgi?id=731798 * Support origin bound certificates. http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.txt @@ -66,10 +49,6 @@ Patches: https://bugzilla.mozilla.org/show_bug.cgi?id=507359 patches/secret_exporter.patch - * Send saved write data in the SSL socket in SSL_ForceHandshake. - patches/handshakeshortwrite.patch - https://bugzilla.mozilla.org/show_bug.cgi?id=676729 - * Add a function to restart a handshake after a client certificate request. patches/restartclientauth.patch diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh index 0f8454f..a895782 100755 --- a/net/third_party/nss/patches/applypatches.sh +++ b/net/third_party/nss/patches/applypatches.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -9,36 +9,30 @@ # chromium source tree. patches_dir=/Users/wtc/chrome1/src/net/third_party/nss/patches -patch -p6 < $patches_dir/nextproto.patch - patch -p6 < $patches_dir/versionskew.patch patch -p6 < $patches_dir/renegoscsv.patch patch -p6 < $patches_dir/cachecerts.patch -patch -p6 < $patches_dir/peercertchain.patch +patch -p5 < $patches_dir/peercertchain.patch patch -p6 < $patches_dir/ocspstapling.patch patch -p6 < $patches_dir/clientauth.patch -patch -p6 < $patches_dir/cachedinfo.patch - patch -p6 < $patches_dir/didhandshakeresume.patch -patch -p6 < $patches_dir/cbcrandomiv.patch - patch -p6 < $patches_dir/origin_bound_certs.patch patch -p6 < $patches_dir/secret_exporter.patch -patch -p6 < $patches_dir/handshakeshortwrite.patch +patch -p6 < $patches_dir/negotiatedextension.patch -patch -p6 < $patches_dir/restartclientauth.patch +patch -p6 < $patches_dir/getrequestedclientcerttypes.patch -patch -p6 < $patches_dir/negotiatedextension.patch +patch -p5 < $patches_dir/clang-sslcon.patch -patch -p3 < $patches_dir/encryptedclientcerts.patch +patch -p6 < $patches_dir/restartclientauth.patch -patch -p3 < $patches_dir/getrequestedclientcerttypes.patch +patch -p6 < $patches_dir/encryptedclientcerts.patch diff --git a/net/third_party/nss/patches/cachecerts.patch b/net/third_party/nss/patches/cachecerts.patch index 9fe07ca..f7ce5fb 100644 --- a/net/third_party/nss/patches/cachecerts.patch +++ b/net/third_party/nss/patches/cachecerts.patch @@ -82,47 +82,14 @@ index 455a532..9830e65 100644 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete * ssl3 Certificate message. * Caller must hold Handshake and RecvBuf locks. -@@ -7769,6 +7810,7 @@ static SECStatus - ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - { - ssl3CertNode * c; -+ ssl3CertNode * lastCert = NULL; - ssl3CertNode * certs = NULL; - PRArenaPool * arena = NULL; - CERTCertificate *cert; -@@ -7896,8 +7938,13 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - if (c->cert->trust) - trusted = PR_TRUE; - -- c->next = certs; -- certs = c; -+ c->next = NULL; -+ if (lastCert) { -+ lastCert->next = c; -+ } else { -+ certs = c; -+ } -+ lastCert = c; - } - - if (remaining != 0) @@ -7947,6 +7994,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); -+ ssl3_CopyPeerCertsToSID(certs, ss->sec.ci.sid); ++ ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); if (!ss->sec.isServer) { /* set the server authentication and key exchange types and sizes -@@ -8118,6 +8166,8 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss) - if (ss->handshake != NULL) { - ss->handshake = ssl_GatherRecord1stHandshake; - ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); -+ ssl3_CopyPeerCertsToSID((ssl3CertNode *)ss->ssl3.peerCertChain, -+ ss->sec.ci.sid); - - ssl_GetRecvBufLock(ss); - if (ss->ssl3.hs.msgState.buf != NULL) { diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h index d1c1181..48d6d83 100644 --- a/mozilla/security/nss/lib/ssl/sslimpl.h diff --git a/net/third_party/nss/patches/cachedinfo.patch b/net/third_party/nss/patches/cachedinfo.patch deleted file mode 100644 index 97ffb84..0000000 --- a/net/third_party/nss/patches/cachedinfo.patch +++ /dev/null @@ -1,975 +0,0 @@ -From 1c425d479c495d266c23876887198a54e82e7078 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:22:24 -0400 -Subject: [PATCH] cachedinfo.patch - ---- - mozilla/security/nss/lib/ssl/fnv1a64.c | 72 +++++++++ - mozilla/security/nss/lib/ssl/manifest.mn | 1 + - mozilla/security/nss/lib/ssl/ssl.h | 26 +++ - mozilla/security/nss/lib/ssl/ssl3con.c | 221 +++++++++++++++++++------ - mozilla/security/nss/lib/ssl/ssl3ext.c | 258 ++++++++++++++++++++++++++++++ - mozilla/security/nss/lib/ssl/sslauth.c | 40 +++++ - mozilla/security/nss/lib/ssl/sslimpl.h | 33 ++++- - mozilla/security/nss/lib/ssl/sslsock.c | 11 ++ - mozilla/security/nss/lib/ssl/sslt.h | 3 +- - 9 files changed, 611 insertions(+), 54 deletions(-) - create mode 100644 mozilla/security/nss/lib/ssl/fnv1a64.c - -diff --git a/mozilla/security/nss/lib/ssl/fnv1a64.c b/mozilla/security/nss/lib/ssl/fnv1a64.c -new file mode 100644 -index 0000000..c7c4b08 ---- /dev/null -+++ b/mozilla/security/nss/lib/ssl/fnv1a64.c -@@ -0,0 +1,72 @@ -+/* -+ * FNV1A64 Hash -+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param -+ * -+ * ***** BEGIN LICENSE BLOCK ***** -+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 -+ * -+ * The contents of this file are subject to the Mozilla Public License Version -+ * 1.1 (the "License"); you may not use this file except in compliance with -+ * the License. You may obtain a copy of the License at -+ * http://www.mozilla.org/MPL/ -+ * -+ * Software distributed under the License is distributed on an "AS IS" basis, -+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -+ * for the specific language governing rights and limitations under the -+ * License. -+ * -+ * The Original Code is the Netscape security libraries. -+ * -+ * The Initial Developer of the Original Code is -+ * Netscape Communications Corporation. -+ * Portions created by the Initial Developer are Copyright (C) 1994-2000 -+ * the Initial Developer. All Rights Reserved. -+ * -+ * Contributor(s): -+ * Adam Langley, Google Inc. -+ * -+ * Alternatively, the contents of this file may be used under the terms of -+ * either the GNU General Public License Version 2 or later (the "GPL"), or -+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -+ * in which case the provisions of the GPL or the LGPL are applicable instead -+ * of those above. If you wish to allow use of your version of this file only -+ * under the terms of either the GPL or the LGPL, and not to allow others to -+ * use your version of this file under the terms of the MPL, indicate your -+ * decision by deleting the provisions above and replace them with the notice -+ * and other provisions required by the GPL or the LGPL. If you do not delete -+ * the provisions above, a recipient may use your version of this file under -+ * the terms of any one of the MPL, the GPL or the LGPL. -+ * -+ * ***** END LICENSE BLOCK ***** */ -+ -+/* $Id: fnv1a64.c,v 1.0 2010/08/09 13:00:00 agl%google.com Exp $ */ -+ -+#include "prtypes.h" -+#include "prnetdb.h" -+ -+/* Older versions of Visual C++ don't support the 'ull' suffix. */ -+#ifdef _MSC_VER -+static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ui64; -+static const PRUint64 FNV1A64_PRIME = 1099511628211ui64; -+#else -+static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ull; -+static const PRUint64 FNV1A64_PRIME = 1099511628211ull; -+#endif -+ -+void FNV1A64_Init(PRUint64* digest) { -+ *digest = FNV1A64_OFFSET_BASIS; -+} -+ -+void FNV1A64_Update(PRUint64* digest, const unsigned char *data, -+ unsigned int length) { -+ unsigned int i; -+ -+ for (i = 0; i < length; i++) { -+ *digest ^= data[i]; -+ *digest *= FNV1A64_PRIME; -+ } -+} -+ -+void FNV1A64_Final(PRUint64 *digest) { -+ *digest = PR_htonll(*digest); -+} -diff --git a/mozilla/security/nss/lib/ssl/manifest.mn b/mozilla/security/nss/lib/ssl/manifest.mn -index 8451229..f09d770 100644 ---- a/mozilla/security/nss/lib/ssl/manifest.mn -+++ b/mozilla/security/nss/lib/ssl/manifest.mn -@@ -51,6 +51,7 @@ MAPFILE = $(OBJDIR)/ssl.def - - CSRCS = \ - derive.c \ -+ fnv1a64.c \ - prelib.c \ - ssl3con.c \ - ssl3gthr.c \ -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index 221fe2d..3a22b45 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -140,6 +140,8 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); - /* bits. The advantage of False Start is that it saves a round trip for */ - /* client-speaks-first protocols when performing a full handshake. */ - #define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */ -+#define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */ -+ /* extension, off by default. */ - - #ifdef SSL_DEPRECATED_FUNCTION - /* Old deprecated function names */ -@@ -256,6 +258,12 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher, - #define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */ - - /* -+** Returns true if the server's Certificate message contained a hash of the -+** certificate chain due to the TLS cached info extension. -+*/ -+SSL_IMPORT PRBool SSL_CertChainDigestReceived(PRFileDesc *fd); -+ -+/* - ** Return the certificate for our SSL peer. If the client calls this - ** it will always return the server's certificate. If the server calls - ** this, it may return NULL if client authentication is not enabled or -@@ -275,6 +283,13 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd); - SSL_IMPORT SECStatus SSL_PeerCertificateChain( - PRFileDesc *fd, CERTCertificate **certs, unsigned int *certs_size); - -+/* -+** Set the predicted cert chain to be used in the cached info extension. -+*/ -+SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(PRFileDesc *fd, -+ CERTCertificate **certs, -+ unsigned int len); -+ - /* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by - * the TLS server. The resulting data is copied to |out_data|. On entry, |*len| - * must contain the size of |out_data|. On exit, |*len| will contain the size -@@ -405,6 +420,17 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, - void *arg); - - /* -+ ** Set the predicted chain of certificates for the peer. This is used for the -+ ** TLS Cached Info extension. Note that the SSL_ENABLE_CACHED_INFO option must -+ ** be set for this to occur. -+ ** -+ ** This function takes a reference to each of the given certificates. -+ */ -+ SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates( -+ PRFileDesc *fd, CERTCertificate **certs, -+ unsigned int numCerts); -+ -+/* - ** Configure SSL socket for running a secure server. Needs the - ** certificate for the server and the servers private key. The arguments - ** are copied. -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index ca2793f..dd99962 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -5145,7 +5145,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - ssl3_CopyPeerCertsFromSID(ss, sid); - } - -- - /* NULL value for PMS signifies re-use of the old MS */ - rv = ssl3_InitPendingCipherSpec(ss, NULL); - if (rv != SECSuccess) { -@@ -7715,6 +7714,69 @@ ssl3_SendCertificate(sslSocket *ss) - } - } - -+ if (ss->ssl3.cachedInfoCertChainDigestReceived) { -+ /* Compute hash. */ -+ PRUint64 certChainHash; -+ int i; -+ FNV1A64_Init(&certChainHash); -+ for (i = 0; i < certChain->len; i++) { -+ unsigned int certLen = certChain->certs[i].len; -+ unsigned char certLenArray[3] = { -+ certLen >> 16, -+ certLen >> 8, -+ certLen -+ }; -+ FNV1A64_Update(&certChainHash, certLenArray, sizeof(certLenArray)); -+ FNV1A64_Update(&certChainHash, certChain->certs[i].data, certLen); -+ } -+ FNV1A64_Final(&certChainHash); -+ -+ /* Both |&certChainHash| and |ss->ssl3.certChainDigest| should be in -+ * network byte order since both are computed with the FNV1A64 hash, -+ * which calls the function htonll. -+ */ -+ if (memcmp(&certChainHash, ss->ssl3.certChainDigest, -+ sizeof(certChainHash)) == 0) { -+ /* The client correctly predicted the certificate chain. */ -+ -+ /* Handshake type: certificate. */ -+ rv = ssl3_AppendHandshakeNumber(ss, certificate, 1); -+ if (rv != SECSuccess) { -+ return rv; /* err set by AppendHandshake. */ -+ } -+ /* Handshake message length. */ -+ rv = ssl3_AppendHandshakeNumber(ss, 15, 3); -+ if (rv != SECSuccess) { -+ return rv; /* err set by AppendHandshake. */ -+ } -+ /* CertChainLen(3) + ASN.1CertLen(3) + DigestLen(1) + Digest(8) */ -+ rv = ssl3_AppendHandshakeNumber(ss, 12, 3); -+ if (rv != SECSuccess) { -+ return rv; /* err set by AppendHandshake. */ -+ } -+ /* ASN.1CertLen(3) + DigestLen(1) + Digest(8) */ -+ rv = ssl3_AppendHandshakeNumber(ss, 9, 3); -+ if (rv != SECSuccess) { -+ return rv; /* err set by AppendHandshake. */ -+ } -+ /* Digest Length Byte */ -+ rv = ssl3_AppendHandshakeNumber(ss, sizeof(certChainHash), 1); -+ if (rv != SECSuccess) { -+ return rv; /* err set by AppendHandshake. */ -+ } -+ /* Digest */ -+ rv = ssl3_AppendHandshake(ss, &certChainHash, -+ sizeof(certChainHash)); -+ if (rv != SECSuccess) { -+ return rv; /* err set by AppendHandshake. */ -+ } -+ -+ return SECSuccess; -+ } -+ } -+ -+ /* Send the entire certificate as usual. */ -+ - rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ -@@ -7869,7 +7931,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - PRInt32 size; - SECStatus rv; - PRBool isServer = (PRBool)(!!ss->sec.isServer); -- PRBool trusted = PR_FALSE; - PRBool isTLS; - SSL3AlertDescription desc = bad_certificate; - int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; -@@ -7929,35 +7990,46 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - goto loser; /* don't send alerts on memory errors */ - } - -- /* First get the peer cert. */ -- remaining -= 3; -- if (remaining < 0) -- goto decode_loser; -+ if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) { -+ /* We are dealing with a certificate_chain digest */ -+ int i; - -- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); -- if (size <= 0) -- goto loser; /* fatal alert already sent by ConsumeHandshake. */ -+ ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE; - -- if (remaining < size) -- goto decode_loser; -+ /* Make sure the digests match. */ -+ if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) { -+ desc = handshake_failure; -+ goto alert_loser; -+ } - -- certItem.data = b; -- certItem.len = size; -- b += size; -- length -= size; -- remaining -= size; -+ /* First get the peer cert. */ -+ if (ss->ssl3.predictedCertChain[0] == NULL) { -+ desc = handshake_failure; -+ goto alert_loser; -+ } -+ ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); - -- ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, -- PR_FALSE, PR_TRUE); -- if (ss->sec.peerCert == NULL) { -- /* We should report an alert if the cert was bad, but not if the -- * problem was just some local problem, like memory error. -- */ -- goto ambiguous_err; -- } -+ /* Now get all of the CA certs. */ -+ ss->ssl3.peerCertChain = NULL; -+ for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) { -+ c = PORT_ArenaNew(arena, ssl3CertNode); -+ if (c == NULL) { -+ goto loser; /* don't send alerts on memory errors */ -+ } -+ c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]); -+ c->next = NULL; -+ if (lastCert) { -+ lastCert->next = c; -+ } else { -+ ss->ssl3.peerCertChain = c; -+ } -+ lastCert = c; -+ } -+ } else { -+ /* We are dealing with a regular certificate message */ -+ ss->ssl3.cachedInfoCertChainDigestReceived = PR_FALSE; - -- /* Now get all of the CA certs. */ -- while (remaining > 0) { -+ /* First get the peer cert. */ - remaining -= 3; - if (remaining < 0) - goto decode_loser; -@@ -7971,35 +8043,63 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - - certItem.data = b; - certItem.len = size; -- b += size; -+ b += size; - length -= size; - remaining -= size; - -- c = PORT_ArenaNew(arena, ssl3CertNode); -- if (c == NULL) { -- goto loser; /* don't send alerts on memory errors */ -- } -- -- c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, -- PR_FALSE, PR_TRUE); -- if (c->cert == NULL) { -+ ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, -+ NULL, PR_FALSE, PR_TRUE); -+ if (ss->sec.peerCert == NULL) { -+ /* We should report an alert if the cert was bad, but not if the -+ * problem was just some local problem, like memory error. -+ */ - goto ambiguous_err; - } - -- if (c->cert->trust) -- trusted = PR_TRUE; -+ /* Now get all of the CA certs. */ -+ while (remaining > 0) { -+ remaining -= 3; -+ if (remaining < 0) -+ goto decode_loser; - -- c->next = NULL; -- if (lastCert) { -- lastCert->next = c; -- } else { -- certs = c; -+ size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); -+ if (size <= 0) -+ goto loser; /* fatal alert already sent by ConsumeHandshake. */ -+ -+ if (remaining < size) -+ goto decode_loser; -+ -+ certItem.data = b; -+ certItem.len = size; -+ b += size; -+ length -= size; -+ remaining -= size; -+ -+ c = PORT_ArenaNew(arena, ssl3CertNode); -+ if (c == NULL) { -+ goto loser; /* don't send alerts on memory errors */ -+ } -+ -+ c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, -+ PR_FALSE, PR_TRUE); -+ if (c->cert == NULL) { -+ goto ambiguous_err; -+ } -+ -+ c->next = NULL; -+ if (lastCert) { -+ lastCert->next = c; -+ } else { -+ certs = c; -+ } -+ lastCert = c; - } -- lastCert = c; -- } - -- if (remaining != 0) -- goto decode_loser; -+ if (remaining != 0) -+ goto decode_loser; -+ -+ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; -+ } - - SECKEY_UpdateCertPQG(ss->sec.peerCert); - -@@ -8019,8 +8119,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - /* someone will handle this connection asynchronously*/ - SSL_DBG(("%d: SSL3[%d]: go to async cert handler", - SSL_GETPID(), ss->fd)); -- ss->ssl3.peerCertChain = certs; -- certs = NULL; - ssl_SetAlwaysBlock(ss); - goto cert_block; - } -@@ -8045,7 +8143,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - } - - ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); -- ssl3_CopyPeerCertsToSID(certs, ss->sec.ci.sid); -+ ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); - - if (!ss->sec.isServer) { - /* set the server authentication and key exchange types and sizes -@@ -8090,8 +8188,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - } - } - -- ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; -- - cert_block: - if (ss->sec.isServer) { - ss->ssl3.hs.ws = wait_client_key; -@@ -8161,7 +8257,10 @@ alert_loser: - (void)SSL3_SendAlert(ss, alert_fatal, desc); - - loser: -- ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; -+ if (ss->ssl3.peerCertChain == NULL) { -+ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; -+ } -+ PORT_Assert(certs == NULL); - ssl3_CleanupPeerCerts(ss); - - if (ss->sec.peerCert != NULL) { -@@ -9647,6 +9746,21 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) - return rv; - } - -+static void -+ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) { -+ unsigned int i; -+ -+ if (!ss->ssl3.predictedCertChain) -+ return; -+ -+ for (i = 0; ss->ssl3.predictedCertChain[i]; i++) { -+ CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]); -+ } -+ -+ PORT_Free(ss->ssl3.predictedCertChain); -+ ss->ssl3.predictedCertChain = NULL; -+} -+ - /* Called from ssl_DestroySocketContents() in sslsock.c */ - void - ssl3_DestroySSL3Info(sslSocket *ss) -@@ -9666,6 +9780,9 @@ ssl3_DestroySSL3Info(sslSocket *ss) - ss->ssl3.clientCertChain = NULL; - } - -+ if (ss->ssl3.predictedCertChain != NULL) -+ ssl3_CleanupPredictedPeerCertificates(ss); -+ - /* clean up handshake */ - if (ss->opt.bypassPKCS11) { - SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); -diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c -index 4e3d9cc..17898fb 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3ext.c -+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c -@@ -236,6 +236,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { - { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, -+ { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn }, - { -1, NULL } - }; - -@@ -247,6 +248,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { - { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, -+ { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn }, - { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, - { -1, NULL } - }; -@@ -272,6 +274,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { - #endif - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, -+ { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn }, - { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } - /* any extra entries will appear as { 0, NULL } */ - }; -@@ -676,6 +679,261 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, - return SECSuccess; - } - -+/* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the -+ * client side. */ -+PRInt32 -+ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append, -+ PRUint32 maxBytes) -+{ -+ PRInt32 extension_length; -+ PRBool send_empty; -+ CERTCertificate ** predictedCertChain; -+ -+ if (!ss->opt.enableCachedInfo) -+ return 0; -+ -+ predictedCertChain = ss->ssl3.predictedCertChain; -+ send_empty = (predictedCertChain == NULL); -+ -+ /* minimum extension: -+ * extension_type (2-bytes) + -+ * length(extension_data) (2-bytes) + -+ * length(cached_info) (2-bytes) + -+ */ -+ extension_length = send_empty ? 6 : 16; -+ -+ if (append && maxBytes >= extension_length) { -+ SECStatus rv; -+ -+ /* ExtensionType */ -+ rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); -+ if (rv != SECSuccess) -+ return -1; -+ /* Extension Length */ -+ rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); -+ if (rv != SECSuccess) -+ return -1; -+ if (send_empty) { -+ /* Cached Information Length */ -+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2); -+ if (rv != SECSuccess) -+ return -1; -+ } else { -+ PRUint64 certChainHash; -+ int i; -+ PRUint8* digestPtr = (PRUint8*) &certChainHash; -+ -+ /* Cached Information Length */ -+ rv = ssl3_AppendHandshakeNumber(ss, 10, 2); -+ if (rv != SECSuccess) -+ return -1; -+ /* Cached Information Type */ -+ rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); -+ if (rv != SECSuccess) -+ return -1; -+ /* hash length */ -+ rv = ssl3_AppendHandshakeNumber(ss, 8, 1); -+ if (rv != SECSuccess) -+ return -1; -+ /* hash */ -+ FNV1A64_Init(&certChainHash); -+ for (i = 0; predictedCertChain[i] != NULL; i++) { -+ unsigned int certLen = predictedCertChain[i]->derCert.len; -+ unsigned char certLenArray[3] = { -+ certLen >> 16, -+ certLen >> 8, -+ certLen -+ }; -+ FNV1A64_Update(&certChainHash, certLenArray, 3); -+ FNV1A64_Update(&certChainHash, -+ predictedCertChain[i]->derCert.data, certLen); -+ } -+ FNV1A64_Final(&certChainHash); -+ rv = ssl3_AppendHandshake(ss, &certChainHash, 8); -+ if (rv != SECSuccess) -+ return -1; -+ for (i = 0; i < 8; i++) { -+ ss->ssl3.certChainDigest[i] = digestPtr[i]; -+ } -+ } -+ -+ } else if (maxBytes < extension_length) { -+ PORT_Assert(0); -+ return 0; -+ } -+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = -+ ssl_cached_info_xtn; -+ return extension_length; -+} -+ -+SECStatus -+ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, -+ SECItem *data) -+{ -+ SECStatus rv; -+ unsigned char *cached_info = data->data; -+ unsigned int remaining_len; -+ -+ /* Ignore the extension if it isn't enabled. */ -+ if (!ss->opt.enableCachedInfo) -+ return SECSuccess; -+ -+ if (data->len < 2) -+ return SECFailure; -+ remaining_len = (cached_info[0] << 8) | cached_info[1]; -+ if (remaining_len > 2048 || remaining_len != data->len - 2) -+ return SECFailure; -+ cached_info += 2; -+ -+ /* Handle reconnaissance case. */ -+ if (remaining_len == 0) { -+ /* The client supports information caching, but provides no information -+ * about what information types it supports */ -+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; -+ rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, -+ ssl3_ServerSendCachedInfoXtn); -+ return rv; -+ } -+ -+ /* Iterate over the CachedObjects and pick the first item of type -+ * certificate_chain, while ignoring everything else. */ -+ while (remaining_len >= 2) { -+ unsigned char cached_object_type = *cached_info++; -+ unsigned int cached_object_length = *cached_info++; -+ remaining_len -= 2; -+ if (remaining_len < cached_object_length) -+ return SECFailure; -+ if (cached_object_length != 8) /* The digest must be present. */ -+ return SECFailure; -+ if (cached_object_type == cached_info_certificate_chain && -+ !ss->ssl3.cachedInfoCertChainDigestReceived) { -+ ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE; -+ memcpy(ss->ssl3.certChainDigest, cached_info, 8); -+ } -+ remaining_len -= cached_object_length; -+ cached_info += cached_object_length; -+ } -+ -+ if (remaining_len != 0) -+ return SECFailure; -+ -+ if (ss->ssl3.cachedInfoCertChainDigestReceived) { -+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; -+ rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, -+ ssl3_ServerSendCachedInfoXtn); -+ return SECSuccess; -+ } -+ -+ return SECSuccess; -+} -+ -+/* ssl3_ServerSendCachedInfoXtn builds the cached_info extension on the -+ * server side. */ -+PRInt32 -+ssl3_ServerSendCachedInfoXtn(sslSocket * ss, PRBool append, -+ PRUint32 maxBytes) -+{ -+ PRInt32 extension_length = 2 /* extension type */ + -+ 2 /* extension length */ + -+ 2 /* cached_info length */ + -+ 1 /* CachedInformationType */ + -+ 1 /* hash value length (0) */; -+ SECStatus rv; -+ -+ PORT_Assert(ss->opt.enableCachedInfo); -+ -+ if (append && maxBytes >= extension_length) { -+ /* ExtensionType */ -+ rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); -+ if (rv != SECSuccess) -+ return -1; -+ /* Extension Length */ -+ rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); -+ if (rv != SECSuccess) -+ return -1; -+ /* Cached Information Length */ -+ rv = ssl3_AppendHandshakeNumber(ss, 2, 2); -+ if (rv != SECSuccess) -+ return -1; -+ /* Cached Information Type */ -+ rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); -+ if (rv != SECSuccess) -+ return -1; -+ /* hash length */ -+ rv = ssl3_AppendHandshakeNumber(ss, 0, 1); -+ if (rv != SECSuccess) -+ return -1; -+ } else if (maxBytes < extension_length) { -+ PORT_Assert(0); -+ return 0; -+ } -+ -+ return extension_length; -+} -+ -+SECStatus -+ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, -+ SECItem *data) -+{ -+ unsigned char * cached_info = data->data; -+ unsigned int remaining_cached_info_length; -+ PRBool has_correct_cert_chain = PR_FALSE; -+ -+ /* If we didn't request this extension, then the server may not echo it. */ -+ if (!ss->opt.enableCachedInfo) -+ return SECFailure; -+ -+ if (data->len == 0) { -+ /* The server supports information caching, but provides no information -+ * about what information types it supports */ -+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; -+ return SECSuccess; -+ } -+ -+ if (data->len < 2) -+ return SECFailure; -+ remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1]; -+ if (remaining_cached_info_length != data->len - 2) -+ return SECFailure; -+ cached_info += 2; -+ while (remaining_cached_info_length >= 2) { -+ /* The server supports only those CachedInformationType types that are -+ * identified by a present CachedObject */ -+ unsigned char cached_object_type; -+ unsigned int cached_object_length; -+ unsigned char cached_object_digest[8]; -+ cached_object_type = *cached_info++; -+ cached_object_length = *cached_info++; -+ remaining_cached_info_length -= 2; -+ if (remaining_cached_info_length < cached_object_length) -+ return SECFailure; -+ if (cached_object_length != 0 && cached_object_length != 8) -+ return SECFailure; -+ remaining_cached_info_length -= cached_object_length; -+ if (cached_object_type == cached_info_certificate_chain) { -+ if (cached_object_length == 0) -+ has_correct_cert_chain = PR_TRUE; -+ else { /* Hashes must match */ -+ int i; -+ for (i = 0; i < 8; i++) -+ cached_object_digest[i] = *cached_info++; -+ if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8)) -+ has_correct_cert_chain = PR_TRUE; -+ } -+ } -+ } -+ -+ if (remaining_cached_info_length != 0) -+ return SECFailure; -+ -+ if (has_correct_cert_chain) { -+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; -+ return SECSuccess; -+ } -+ -+ return SECFailure; -+} -+ - /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the - * client side. See RFC 4366 section 3.6. */ - PRInt32 -diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/ssl/sslauth.c -index df40f30..fcd15ca 100644 ---- a/mozilla/security/nss/lib/ssl/sslauth.c -+++ b/mozilla/security/nss/lib/ssl/sslauth.c -@@ -95,6 +95,46 @@ SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs, - return SECSuccess; - } - -+SECStatus -+SSL_SetPredictedPeerCertificates(PRFileDesc *fd, CERTCertificate **certs, -+ unsigned int numCerts) -+{ -+ sslSocket *ss; -+ unsigned int i; -+ -+ ss = ssl_FindSocket(fd); -+ if (!ss) { -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedPeerCertificates", -+ SSL_GETPID(), fd)); -+ return SECFailure; -+ } -+ -+ ss->ssl3.predictedCertChain = -+ PORT_NewArray(CERTCertificate*, numCerts + 1); -+ if (!ss->ssl3.predictedCertChain) -+ return SECFailure; /* error code was set */ -+ for (i = 0; i < numCerts; i++) -+ ss->ssl3.predictedCertChain[i] = CERT_DupCertificate(certs[i]); -+ ss->ssl3.predictedCertChain[numCerts] = NULL; -+ -+ return SECSuccess; -+} -+ -+PRBool -+SSL_CertChainDigestReceived(PRFileDesc *fd) -+{ -+ sslSocket *ss; -+ -+ ss = ssl_FindSocket(fd); -+ if (!ss) { -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_CertChainDigestReceived", -+ SSL_GETPID(), fd)); -+ return SECFailure; -+ } -+ -+ return ss->ssl3.cachedInfoCertChainDigestReceived; -+} -+ - /* NEED LOCKS IN HERE. */ - CERTCertificate * - SSL_LocalCertificate(PRFileDesc *fd) -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index 8e2bd14..f1e9a3e 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h -@@ -340,6 +340,7 @@ typedef struct sslOptionsStr { - unsigned int requireSafeNegotiation : 1; /* 22 */ - unsigned int enableFalseStart : 1; /* 23 */ - unsigned int enableOCSPStapling : 1; /* 24 */ -+ unsigned int enableCachedInfo : 1; /* 25 */ - } sslOptions; - - typedef enum { sslHandshakingUndetermined = 0, -@@ -754,6 +755,11 @@ struct TLSExtensionDataStr { - PRUint32 sniNameArrSize; - }; - -+typedef enum { -+ cached_info_certificate_chain = 1, -+ cached_info_trusted_cas = 2 -+} TLSCachedInfoType; -+ - /* - ** This is the "hs" member of the "ssl3" struct. - ** This entire struct is protected by ssl3HandshakeLock -@@ -832,6 +838,14 @@ struct ssl3StateStr { - CERTCertificateList *clientCertChain; /* used by client */ - PRBool sendEmptyCert; /* used by client */ - -+ /* TLS Cached Info Extension */ -+ CERTCertificate ** predictedCertChain; -+ /* An array terminated with a NULL. */ -+ PRUint8 certChainDigest[8]; -+ /* Used in cached info extension. Stored in network -+ * byte order. */ -+ PRBool cachedInfoCertChainDigestReceived; -+ - int policy; - /* This says what cipher suites we can do, and should - * be either SSL_ALLOWED or SSL_RESTRICTED -@@ -839,7 +853,10 @@ struct ssl3StateStr { - PRArenaPool * peerCertArena; - /* These are used to keep track of the peer CA */ - void * peerCertChain; -- /* chain while we are trying to validate it. */ -+ /* Chain while we are trying to validate it. This -+ * does not include the leaf cert. It is actually a -+ * linked list of ssl3CertNode structs. -+ */ - CERTDistNames * ca_list; - /* used by server. trusted CAs for this socket. */ - PRBool initialized; -@@ -1524,6 +1541,10 @@ extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -+extern SECStatus ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, -+ PRUint16 ex_type, SECItem *data); -+extern SECStatus ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, -+ PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, -@@ -1545,6 +1566,10 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append, - */ - extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); -+extern PRInt32 ssl3_ClientSendCachedInfoXtn(sslSocket *ss, PRBool append, -+ PRUint32 maxBytes); -+extern PRInt32 ssl3_ServerSendCachedInfoXtn(sslSocket *ss, PRBool append, -+ PRUint32 maxBytes); - - /* Assigns new cert, cert chain and keys to ss->serverCerts - * struct. If certChain is NULL, tries to find one. Aborts if -@@ -1648,6 +1673,12 @@ SECStatus SSL_DisableDefaultExportCipherSuites(void); - SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); - PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite); - -+/********************** FNV hash *********************/ -+ -+void FNV1A64_Init(PRUint64 *digest); -+void FNV1A64_Update(PRUint64 *digest, const unsigned char *data, -+ unsigned int length); -+void FNV1A64_Final(PRUint64 *digest); - - #ifdef TRACE - #define SSL_TRACE(msg) ssl_Trace msg -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c -index 4c4df3f..3d89d86 100644 ---- a/mozilla/security/nss/lib/ssl/sslsock.c -+++ b/mozilla/security/nss/lib/ssl/sslsock.c -@@ -186,6 +186,7 @@ static sslOptions ssl_defaults = { - PR_FALSE, /* requireSafeNegotiation */ - PR_FALSE, /* enableFalseStart */ - PR_FALSE, /* enableOCSPStapling */ -+ PR_FALSE, /* enableCachedInfo */ - }; - - sslSessionIDLookupFunc ssl_sid_lookup; -@@ -743,6 +744,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) - ss->opt.enableOCSPStapling = on; - break; - -+ case SSL_ENABLE_CACHED_INFO: -+ ss->opt.enableCachedInfo = on; -+ break; -+ - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - rv = SECFailure; -@@ -808,6 +813,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) - on = ss->opt.requireSafeNegotiation; break; - case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; - case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; -+ case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -862,6 +868,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) - case SSL_ENABLE_OCSP_STAPLING: - on = ssl_defaults.enableOCSPStapling; - break; -+ case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -1013,6 +1020,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) - ssl_defaults.enableOCSPStapling = on; - break; - -+ case SSL_ENABLE_CACHED_INFO: -+ ssl_defaults.enableCachedInfo = on; -+ break; -+ - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; -diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h -index 917c093..bca7496 100644 ---- a/mozilla/security/nss/lib/ssl/sslt.h -+++ b/mozilla/security/nss/lib/ssl/sslt.h -@@ -205,9 +205,10 @@ typedef enum { - #endif - ssl_session_ticket_xtn = 35, - ssl_next_proto_neg_xtn = 13172, -+ ssl_cached_info_xtn = 13173, - ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ - } SSLExtensionType; - --#define SSL_MAX_EXTENSIONS 7 -+#define SSL_MAX_EXTENSIONS 8 - - #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/patches/cbcrandomiv.patch b/net/third_party/nss/patches/cbcrandomiv.patch deleted file mode 100644 index a55e808..0000000 --- a/net/third_party/nss/patches/cbcrandomiv.patch +++ /dev/null @@ -1,181 +0,0 @@ -From fb2d182ed92f38bd9c1134bb929f095ea6d3e752 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:23:29 -0400 -Subject: [PATCH] cbcrandomiv.patch - ---- - mozilla/security/nss/lib/ssl/ssl3con.c | 97 +++++++++++++++++++++++--------- - 1 files changed, 70 insertions(+), 27 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index dd99962..d561307 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -2039,24 +2039,24 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { - return isPresent; - } - -+/* Caller must hold the spec read lock. wrBuf is sometimes, but not always, -+ * ss->sec.writeBuf. -+ */ - static SECStatus --ssl3_CompressMACEncryptRecord(sslSocket * ss, -+ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, -+ PRBool isServer, - SSL3ContentType type, - const SSL3Opaque * pIn, -- PRUint32 contentLen) -+ PRUint32 contentLen, -+ sslBuffer * wrBuf) - { -- ssl3CipherSpec * cwSpec; - const ssl3BulkCipherDef * cipher_def; -- sslBuffer * wrBuf = &ss->sec.writeBuf; - SECStatus rv; - PRUint32 macLen = 0; - PRUint32 fragLen; - PRUint32 p1Len, p2Len, oddLen = 0; - PRInt32 cipherBytes = 0; - -- ssl_GetSpecReadLock(ss); /********************************/ -- -- cwSpec = ss->ssl3.cwSpec; - cipher_def = cwSpec->cipher_def; - - if (cwSpec->compressor) { -@@ -2073,12 +2073,12 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss, - /* - * Add the MAC - */ -- rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), -+ rv = ssl3_ComputeRecordMAC( cwSpec, isServer, - type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen, - wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen); - if (rv != SECSuccess) { - ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); -- goto spec_locked_loser; -+ return SECFailure; - } - p1Len = contentLen; - p2Len = macLen; -@@ -2131,7 +2131,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss, - PORT_Assert(rv == SECSuccess && cipherBytes == p1Len); - if (rv != SECSuccess || cipherBytes != p1Len) { - PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); -- goto spec_locked_loser; -+ return SECFailure; - } - } - if (p2Len > 0) { -@@ -2145,7 +2145,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss, - PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len); - if (rv != SECSuccess || cipherBytesPart2 != p2Len) { - PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); -- goto spec_locked_loser; -+ return SECFailure; - } - cipherBytes += cipherBytesPart2; - } -@@ -2160,13 +2160,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss, - wrBuf->buf[3] = MSB(cipherBytes); - wrBuf->buf[4] = LSB(cipherBytes); - -- ssl_ReleaseSpecReadLock(ss); /************************************/ -- - return SECSuccess; -- --spec_locked_loser: -- ssl_ReleaseSpecReadLock(ss); -- return SECFailure; - } - - /* Process the plain text before sending it. -@@ -2227,20 +2221,71 @@ ssl3_SendRecord( sslSocket * ss, - - while (nIn > 0) { - PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); -+ unsigned int spaceNeeded; -+ unsigned int numRecords; -+ -+ ssl_GetSpecReadLock(ss); /********************************/ -+ -+ if (nIn > 1 && -+ ss->opt.enableFalseStart && -+ ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS && -+ type == content_application_data && -+ ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { -+ /* We will split the first byte of the record into its own record, -+ * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h -+ */ -+ numRecords = 2; -+ } else { -+ numRecords = 1; -+ } - -- if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { -- PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); -- newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); -- newSpace += SSL3_BUFFER_FUDGE; -- rv = sslBuffer_Grow(wrBuf, newSpace); -+ spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); -+ if (spaceNeeded > wrBuf->space) { -+ rv = sslBuffer_Grow(wrBuf, spaceNeeded); - if (rv != SECSuccess) { - SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", -- SSL_GETPID(), ss->fd, newSpace)); -- return SECFailure; /* sslBuffer_Grow set a memory error code. */ -+ SSL_GETPID(), ss->fd, spaceNeeded)); -+ goto spec_locked_loser; /* sslBuffer_Grow set a memory error code. */ -+ } -+ } -+ -+ if (numRecords == 2) { -+ sslBuffer secondRecord; -+ -+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, -+ ss->sec.isServer, type, pIn, 1, -+ wrBuf); -+ if (rv != SECSuccess) -+ goto spec_locked_loser; -+ -+ PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:", -+ wrBuf->buf, wrBuf->len)); -+ -+ secondRecord.buf = wrBuf->buf + wrBuf->len; -+ secondRecord.len = 0; -+ secondRecord.space = wrBuf->space - wrBuf->len; -+ -+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, -+ ss->sec.isServer, type, pIn + 1, -+ contentLen - 1, &secondRecord); -+ if (rv == SECSuccess) { -+ PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:", -+ secondRecord.buf, secondRecord.len)); -+ wrBuf->len += secondRecord.len; -+ } -+ } else { -+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, -+ ss->sec.isServer, type, pIn, -+ contentLen, wrBuf); -+ if (rv == SECSuccess) { -+ PRINT_BUF(50, (ss, "send (encrypted) record data [1/1]:", -+ wrBuf->buf, wrBuf->len)); - } - } - -- rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen); -+spec_locked_loser: -+ ssl_ReleaseSpecReadLock(ss); /************************************/ -+ - if (rv != SECSuccess) - return SECFailure; - -@@ -2248,8 +2293,6 @@ ssl3_SendRecord( sslSocket * ss, - nIn -= contentLen; - PORT_Assert( nIn >= 0 ); - -- PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len)); -- - /* If there's still some previously saved ciphertext, - * or the caller doesn't want us to send the data yet, - * then add all our new ciphertext to the amount previously saved. diff --git a/net/third_party/nss/patches/clientauth.patch b/net/third_party/nss/patches/clientauth.patch index 371c640..7bf8369 100644 --- a/net/third_party/nss/patches/clientauth.patch +++ b/net/third_party/nss/patches/clientauth.patch @@ -1,24 +1,7 @@ -From 1ebf459243cea430614e1958ecab1ad10457ccc2 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:44:48 -0400 -Subject: [PATCH] clientauth.patch - ---- - mozilla/security/nss/lib/ssl/ssl.h | 39 +++ - mozilla/security/nss/lib/ssl/ssl3con.c | 163 ++++++++++--- - mozilla/security/nss/lib/ssl/ssl3ext.c | 2 +- - mozilla/security/nss/lib/ssl/sslauth.c | 22 ++ - mozilla/security/nss/lib/ssl/sslimpl.h | 45 ++++ - mozilla/security/nss/lib/ssl/sslplatf.c | 399 +++++++++++++++++++++++++++++++ - mozilla/security/nss/lib/ssl/sslsock.c | 14 + - 7 files changed, 647 insertions(+), 37 deletions(-) - create mode 100644 mozilla/security/nss/lib/ssl/sslplatf.c - -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index 7e748bd..03535f3 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -353,6 +353,45 @@ typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg, +diff -upN a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-28 19:26:04.047351199 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-28 20:04:24.039351965 -0800 +@@ -421,6 +421,45 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd, SSLGetClientAuthData f, void *a); @@ -64,11 +47,10 @@ index 7e748bd..03535f3 100644 /* ** SNI extension processing callback function. -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index d372ee2..ad8f4cd 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -2018,6 +2018,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { +diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 19:26:04.047351199 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 20:07:04.101579541 -0800 +@@ -2015,6 +2015,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID PRBool isPresent = PR_TRUE; /* we only care if we are doing client auth */ @@ -78,7 +60,7 @@ index d372ee2..ad8f4cd 100644 if (!sid || !sid->u.ssl3.clAuthValid) { return PR_TRUE; } -@@ -4865,27 +4868,30 @@ ssl3_SendCertificateVerify(sslSocket *ss) +@@ -4893,24 +4896,33 @@ ssl3_SendCertificateVerify(sslSocket *ss } isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); @@ -109,12 +91,6 @@ index d372ee2..ad8f4cd 100644 - sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot); - sid->u.ssl3.clAuthValid = PR_TRUE; - PK11_FreeSlot(slot); -- } -- /* If we're doing RSA key exchange, we're all done with the private key -- * here. Diffie-Hellman key exchanges need the client's -- * private key for the key exchange. -- */ -- if (ss->ssl3.hs.kea_def->exchKeyType == kt_rsa) { + /* Remember the info about the slot that did the signing. + ** Later, when doing an SSL restart handshake, verify this. + ** These calls are mere accessors, and can't fail. @@ -126,37 +102,28 @@ index d372ee2..ad8f4cd 100644 + sid->u.ssl3.clAuthValid = PR_TRUE; + PK11_FreeSlot(slot); + } - SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); - ss->ssl3.clientPrivateKey = NULL; ++ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); ++ ss->ssl3.clientPrivateKey = NULL; } -@@ -4943,6 +4949,26 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - goto alert_loser; +- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); +- ss->ssl3.clientPrivateKey = NULL; + if (rv != SECSuccess) { + goto done; /* err code was set by ssl3_SignHashes */ + } +@@ -4978,6 +4990,12 @@ ssl3_HandleServerHello(sslSocket *ss, SS + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); + ss->ssl3.clientPrivateKey = NULL; } - -+ /* clean up anything left from previous handshake. */ -+ if (ss->ssl3.clientCertChain != NULL) { -+ CERT_DestroyCertificateList(ss->ssl3.clientCertChain); -+ ss->ssl3.clientCertChain = NULL; -+ } -+ if (ss->ssl3.clientCertificate != NULL) { -+ CERT_DestroyCertificate(ss->ssl3.clientCertificate); -+ ss->ssl3.clientCertificate = NULL; -+ } -+ if (ss->ssl3.clientPrivateKey != NULL) { -+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); -+ ss->ssl3.clientPrivateKey = NULL; -+ } +#ifdef NSS_PLATFORM_CLIENT_AUTH + if (ss->ssl3.platformClientKey) { + ssl_FreePlatformKey(ss->ssl3.platformClientKey); + ss->ssl3.platformClientKey = (PlatformKey)NULL; + } +#endif /* NSS_PLATFORM_CLIENT_AUTH */ -+ + temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); if (temp < 0) { - goto loser; /* alert has been sent */ -@@ -5485,6 +5511,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +@@ -5522,6 +5540,10 @@ ssl3_HandleCertificateRequest(sslSocket SSL3AlertDescription desc = illegal_parameter; SECItem cert_types = {siBuffer, NULL, 0}; CERTDistNames ca_list; @@ -167,31 +134,15 @@ index d372ee2..ad8f4cd 100644 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake", SSL_GETPID(), ss->fd)); -@@ -5498,19 +5528,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) - goto alert_loser; - } - -- /* clean up anything left from previous handshake. */ -- if (ss->ssl3.clientCertChain != NULL) { -- CERT_DestroyCertificateList(ss->ssl3.clientCertChain); -- ss->ssl3.clientCertChain = NULL; -- } -- if (ss->ssl3.clientCertificate != NULL) { -- CERT_DestroyCertificate(ss->ssl3.clientCertificate); -- ss->ssl3.clientCertificate = NULL; -- } -- if (ss->ssl3.clientPrivateKey != NULL) { -- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); -- ss->ssl3.clientPrivateKey = NULL; -- } -+ PORT_Assert(ss->ssl3.clientCertChain == NULL); -+ PORT_Assert(ss->ssl3.clientCertificate == NULL); -+ PORT_Assert(ss->ssl3.clientPrivateKey == NULL); +@@ -5538,6 +5560,7 @@ ssl3_HandleCertificateRequest(sslSocket + PORT_Assert(ss->ssl3.clientCertChain == NULL); + PORT_Assert(ss->ssl3.clientCertificate == NULL); + PORT_Assert(ss->ssl3.clientPrivateKey == NULL); + PORT_Assert(ss->ssl3.platformClientKey == (PlatformKey)NULL); isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length); -@@ -5577,6 +5598,20 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +@@ -5604,6 +5627,20 @@ ssl3_HandleCertificateRequest(sslSocket desc = no_certificate; ss->ssl3.hs.ws = wait_hello_done; @@ -212,14 +163,14 @@ index d372ee2..ad8f4cd 100644 if (ss->getClientAuthData == NULL) { rv = SECFailure; /* force it to send a no_certificate alert */ } else { -@@ -5586,12 +5621,52 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +@@ -5613,12 +5650,52 @@ ssl3_HandleCertificateRequest(sslSocket &ss->ssl3.clientCertificate, &ss->ssl3.clientPrivateKey); } +#endif /* NSS_PLATFORM_CLIENT_AUTH */ switch (rv) { case SECWouldBlock: /* getClientAuthData has put up a dialog box. */ - ssl_SetAlwaysBlock(ss); + ssl3_SetAlwaysBlock(ss); break; /* not an error */ case SECSuccess: @@ -265,7 +216,7 @@ index d372ee2..ad8f4cd 100644 /* check what the callback function returned */ if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { /* we are missing either the key or cert */ -@@ -5654,6 +5729,10 @@ loser: +@@ -5681,6 +5758,10 @@ loser: done: if (arena != NULL) PORT_FreeArena(arena, PR_FALSE); @@ -276,28 +227,17 @@ index d372ee2..ad8f4cd 100644 return rv; } -@@ -5785,9 +5864,17 @@ ssl3_HandleServerHelloDone(sslSocket *ss) - if (rv != SECSuccess) { - goto loser; /* error code is set. */ - } -- } else -- if (ss->ssl3.clientCertChain != NULL && -- ss->ssl3.clientPrivateKey != NULL) { -+ } else if (ss->ssl3.clientCertChain != NULL && -+ ss->ssl3.platformClientKey) { -+#ifdef NSS_PLATFORM_CLIENT_AUTH -+ send_verify = PR_TRUE; -+ rv = ssl3_SendCertificate(ss); -+ if (rv != SECSuccess) { -+ goto loser; /* error code is set. */ -+ } -+#endif /* NSS_PLATFORM_CLIENT_AUTH */ -+ } else if (ss->ssl3.clientCertChain != NULL && -+ ss->ssl3.clientPrivateKey != NULL) { - send_verify = PR_TRUE; - rv = ssl3_SendCertificate(ss); - if (rv != SECSuccess) { -@@ -9856,6 +9943,10 @@ ssl3_DestroySSL3Info(sslSocket *ss) +@@ -5755,7 +5836,8 @@ ssl3_SendClientSecondRound(sslSocket *ss + + sendClientCert = !ss->ssl3.sendEmptyCert && + ss->ssl3.clientCertChain != NULL && +- ss->ssl3.clientPrivateKey != NULL; ++ (ss->ssl3.platformClientKey || ++ ss->ssl3.clientPrivateKey != NULL); + + /* We must wait for the server's certificate to be authenticated before + * sending the client certificate in order to disclosing the client +@@ -9725,6 +9807,10 @@ ssl3_DestroySSL3Info(sslSocket *ss) if (ss->ssl3.clientPrivateKey != NULL) SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); @@ -308,10 +248,9 @@ index d372ee2..ad8f4cd 100644 if (ss->ssl3.peerCertArena != NULL) ssl3_CleanupPeerCerts(ss); -diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c -index 887344b..e54b4fd 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3ext.c -+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c +diff -upN a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c +--- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 19:26:04.047351199 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 20:20:35.392842118 -0800 @@ -46,8 +46,8 @@ #include "nssrenam.h" #include "nss.h" @@ -322,11 +261,10 @@ index 887344b..e54b4fd 100644 #include "pk11pub.h" #include "blapi.h" #include "prinit.h" -diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/ssl/sslauth.c -index fcd15ca..8da5c66 100644 ---- a/mozilla/security/nss/lib/ssl/sslauth.c -+++ b/mozilla/security/nss/lib/ssl/sslauth.c -@@ -292,6 +292,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, +diff -upN a/src/net/third_party/nss/ssl/sslauth.c b/src/net/third_party/nss/ssl/sslauth.c +--- a/src/net/third_party/nss/ssl/sslauth.c 2012-02-28 18:34:23.263186340 -0800 ++++ b/src/net/third_party/nss/ssl/sslauth.c 2012-02-28 20:04:24.039351965 -0800 +@@ -251,6 +251,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, return SECSuccess; } @@ -355,10 +293,9 @@ index fcd15ca..8da5c66 100644 /* NEED LOCKS IN HERE. */ SECStatus SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index 70ff4c3..d73a0e3 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h +diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 19:26:04.047351199 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 20:04:24.039351965 -0800 @@ -65,6 +65,15 @@ #include "sslt.h" /* for some formerly private types, now public */ @@ -375,7 +312,7 @@ index 70ff4c3..d73a0e3 100644 /* to make some of these old enums public without namespace pollution, ** it was necessary to prepend ssl_ to the names. ** These #defines preserve compatibility with the old code here in libssl. -@@ -464,6 +473,14 @@ typedef SECStatus (*SSLCompressor)(void * context, +@@ -462,6 +471,14 @@ typedef SECStatus (*SSLCompressor)(void int inlen); typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit); @@ -401,7 +338,7 @@ index 70ff4c3..d73a0e3 100644 CERTCertificateList *clientCertChain; /* used by client */ PRBool sendEmptyCert; /* used by client */ -@@ -1097,6 +1118,10 @@ const unsigned char * preferredCipher; +@@ -1082,6 +1103,10 @@ const unsigned char * preferredCipher; void *authCertificateArg; SSLGetClientAuthData getClientAuthData; void *getClientAuthDataArg; @@ -412,7 +349,7 @@ index 70ff4c3..d73a0e3 100644 SSLSNISocketConfig sniSocketConfig; void *sniSocketConfigArg; SSLBadCertHandler handleBadCert; -@@ -1663,6 +1688,26 @@ extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); +@@ -1644,6 +1669,26 @@ extern SECStatus ssl_InitSessionCacheLoc extern SECStatus ssl_FreeSessionCacheLocks(void); @@ -439,11 +376,9 @@ index 70ff4c3..d73a0e3 100644 /********************** misc calls *********************/ -diff --git a/mozilla/security/nss/lib/ssl/sslplatf.c b/mozilla/security/nss/lib/ssl/sslplatf.c -new file mode 100644 -index 0000000..208956f ---- /dev/null -+++ b/mozilla/security/nss/lib/ssl/sslplatf.c +diff -upN a/src/net/third_party/nss/ssl/sslplatf.c b/src/net/third_party/nss/ssl/sslplatf.c +--- a/src/net/third_party/nss/ssl/sslplatf.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/src/net/third_party/nss/ssl/sslplatf.c 2012-02-28 20:04:24.039351965 -0800 @@ -0,0 +1,399 @@ +/* + * Platform specific crypto wrappers @@ -844,10 +779,9 @@ index 0000000..208956f +#endif + +#endif /* NSS_PLATFORM_CLIENT_AUTH */ -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c -index 7d12bfe..68fd3cb 100644 ---- a/mozilla/security/nss/lib/ssl/sslsock.c -+++ b/mozilla/security/nss/lib/ssl/sslsock.c +diff -upN a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 19:26:04.057351342 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 20:04:24.049352104 -0800 @@ -339,6 +339,10 @@ ssl_DupSocket(sslSocket *os) ss->authCertificateArg = os->authCertificateArg; ss->getClientAuthData = os->getClientAuthData; @@ -859,7 +793,7 @@ index 7d12bfe..68fd3cb 100644 ss->sniSocketConfig = os->sniSocketConfig; ss->sniSocketConfigArg = os->sniSocketConfigArg; ss->handleBadCert = os->handleBadCert; -@@ -1468,6 +1472,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) +@@ -1530,6 +1534,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile ss->getClientAuthData = sm->getClientAuthData; if (sm->getClientAuthDataArg) ss->getClientAuthDataArg = sm->getClientAuthDataArg; @@ -872,7 +806,7 @@ index 7d12bfe..68fd3cb 100644 if (sm->sniSocketConfig) ss->sniSocketConfig = sm->sniSocketConfig; if (sm->sniSocketConfigArg) -@@ -2525,6 +2535,10 @@ ssl_NewSocket(PRBool makeLocks) +@@ -2617,6 +2627,10 @@ ssl_NewSocket(PRBool makeLocks) ss->sniSocketConfig = NULL; ss->sniSocketConfigArg = NULL; ss->getClientAuthData = NULL; diff --git a/net/third_party/nss/patches/didhandshakeresume.patch b/net/third_party/nss/patches/didhandshakeresume.patch index 95890e9..ed74c79 100644 --- a/net/third_party/nss/patches/didhandshakeresume.patch +++ b/net/third_party/nss/patches/didhandshakeresume.patch @@ -1,46 +1,20 @@ -From 56e625df4d443b939c39fa75f907518bf66f6584 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:23:01 -0400 -Subject: [PATCH] didhandshakeresume.patch - ---- - mozilla/security/nss/lib/ssl/ssl.def | 1 + - mozilla/security/nss/lib/ssl/ssl.h | 4 ++++ - mozilla/security/nss/lib/ssl/sslsock.c | 14 ++++++++++++++ - 3 files changed, 19 insertions(+), 0 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def -index 35cc1e3..7ef15db 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.def -+++ b/mozilla/security/nss/lib/ssl/ssl.def -@@ -156,6 +156,7 @@ SSL_SNISocketConfigHook; - ;+ global: - SSL_GetNextProto; - SSL_GetStapledOCSPResponse; -+SSL_HandshakeResumedSession; - SSL_PeerCertificateChain; - SSL_SetNextProtoNego; - ;+ local: -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index 3a22b45..c32438d 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -697,6 +697,10 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-28 20:34:50.114663722 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 14:37:56.872332622 -0800 +@@ -818,6 +818,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegoti SSLExtensionType extId, PRBool *yes); +SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd, + PRBool *last_handshake_resumed); + -+ - SEC_END_PROTOS - - #endif /* __ssl_h_ */ -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c -index 3d89d86..11b53da 100644 ---- a/mozilla/security/nss/lib/ssl/sslsock.c -+++ b/mozilla/security/nss/lib/ssl/sslsock.c -@@ -1507,6 +1507,20 @@ SSL_GetStapledOCSPResponse(PRFileDesc *fd, unsigned char *out_data, + /* + * Return a boolean that indicates whether the underlying library + * will perform as the caller expects. +diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 20:34:50.124663860 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 14:39:13.203415737 -0800 +@@ -1590,6 +1590,20 @@ SSL_GetStapledOCSPResponse(PRFileDesc *f return SECSuccess; } diff --git a/net/third_party/nss/patches/encryptedclientcerts.patch b/net/third_party/nss/patches/encryptedclientcerts.patch index 15a5e78..7612092 100644 --- a/net/third_party/nss/patches/encryptedclientcerts.patch +++ b/net/third_party/nss/patches/encryptedclientcerts.patch @@ -1,208 +1,34 @@ -Index: net/third_party/nss/ssl/ssl.h -=================================================================== ---- net/third_party/nss/ssl/ssl.h (revision 108962) -+++ net/third_party/nss/ssl/ssl.h (working copy) -@@ -143,6 +143,7 @@ - #define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */ - /* extension, off by default. */ +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 19:15:20.975171099 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 19:18:21.947702106 -0800 +@@ -169,6 +169,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi + #define SSL_CBC_RANDOM_IV 23 + #define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ #define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */ +#define SSL_ENCRYPT_CLIENT_CERTS 26 /* Enable encrypted client certs. */ #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ -Index: net/third_party/nss/ssl/sslimpl.h -=================================================================== ---- net/third_party/nss/ssl/sslimpl.h (revision 108962) -+++ net/third_party/nss/ssl/sslimpl.h (working copy) -@@ -350,6 +350,7 @@ - unsigned int enableOCSPStapling : 1; /* 24 */ - unsigned int enableCachedInfo : 1; /* 25 */ +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 19:15:20.975171099 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 19:19:26.478604857 -0800 +@@ -350,6 +350,7 @@ typedef struct sslOptionsStr { + unsigned int cbcRandomIV : 1; /* 24 */ + unsigned int enableOCSPStapling : 1; /* 25 */ unsigned int enableOBCerts : 1; /* 26 */ + unsigned int encryptClientCerts : 1; /* 27 */ } sslOptions; typedef enum { sslHandshakingUndetermined = 0, -Index: net/third_party/nss/ssl/ssl3ext.c -=================================================================== ---- net/third_party/nss/ssl/ssl3ext.c (revision 108962) -+++ net/third_party/nss/ssl/ssl3ext.c (working copy) -@@ -78,6 +78,12 @@ - PRBool append, PRUint32 maxBytes); - static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -+static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, -+ PRUint16 ex_type, SECItem *data); -+static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, -+ PRUint16 ex_type, SECItem *data); -+static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, -+ PRBool append, PRUint32 maxBytes); - - /* - * Write bytes. Using this function means the SECItem structure -@@ -234,6 +240,7 @@ - { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, - #endif - { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, -+ { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn }, -@@ -247,6 +254,7 @@ - { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, - /* TODO: add a handler for ssl_ec_point_formats_xtn */ - { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, -+ { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn }, -@@ -275,6 +283,7 @@ - { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, - #endif - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, -+ { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn }, - { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, -@@ -1318,6 +1327,18 @@ - return SECSuccess; - } - -+static SECStatus -+ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, -+ SECItem *data) -+{ -+ if (data->len != 0) -+ return SECFailure; -+ -+ /* Keep track of negotiated extensions. */ -+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; -+ return SECSuccess; -+} -+ - SECStatus - ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, - SECItem *data) -@@ -1728,6 +1749,24 @@ - return rv; - } - -+static SECStatus -+ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, -+ SECItem *data) -+{ -+ SECStatus rv = SECSuccess; -+ -+ if (data->len != 0) -+ return SECFailure; -+ -+ if (ss->opt.encryptClientCerts) { -+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; -+ rv = ssl3_RegisterServerHelloExtensionSender( -+ ss, ex_type, ssl3_SendEncryptedClientCertsXtn); -+ } -+ -+ return rv; -+} -+ - /* - * Read bytes. Using this function means the SECItem structure - * cannot be freed. The caller is expected to call this function -@@ -1927,6 +1966,33 @@ - return needed; - } - -+static PRInt32 -+ssl3_SendEncryptedClientCertsXtn( -+ sslSocket * ss, -+ PRBool append, -+ PRUint32 maxBytes) -+{ -+ PRInt32 needed; -+ -+ if (!ss->opt.encryptClientCerts) -+ return 0; -+ -+ needed = 4; /* two bytes of type and two of length. */ -+ if (append && maxBytes >= needed) { -+ SECStatus rv; -+ rv = ssl3_AppendHandshakeNumber(ss, ssl_encrypted_client_certs, 2); -+ if (rv != SECSuccess) -+ return -1; -+ rv = ssl3_AppendHandshakeNumber(ss, 0 /* length */, 2); -+ if (rv != SECSuccess) -+ return -1; -+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = -+ ssl_encrypted_client_certs; -+ } -+ -+ return needed; -+} -+ - /* This function runs in both the client and server. */ - static SECStatus - ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) -Index: net/third_party/nss/ssl/sslsock.c -=================================================================== ---- net/third_party/nss/ssl/sslsock.c (revision 108962) -+++ net/third_party/nss/ssl/sslsock.c (working copy) -@@ -188,6 +188,7 @@ - PR_FALSE, /* enableOCSPStapling */ - PR_FALSE, /* enableCachedInfo */ - PR_FALSE, /* enableOBCerts */ -+ PR_FALSE, /* encryptClientCerts */ - }; - - sslSessionIDLookupFunc ssl_sid_lookup; -@@ -757,6 +758,10 @@ - ss->opt.enableOBCerts = on; - break; - -+ case SSL_ENCRYPT_CLIENT_CERTS: -+ ss->opt.encryptClientCerts = on; -+ break; -+ - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - rv = SECFailure; -@@ -824,6 +829,8 @@ - case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; - case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break; - case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; -+ case SSL_ENCRYPT_CLIENT_CERTS: -+ on = ss->opt.encryptClientCerts; break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -880,6 +887,8 @@ - break; - case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break; - case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; -+ case SSL_ENCRYPT_CLIENT_CERTS: -+ on = ssl_defaults.encryptClientCerts; break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -1039,6 +1048,10 @@ - ssl_defaults.enableOBCerts = on; - break; - -+ case SSL_ENCRYPT_CLIENT_CERTS: -+ ssl_defaults.encryptClientCerts = on; -+ break; -+ - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; -Index: net/third_party/nss/ssl/ssl3con.c -=================================================================== ---- net/third_party/nss/ssl/ssl3con.c (revision 108962) -+++ net/third_party/nss/ssl/ssl3con.c (working copy) -@@ -2835,8 +2835,15 @@ +diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 19:15:20.975171099 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 20:00:15.851981917 -0800 +@@ -2863,7 +2863,14 @@ ssl3_HandleChangeCipherSpecs(sslSocket * ss->ssl3.prSpec = ss->ssl3.crSpec; ss->ssl3.crSpec = prSpec; - ss->ssl3.hs.ws = wait_finished; - ++ + if (ss->sec.isServer && + ss->opt.requestCertificate && + ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { @@ -210,11 +36,10 @@ Index: net/third_party/nss/ssl/ssl3con.c + } else { + ss->ssl3.hs.ws = wait_finished; + } -+ + SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending", SSL_GETPID(), ss->fd )); - -@@ -4850,10 +4857,11 @@ +@@ -4877,10 +4884,11 @@ loser: static SECStatus ssl3_SendCertificateVerify(sslSocket *ss) { @@ -230,7 +55,7 @@ Index: net/third_party/nss/ssl/ssl3con.c PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); -@@ -4862,13 +4870,17 @@ +@@ -4889,13 +4897,17 @@ ssl3_SendCertificateVerify(sslSocket *ss SSL_GETPID(), ss->fd)); ssl_GetSpecReadLock(ss); @@ -250,19 +75,18 @@ Index: net/third_party/nss/ssl/ssl3con.c if (ss->ssl3.platformClientKey) { #ifdef NSS_PLATFORM_CLIENT_AUTH rv = ssl3_PlatformSignHashes(&hashes, ss->ssl3.platformClientKey, -@@ -5840,7 +5852,10 @@ +@@ -5912,6 +5924,10 @@ ssl3_SendClientSecondRound(sslSocket *ss { - SECStatus rv; - SSL3WaitState ws = ss->ssl3.hs.ws; -- PRBool send_verify = PR_FALSE; -+ PRBool sendEmptyCert, sendCert; -+ int n = 0, i; + SECStatus rv; + PRBool sendClientCert; ++ PRBool sendEmptyCert; ++ int n = 0, i; + typedef SECStatus (*SendFunction)(sslSocket*); + SendFunction send_funcs[5]; - SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake", - SSL_GETPID(), ss->fd)); -@@ -5858,46 +5873,45 @@ + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); +@@ -5958,35 +5974,40 @@ ssl3_SendClientSecondRound(sslSocket *ss ssl_GetXmitBufLock(ss); /*******************************/ @@ -273,18 +97,7 @@ Index: net/third_party/nss/ssl/ssl3con.c - if (rv != SECSuccess) { - goto loser; /* error code is set. */ - } -- } else if (ss->ssl3.clientCertChain != NULL && -- ss->ssl3.platformClientKey) { --#ifdef NSS_PLATFORM_CLIENT_AUTH -- send_verify = PR_TRUE; -- rv = ssl3_SendCertificate(ss); -- if (rv != SECSuccess) { -- goto loser; /* error code is set. */ -- } --#endif /* NSS_PLATFORM_CLIENT_AUTH */ -- } else if (ss->ssl3.clientCertChain != NULL && -- ss->ssl3.clientPrivateKey != NULL) { -- send_verify = PR_TRUE; +- } else if (sendClientCert) { - rv = ssl3_SendCertificate(ss); - if (rv != SECSuccess) { - goto loser; /* error code is set. */ @@ -292,10 +105,6 @@ Index: net/third_party/nss/ssl/ssl3con.c - } + sendEmptyCert = ss->ssl3.sendEmptyCert; + ss->ssl3.sendEmptyCert = PR_FALSE; -+ sendCert = !sendEmptyCert && -+ ss->ssl3.clientCertChain != NULL && -+ (ss->ssl3.platformClientKey || -+ ss->ssl3.clientPrivateKey != NULL); - rv = ssl3_SendClientKeyExchange(ss); - if (rv != SECSuccess) { @@ -306,7 +115,7 @@ Index: net/third_party/nss/ssl/ssl3con.c + if (sendEmptyCert) { + send_funcs[n++] = ssl3_SendEmptyCertificate; + } -+ if (sendCert) { ++ if (sendClientCert) { + send_funcs[n++] = ssl3_SendCertificate; + send_funcs[n++] = ssl3_SendCertificateVerify; + } @@ -314,36 +123,36 @@ Index: net/third_party/nss/ssl/ssl3con.c + if (sendEmptyCert) { + send_funcs[n++] = ssl3_SendEmptyCertificate; + } -+ if (sendCert) { ++ if (sendClientCert) { + send_funcs[n++] = ssl3_SendCertificate; + } + send_funcs[n++] = ssl3_SendClientKeyExchange; -+ if (sendCert) { ++ if (sendClientCert) { + send_funcs[n++] = ssl3_SendCertificateVerify; + } + send_funcs[n++] = ssl3_SendChangeCipherSpecs; } -- if (send_verify) { +- if (sendClientCert) { - rv = ssl3_SendCertificateVerify(ss); +- if (rv != SECSuccess) { +- goto loser; /* err is set. */ +- } +- } + PORT_Assert(n <= sizeof(send_funcs)/sizeof(send_funcs[0])); -+ + +- rv = ssl3_SendChangeCipherSpecs(ss); +- if (rv != SECSuccess) { +- goto loser; /* err code was set. */ + for (i = 0; i < n; i++) { + rv = send_funcs[i](ss); - if (rv != SECSuccess) { -- goto loser; /* err is set. */ -- } ++ if (rv != SECSuccess) { + goto loser; /* err code was set. */ + } } -- rv = ssl3_SendChangeCipherSpecs(ss); -- if (rv != SECSuccess) { -- goto loser; /* err code was set. */ -- } - /* We don't send NPN in a renegotiation as it's explicitly disallowed by - * the spec. */ -@@ -6110,8 +6124,13 @@ + /* XXX: If the server's certificate hasn't been authenticated by this +@@ -6201,8 +6222,13 @@ ssl3_SendServerHelloSequence(sslSocket * return rv; /* err code is set. */ } @@ -359,7 +168,7 @@ Index: net/third_party/nss/ssl/ssl3con.c return SECSuccess; } -@@ -7355,7 +7374,11 @@ +@@ -7446,7 +7472,11 @@ ssl3_HandleCertificateVerify(sslSocket * desc = isTLS ? decode_error : illegal_parameter; goto alert_loser; /* malformed */ } @@ -372,20 +181,20 @@ Index: net/third_party/nss/ssl/ssl3con.c return SECSuccess; alert_loser: -@@ -8348,7 +8371,11 @@ - - cert_block: - if (ss->sec.isServer) { +@@ -8346,7 +8376,11 @@ ssl3_HandleCertificate(sslSocket *ss, SS + } + } else { + server_no_cert: - ss->ssl3.hs.ws = wait_client_key; + if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + ss->ssl3.hs.ws = wait_cert_verify; + } else { + ss->ssl3.hs.ws = wait_client_key; + } - } else { - ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ - if (ss->ssl3.hs.kea_def->is_limited || -@@ -8978,6 +9005,8 @@ + } + + PORT_Assert(rv == SECSuccess); +@@ -8959,6 +8993,8 @@ ssl3_HandleHandshakeMessage(sslSocket *s if (type == finished) { sender = ss->sec.isServer ? sender_client : sender_server; rSpec = ss->ssl3.crSpec; @@ -394,20 +203,188 @@ Index: net/third_party/nss/ssl/ssl3con.c } rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); } -Index: net/third_party/nss/ssl/sslt.h -=================================================================== ---- net/third_party/nss/ssl/sslt.h (revision 108962) -+++ net/third_party/nss/ssl/sslt.h (working copy) -@@ -206,10 +206,11 @@ +diff -up a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c +--- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-29 17:12:15.720044263 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-29 20:00:15.851981917 -0800 +@@ -84,6 +84,12 @@ static SECStatus ssl3_ServerHandleNextPr + PRUint16 ex_type, SECItem *data); + static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); ++static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, ++ PRUint16 ex_type, SECItem *data); ++static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, ++ PRUint16 ex_type, SECItem *data); ++static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, ++ PRBool append, PRUint32 maxBytes); + + /* + * Write bytes. Using this function means the SECItem structure +@@ -240,6 +246,7 @@ static const ssl3HelloExtensionHandler c + { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, + #endif + { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, ++ { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, + { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, +@@ -252,6 +259,7 @@ static const ssl3HelloExtensionHandler s + { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, + /* TODO: add a handler for ssl_ec_point_formats_xtn */ + { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, ++ { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, +@@ -279,6 +287,7 @@ ssl3HelloExtensionSender clientHelloSend + { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, + #endif + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, ++ { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, + { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } +@@ -1083,6 +1092,18 @@ ssl3_ClientHandleSessionTicketXtn(sslSoc + return SECSuccess; + } + ++static SECStatus ++ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ if (data->len != 0) ++ return SECFailure; ++ ++ /* Keep track of negotiated extensions. */ ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ return SECSuccess; ++} ++ + SECStatus + ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) +@@ -1496,6 +1517,24 @@ loser: + return rv; + } + ++static SECStatus ++ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ SECStatus rv = SECSuccess; ++ ++ if (data->len != 0) ++ return SECFailure; ++ ++ if (ss->opt.encryptClientCerts) { ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ rv = ssl3_RegisterServerHelloExtensionSender( ++ ss, ex_type, ssl3_SendEncryptedClientCertsXtn); ++ } ++ ++ return rv; ++} ++ + /* + * Read bytes. Using this function means the SECItem structure + * cannot be freed. The caller is expected to call this function +@@ -1695,6 +1734,33 @@ ssl3_SendRenegotiationInfoXtn( + return needed; + } + ++static PRInt32 ++ssl3_SendEncryptedClientCertsXtn( ++ sslSocket * ss, ++ PRBool append, ++ PRUint32 maxBytes) ++{ ++ PRInt32 needed; ++ ++ if (!ss->opt.encryptClientCerts) ++ return 0; ++ ++ needed = 4; /* two bytes of type and two of length. */ ++ if (append && maxBytes >= needed) { ++ SECStatus rv; ++ rv = ssl3_AppendHandshakeNumber(ss, ssl_encrypted_client_certs, 2); ++ if (rv != SECSuccess) ++ return -1; ++ rv = ssl3_AppendHandshakeNumber(ss, 0 /* length */, 2); ++ if (rv != SECSuccess) ++ return -1; ++ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = ++ ssl_encrypted_client_certs; ++ } ++ ++ return needed; ++} ++ + /* This function runs in both the client and server. */ + static SECStatus + ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:49:08.431530583 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 20:00:15.851981917 -0800 +@@ -188,6 +188,7 @@ static sslOptions ssl_defaults = { + PR_TRUE, /* cbcRandomIV */ + PR_FALSE, /* enableOCSPStapling */ + PR_FALSE, /* enableOBCerts */ ++ PR_FALSE, /* encryptClientCerts */ + }; + + sslSessionIDLookupFunc ssl_sid_lookup; +@@ -755,6 +756,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh + ss->opt.enableOBCerts = on; + break; + ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ ss->opt.encryptClientCerts = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; +@@ -822,6 +827,8 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh + case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; + case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; + case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ on = ss->opt.encryptClientCerts; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -880,6 +887,8 @@ SSL_OptionGetDefault(PRInt32 which, PRBo + on = ssl_defaults.enableOCSPStapling; + break; + case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ on = ssl_defaults.encryptClientCerts; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -1047,6 +1056,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo + ssl_defaults.enableOBCerts = on; + break; + ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ ssl_defaults.encryptClientCerts = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +diff -up a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/sslt.h +--- a/src/net/third_party/nss/ssl/sslt.h 2012-02-29 17:12:15.780045080 -0800 ++++ b/src/net/third_party/nss/ssl/sslt.h 2012-02-29 19:34:43.921452065 -0800 +@@ -205,10 +205,11 @@ typedef enum { + #endif ssl_session_ticket_xtn = 35, - ssl_next_proto_neg_xtn = 13172, - ssl_cached_info_xtn = 13173, + ssl_next_proto_nego_xtn = 13172, + ssl_encrypted_client_certs = 13180, /* not IANA assigned. */ ssl_renegotiation_info_xtn = 0xff01, /* experimental number */ ssl_ob_cert_xtn = 13175 /* experimental number */ } SSLExtensionType; --#define SSL_MAX_EXTENSIONS 9 -+#define SSL_MAX_EXTENSIONS 10 +-#define SSL_MAX_EXTENSIONS 8 ++#define SSL_MAX_EXTENSIONS 9 #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/patches/getrequestedclientcerttypes.patch b/net/third_party/nss/patches/getrequestedclientcerttypes.patch index bc054dc..0b47707 100644 --- a/net/third_party/nss/patches/getrequestedclientcerttypes.patch +++ b/net/third_party/nss/patches/getrequestedclientcerttypes.patch @@ -1,11 +1,7 @@ -Index: security/nss/lib/ssl/ssl.h -=================================================================== -RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v -retrieving revision 1.38.2.1 -diff -u -r1.38.2.1 ssl.h ---- security/nss/lib/ssl/ssl.h 31 Jul 2010 04:33:52 -0000 1.38.2.1 -+++ security/nss/lib/ssl/ssl.h 6 Dec 2011 00:24:08 -0000 -@@ -459,6 +459,16 @@ +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:23:52.089678011 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:43:25.796676478 -0800 +@@ -648,6 +648,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWith PRBool flushCache, PRIntervalTime timeout); @@ -22,14 +18,10 @@ diff -u -r1.38.2.1 ssl.h #ifdef SSL_DEPRECATED_FUNCTION /* deprecated! -Index: security/nss/lib/ssl/ssl3con.c -=================================================================== -RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v -retrieving revision 1.142.2.4 -diff -u -r1.142.2.4 ssl3con.c ---- security/nss/lib/ssl/ssl3con.c 1 Sep 2010 19:47:11 -0000 1.142.2.4 -+++ security/nss/lib/ssl/ssl3con.c 6 Dec 2011 00:24:08 -0000 -@@ -5473,6 +5473,9 @@ +diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:23:52.089678011 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:43:25.796676478 -0800 +@@ -5567,6 +5567,9 @@ ssl3_HandleCertificateRequest(sslSocket if (rv != SECSuccess) goto loser; /* malformed, alert has been sent */ @@ -39,22 +31,18 @@ diff -u -r1.142.2.4 ssl3con.c arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) goto no_mem; -@@ -5608,6 +5611,7 @@ +@@ -5756,6 +5759,7 @@ loser: PORT_SetError(errCode); rv = SECFailure; done: + ss->requestedCertTypes = NULL; if (arena != NULL) PORT_FreeArena(arena, PR_FALSE); - return rv; -Index: security/nss/lib/ssl/sslimpl.h -=================================================================== -RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslimpl.h,v -retrieving revision 1.77.2.1 -diff -u -r1.77.2.1 sslimpl.h ---- security/nss/lib/ssl/sslimpl.h 31 Jul 2010 04:33:52 -0000 1.77.2.1 -+++ security/nss/lib/ssl/sslimpl.h 6 Dec 2011 00:24:08 -0000 -@@ -1044,6 +1044,10 @@ + #ifdef NSS_PLATFORM_CLIENT_AUTH +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:23:52.089678011 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:43:25.796676478 -0800 +@@ -1097,6 +1097,10 @@ struct sslSocketStr { unsigned int sizeCipherSpecs; const unsigned char * preferredCipher; @@ -65,15 +53,11 @@ diff -u -r1.77.2.1 sslimpl.h ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */ /* Callbacks */ -Index: security/nss/lib/ssl/sslsock.c -=================================================================== -RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsock.c,v -retrieving revision 1.67.2.1 -diff -u -r1.67.2.1 sslsock.c ---- security/nss/lib/ssl/sslsock.c 31 Jul 2010 04:33:52 -0000 1.67.2.1 -+++ security/nss/lib/ssl/sslsock.c 6 Dec 2011 00:24:08 -0000 -@@ -1373,6 +1373,20 @@ - return NULL; +diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:12:15.750044671 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:43:25.796676478 -0800 +@@ -1615,6 +1615,20 @@ SSL_HandshakeResumedSession(PRFileDesc * + return SECSuccess; } +const SECItem * @@ -93,7 +77,7 @@ diff -u -r1.67.2.1 sslsock.c /************************************************************************/ /* The following functions are the TOP LEVEL SSL functions. ** They all get called through the NSPRIOMethods table below. -@@ -2357,6 +2371,7 @@ +@@ -2643,6 +2657,7 @@ ssl_NewSocket(PRBool makeLocks) sc->serverKeyPair = NULL; sc->serverKeyBits = 0; } diff --git a/net/third_party/nss/patches/handshakeshortwrite.patch b/net/third_party/nss/patches/handshakeshortwrite.patch deleted file mode 100644 index cb26d12..0000000 --- a/net/third_party/nss/patches/handshakeshortwrite.patch +++ /dev/null @@ -1,40 +0,0 @@ -From eb24998651cb972c60453b5d5fb1e13dfd8107ce Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:26:44 -0400 -Subject: [PATCH] handshakeshortwrite.patch - ---- - mozilla/security/nss/lib/ssl/sslsecur.c | 13 ++++++++++++- - 1 files changed, 12 insertions(+), 1 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ssl/sslsecur.c -index 816b8f6..dc374e0 100644 ---- a/mozilla/security/nss/lib/ssl/sslsecur.c -+++ b/mozilla/security/nss/lib/ssl/sslsecur.c -@@ -388,6 +388,18 @@ SSL_ForceHandshake(PRFileDesc *fd) - if (!ss->opt.useSecurity) - return SECSuccess; - -+ if (!ssl_SocketIsBlocking(ss)) { -+ ssl_GetXmitBufLock(ss); -+ if (ss->pendingBuf.len != 0) { -+ int sent = ssl_SendSavedWriteData(ss); -+ if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { -+ ssl_ReleaseXmitBufLock(ss); -+ return SECFailure; -+ } -+ } -+ ssl_ReleaseXmitBufLock(ss); -+ } -+ - ssl_Get1stHandshakeLock(ss); - - if (ss->version >= SSL_LIBRARY_VERSION_3_0) { -@@ -1128,7 +1140,6 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) - ssl_ReleaseXmitBufLock(ss); - return SECFailure; - } -- /* XXX short write? */ - } - ssl_ReleaseXmitBufLock(ss); - } diff --git a/net/third_party/nss/patches/nextproto.patch b/net/third_party/nss/patches/nextproto.patch deleted file mode 100644 index 55cac6e..0000000 --- a/net/third_party/nss/patches/nextproto.patch +++ /dev/null @@ -1,592 +0,0 @@ -From 0c2f72b38711abdd4ada08ae8d7e96dce79a672b Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:19:28 -0400 -Subject: [PATCH 01/15] nextproto.patch - ---- - mozilla/security/nss/lib/ssl/ssl.def | 8 ++ - mozilla/security/nss/lib/ssl/ssl.h | 51 ++++++++++++ - mozilla/security/nss/lib/ssl/ssl3con.c | 58 +++++++++++++ - mozilla/security/nss/lib/ssl/ssl3ext.c | 104 ++++++++++++++++++++++++- - mozilla/security/nss/lib/ssl/ssl3prot.h | 3 +- - mozilla/security/nss/lib/ssl/sslerr.h | 2 + - mozilla/security/nss/lib/ssl/sslimpl.h | 21 +++++ - mozilla/security/nss/lib/ssl/sslsock.c | 134 +++++++++++++++++++++++++++++++ - mozilla/security/nss/lib/ssl/sslt.h | 3 +- - 9 files changed, 381 insertions(+), 3 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def -index d3f455c..6ea48c0 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.def -+++ b/mozilla/security/nss/lib/ssl/ssl.def -@@ -152,3 +152,11 @@ SSL_SNISocketConfigHook; - ;+ local: - ;+*; - ;+}; -+;+NSS_CHROMIUM { -+;+ global: -+SSL_GetNextProto; -+SSL_SetNextProtoCallback; -+SSL_SetNextProtoNego; -+;+ local: -+;+*; -+;+}; -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index 4a9e89d..f54eb09 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -153,6 +153,57 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on); - SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); - SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle); - -+/* SSLNextProtoCallback is called, during the handshake, when the server has -+ * sent a Next Protocol Negotiation extension. |protos| and |protosLen| define -+ * a buffer which contains the server's advertisement. This data is guaranteed -+ * to be well formed per the NPN spec. |protoOut| is a buffer provided by the -+ * caller, of length 255 (the maximum allowed by the protocol). -+ * On successful return, the protocol to be announced to the server will be in -+ * |protoOut| and its length in |*protoOutLen|. */ -+typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)( -+ void *arg, -+ PRFileDesc *fd, -+ const unsigned char* protos, -+ unsigned int protosLen, -+ unsigned char* protoOut, -+ unsigned int* protoOutLen); -+ -+/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol -+ * Negotiation. It causes a client to advertise NPN. */ -+SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd, -+ SSLNextProtoCallback callback, -+ void *arg); -+ -+/* SSL_SetNextProtoNego can be used as an alternative to -+ * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and -+ * installs a default callback function which selects the first supported -+ * protocol in server-preference order. If no matching protocol is found it -+ * selects the first supported protocol. -+ * -+ * The supported protocols are specified in |data| in wire-format (8-bit -+ * length-prefixed). For example: "\010http/1.1\006spdy/2". */ -+SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, -+ const unsigned char *data, -+ unsigned int length); -+/* SSL_GetNextProto can be used after a handshake on a socket where -+ * SSL_SetNextProtoNego was called to retrieve the result of the Next Protocol -+ * negotiation. -+ * -+ * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated -+ * protocol, if any, is written into buf, which must be at least buf_len bytes -+ * long. If the negotiated protocol is longer than this, it is truncated. The -+ * number of bytes copied is written into *length. */ -+SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, -+ int *state, -+ unsigned char *buf, -+ unsigned int *length, -+ unsigned int buf_len); -+ -+/* TODO(wtc): it may be a good idea to define these as an enum type. */ -+#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */ -+#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */ -+#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */ -+ - /* - ** Control ciphers that SSL uses. If on is non-zero then the named cipher - ** is enabled, otherwise it is disabled. -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index 8048913..d2d4f91 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss); - static SECStatus ssl3_SendCertificate( sslSocket *ss); - static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); - static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); -+static SECStatus ssl3_SendNextProto( sslSocket *ss); - static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); - static SECStatus ssl3_SendServerHello( sslSocket *ss); - static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); -@@ -5742,6 +5743,16 @@ ssl3_HandleServerHelloDone(sslSocket *ss) - if (rv != SECSuccess) { - goto loser; /* err code was set. */ - } -+ -+ /* We don't send NPN in a renegotiation as it's explicitly disallowed by -+ * the spec. */ -+ if (!ss->firstHsDone) { -+ rv = ssl3_SendNextProto(ss); -+ if (rv != SECSuccess) { -+ goto loser; /* err code was set. */ -+ } -+ } -+ - rv = ssl3_SendFinished(ss, 0); - if (rv != SECSuccess) { - goto loser; /* err code was set. */ -@@ -8169,6 +8180,40 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, - } - - /* called from ssl3_HandleServerHelloDone -+ */ -+static SECStatus -+ssl3_SendNextProto(sslSocket *ss) -+{ -+ SECStatus rv; -+ int padding_len; -+ static const unsigned char padding[32] = {0}; -+ -+ if (ss->ssl3.nextProto.len == 0) -+ return SECSuccess; -+ -+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); -+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); -+ -+ padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); -+ -+ rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + -+ 2 + padding_len); -+ if (rv != SECSuccess) { -+ return rv; /* error code set by AppendHandshakeHeader */ -+ } -+ rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, -+ ss->ssl3.nextProto.len, 1); -+ if (rv != SECSuccess) { -+ return rv; /* error code set by AppendHandshake */ -+ } -+ rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1); -+ if (rv != SECSuccess) { -+ return rv; /* error code set by AppendHandshake */ -+ } -+ return rv; -+} -+ -+/* called from ssl3_HandleServerHelloDone - * ssl3_HandleClientHello - * ssl3_HandleFinished - */ -@@ -8421,6 +8466,14 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, - if (doStepUp || ss->writerThread == PR_GetCurrentThread()) { - flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; - } -+ -+ if (!isServer && !ss->firstHsDone) { -+ rv = ssl3_SendNextProto(ss); -+ if (rv != SECSuccess) { -+ goto xmit_loser; /* err code was set. */ -+ } -+ } -+ - rv = ssl3_SendFinished(ss, flags); - if (rv != SECSuccess) { - goto xmit_loser; /* err is set. */ -@@ -9488,6 +9541,11 @@ ssl3_DestroySSL3Info(sslSocket *ss) - ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/); - - ss->ssl3.initialized = PR_FALSE; -+ -+ if (ss->ssl3.nextProto.data) { -+ PORT_Free(ss->ssl3.nextProto.data); -+ ss->ssl3.nextProto.data = NULL; -+ } - } - - /* End of ssl3con.c */ -diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c -index becbfe9..711cad0 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3ext.c -+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c -@@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { - #endif - { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, -+ { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, - { -1, NULL } - }; - -@@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { - /* TODO: add a handler for ssl_ec_point_formats_xtn */ - { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, -+ { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, - { -1, NULL } - }; - -@@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { - { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, - { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, - #endif -- { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn } -+ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, -+ { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } - /* any extra entries will appear as { 0, NULL } */ - }; - -@@ -534,6 +537,105 @@ ssl3_SendSessionTicketXtn( - return -1; - } - -+/* handle an incoming Next Protocol Negotiation extension. */ -+SECStatus -+ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) -+{ -+ if (data->len != 0) { -+ /* Clients MUST send an empty NPN extension, if any. */ -+ return SECFailure; -+ } -+ -+ return SECSuccess; -+} -+ -+/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none -+ * of the lengths may be 0 and the sum of the lengths must equal the length of -+ * the block. */ -+SECStatus -+ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) -+{ -+ unsigned int offset = 0; -+ -+ while (offset < length) { -+ if (data[offset] == 0) { -+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); -+ return SECFailure; -+ } -+ offset += (unsigned int)data[offset] + 1; -+ } -+ -+ if (offset > length) { -+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); -+ return SECFailure; -+ } -+ -+ return SECSuccess; -+} -+ -+SECStatus -+ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, -+ SECItem *data) -+{ -+ SECStatus rv; -+ unsigned char result[255]; -+ unsigned int result_len; -+ -+ rv = ssl3_ValidateNextProtoNego(data->data, data->len); -+ if (rv != SECSuccess) -+ return rv; -+ -+ rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, -+ data->data, data->len, -+ result, &result_len); -+ if (rv != SECSuccess) -+ return rv; -+ /* If the callback wrote more than allowed to |result| it has corrupted our -+ * stack. */ -+ PORT_Assert(result_len <= sizeof(result)); -+ -+ if (ss->ssl3.nextProto.data) -+ PORT_Free(ss->ssl3.nextProto.data); -+ ss->ssl3.nextProto.data = PORT_Alloc(result_len); -+ PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); -+ ss->ssl3.nextProto.len = result_len; -+ return SECSuccess; -+} -+ -+PRInt32 -+ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, -+ PRBool append, -+ PRUint32 maxBytes) -+{ -+ PRInt32 extension_length; -+ -+ /* Renegotiations do not send this extension. */ -+ if (!ss->nextProtoCallback || ss->firstHsDone) { -+ return 0; -+ } -+ -+ extension_length = 4; -+ -+ if (append && maxBytes >= extension_length) { -+ SECStatus rv; -+ rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); -+ if (rv != SECSuccess) -+ goto loser; -+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2); -+ if (rv != SECSuccess) -+ goto loser; -+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = -+ ssl_next_proto_neg_xtn; -+ } else if (maxBytes < extension_length) { -+ return 0; -+ } -+ -+ return extension_length; -+ -+ loser: -+ return -1; -+} -+ - /* - * NewSessionTicket - * Called from ssl3_HandleFinished -diff --git a/mozilla/security/nss/lib/ssl/ssl3prot.h b/mozilla/security/nss/lib/ssl/ssl3prot.h -index 4702fcc..f3c950e 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3prot.h -+++ b/mozilla/security/nss/lib/ssl/ssl3prot.h -@@ -157,7 +157,8 @@ typedef enum { - server_hello_done = 14, - certificate_verify = 15, - client_key_exchange = 16, -- finished = 20 -+ finished = 20, -+ next_proto = 67 - } SSL3HandshakeType; - - typedef struct { -diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ssl/sslerr.h -index a2f6524..c76ffa9 100644 ---- a/mozilla/security/nss/lib/ssl/sslerr.h -+++ b/mozilla/security/nss/lib/ssl/sslerr.h -@@ -203,6 +203,8 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114), - - SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115), - -+SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 117), -+ - SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ - } SSLErrorCodes; - #endif /* NO_SECURITY_ERROR_ENUM */ -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index 9af471d..199c573 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h -@@ -313,6 +313,10 @@ typedef struct { - #endif /* NSS_ENABLE_ECC */ - - typedef struct sslOptionsStr { -+ /* If SSL_SetNextProtoNego has been called, then this contains the -+ * list of supported protocols. */ -+ SECItem nextProtoNego; -+ - unsigned int useSecurity : 1; /* 1 */ - unsigned int useSocks : 1; /* 2 */ - unsigned int requestCertificate : 1; /* 3 */ -@@ -827,6 +831,13 @@ struct ssl3StateStr { - PRBool initialized; - SSL3HandshakeState hs; - ssl3CipherSpec specs[2]; /* one is current, one is pending. */ -+ -+ /* In a client: if the server supports Next Protocol Negotiation, then -+ * this is the protocol that was negotiated. -+ * -+ * If the data pointer is non-NULL, then it is malloced data. */ -+ SECItem nextProto; -+ int nextProtoState; /* See NEXT_PROTO_* defines */ - }; - - typedef struct { -@@ -1058,6 +1069,8 @@ const unsigned char * preferredCipher; - SSLHandshakeCallback handshakeCallback; - void *handshakeCallbackData; - void *pkcs11PinArg; -+ SSLNextProtoCallback nextProtoCallback; -+ void *nextProtoArg; - - PRIntervalTime rTimeout; /* timeout for NSPR I/O */ - PRIntervalTime wTimeout; /* timeout for NSPR I/O */ -@@ -1494,8 +1507,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket * ss, - PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -+extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, -+ PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -+extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, -+ PRUint16 ex_type, SECItem *data); - - /* ClientHello and ServerHello extension senders. - * Note that not all extension senders are exposed here; only those that -@@ -1526,6 +1543,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, - extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, - PRBool append, PRUint32 maxBytes); - #endif -+extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, -+ PRUint32 maxBytes); -+extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, -+ unsigned short length); - - /* call the registered extension handlers. */ - extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss, -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c -index bc770a1..829103b 100644 ---- a/mozilla/security/nss/lib/ssl/sslsock.c -+++ b/mozilla/security/nss/lib/ssl/sslsock.c -@@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */ - ** default settings for socket enables - */ - static sslOptions ssl_defaults = { -+ { siBuffer, NULL, 0 }, /* nextProtoNego */ - PR_TRUE, /* useSecurity */ - PR_FALSE, /* useSocks */ - PR_FALSE, /* requestCertificate */ -@@ -438,6 +439,10 @@ ssl_DestroySocketContents(sslSocket *ss) - ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); - ss->ephemeralECDHKeyPair = NULL; - } -+ if (ss->opt.nextProtoNego.data) { -+ PORT_Free(ss->opt.nextProtoNego.data); -+ ss->opt.nextProtoNego.data = NULL; -+ } - PORT_Assert(!ss->xtnData.sniNameArr); - if (ss->xtnData.sniNameArr) { - PORT_Free(ss->xtnData.sniNameArr); -@@ -1266,6 +1271,135 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) - return fd; - } - -+SECStatus -+SSL_SetNextProtoCallback(PRFileDesc *fd, -+ SSLNextProtoCallback callback, -+ void *arg) { -+ sslSocket *ss = ssl_FindSocket(fd); -+ -+ if (!ss) { -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID(), -+ fd)); -+ PORT_SetError(SEC_ERROR_INVALID_ARGS); -+ return SECFailure; -+ } -+ -+ ssl_GetSSL3HandshakeLock(ss); -+ ss->nextProtoCallback = callback; -+ ss->nextProtoArg = arg; -+ ssl_ReleaseSSL3HandshakeLock(ss); -+ return SECSuccess; -+} -+ -+/* NextProtoStandardCallback is set as an NPN callback for the case when the -+ * user of the sockets wants the standard selection algorithm. */ -+static SECStatus -+NextProtoStandardCallback(void *arg, -+ PRFileDesc *fd, -+ const unsigned char *protos, -+ unsigned int protos_len, -+ unsigned char *protoOut, -+ unsigned int *protoOutLen) -+{ -+ unsigned int i, j; -+ const unsigned char *result; -+ -+ sslSocket *ss = ssl_FindSocket(fd); -+ PORT_Assert(ss); -+ -+ if (protos_len == 0) { -+ /* The server supports the extension, but doesn't have any protocols -+ * configured. In this case we request our favoured protocol. */ -+ goto pick_first; -+ } -+ -+ /* For each protocol in server preference, see if we support it. */ -+ for (i = 0; i < protos_len; ) { -+ for (j = 0; j < ss->opt.nextProtoNego.len; ) { -+ if (protos[i] == ss->opt.nextProtoNego.data[j] && -+ memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1], -+ protos[i]) == 0) { -+ /* We found a match. */ -+ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; -+ result = &protos[i]; -+ goto found; -+ } -+ j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; -+ } -+ i += (unsigned int)protos[i] + 1; -+ } -+ -+pick_first: -+ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; -+ result = ss->opt.nextProtoNego.data; -+ -+found: -+ memcpy(protoOut, result + 1, result[0]); -+ *protoOutLen = result[0]; -+ return SECSuccess; -+} -+ -+SECStatus -+SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, -+ unsigned int length) -+{ -+ SECStatus rv; -+ -+ sslSocket *ss = ssl_FindSocket(fd); -+ -+ if (!ss) { -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", -+ SSL_GETPID(), fd)); -+ PORT_SetError(SEC_ERROR_INVALID_ARGS); -+ return SECFailure; -+ } -+ -+ if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess) -+ return SECFailure; -+ -+ ssl_GetSSL3HandshakeLock(ss); -+ if (ss->opt.nextProtoNego.data) -+ PORT_Free(ss->opt.nextProtoNego.data); -+ ss->opt.nextProtoNego.data = PORT_Alloc(length); -+ if (!ss->opt.nextProtoNego.data) { -+ ssl_ReleaseSSL3HandshakeLock(ss); -+ return SECFailure; -+ } -+ memcpy(ss->opt.nextProtoNego.data, data, length); -+ ss->opt.nextProtoNego.len = length; -+ ss->opt.nextProtoNego.type = siBuffer; -+ ssl_ReleaseSSL3HandshakeLock(ss); -+ -+ return SSL_SetNextProtoCallback(fd, NextProtoStandardCallback, NULL); -+} -+ -+SECStatus -+SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, -+ unsigned int *length, unsigned int buf_len) -+{ -+ sslSocket *ss = ssl_FindSocket(fd); -+ -+ if (!ss) { -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(), -+ fd)); -+ return SECFailure; -+ } -+ -+ *state = ss->ssl3.nextProtoState; -+ -+ if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && -+ ss->ssl3.nextProto.data) { -+ *length = ss->ssl3.nextProto.len; -+ if (*length > buf_len) -+ *length = buf_len; -+ PORT_Memcpy(buf, ss->ssl3.nextProto.data, *length); -+ } else { -+ *length = 0; -+ } -+ -+ return SECSuccess; -+} -+ - PRFileDesc * - SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) - { -diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h -index c7d4553..f6e0b62 100644 ---- a/mozilla/security/nss/lib/ssl/sslt.h -+++ b/mozilla/security/nss/lib/ssl/sslt.h -@@ -203,9 +203,10 @@ typedef enum { - ssl_ec_point_formats_xtn = 11, - #endif - ssl_session_ticket_xtn = 35, -+ ssl_next_proto_neg_xtn = 13172, - ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ - } SSLExtensionType; - --#define SSL_MAX_EXTENSIONS 5 -+#define SSL_MAX_EXTENSIONS 6 - - #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/patches/ocspstapling.patch b/net/third_party/nss/patches/ocspstapling.patch index 4b342b9..fb6dad3 100644 --- a/net/third_party/nss/patches/ocspstapling.patch +++ b/net/third_party/nss/patches/ocspstapling.patch @@ -1,47 +1,17 @@ -From 5d8c33901f2b1be41afd1b0211bee5d5236a868d Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:21:00 -0400 -Subject: [PATCH] ocspstapling.patch - ---- - mozilla/security/nss/lib/ssl/ssl.def | 1 + - mozilla/security/nss/lib/ssl/ssl.h | 18 +++++ - mozilla/security/nss/lib/ssl/ssl3con.c | 111 +++++++++++++++++++++++++++++++ - mozilla/security/nss/lib/ssl/ssl3ext.c | 78 +++++++++++++++++++++- - mozilla/security/nss/lib/ssl/ssl3prot.h | 1 + - mozilla/security/nss/lib/ssl/sslerr.h | 2 + - mozilla/security/nss/lib/ssl/sslimpl.h | 13 ++++ - mozilla/security/nss/lib/ssl/sslsock.c | 43 ++++++++++++ - mozilla/security/nss/lib/ssl/sslt.h | 3 +- - 9 files changed, 268 insertions(+), 2 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def -index 0fa8777..35cc1e3 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.def -+++ b/mozilla/security/nss/lib/ssl/ssl.def -@@ -155,6 +155,7 @@ SSL_SNISocketConfigHook; - ;+NSS_CHROMIUM { - ;+ global: - SSL_GetNextProto; -+SSL_GetStapledOCSPResponse; - SSL_PeerCertificateChain; - SSL_SetNextProtoNego; - ;+ local: -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index cccb49a..221fe2d 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -139,6 +139,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); - /* occur on RSA or DH ciphersuites where the cipher's key length is >= 80 */ - /* bits. The advantage of False Start is that it saves a round trip for */ - /* client-speaks-first protocols when performing a full handshake. */ -+#define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */ +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-28 18:34:23.263186340 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-28 18:47:14.683775498 -0800 +@@ -167,6 +167,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi + * accept fragmented alerts). + */ + #define SSL_CBC_RANDOM_IV 23 ++#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ -@@ -274,6 +275,23 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd); - SSL_IMPORT SECStatus SSL_PeerCertificateChain( - PRFileDesc *fd, CERTCertificate **certs, unsigned int *certs_size); +@@ -347,6 +348,23 @@ SSL_IMPORT SECStatus SSL_PeerCertificate + PRFileDesc *fd, CERTCertificate **certs, + unsigned int *numCerts, unsigned int maxNumCerts); +/* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by + * the TLS server. The resulting data is copied to |out_data|. On entry, |*len| @@ -63,11 +33,10 @@ index cccb49a..221fe2d 100644 /* ** Authenticate certificate hook. Called when a certificate comes in ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index 9830e65..ca2793f 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -7803,6 +7803,57 @@ ssl3_CopyPeerCertsToSID(ssl3CertNode *certs, sslSessionID *sid) +diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 17:48:46.326209244 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 19:12:51.845953454 -0800 +@@ -7887,6 +7887,57 @@ ssl3_CopyPeerCertsToSID(ssl3CertNode *ce } /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete @@ -125,7 +94,7 @@ index 9830e65..ca2793f 100644 * ssl3 Certificate message. * Caller must hold Handshake and RecvBuf locks. */ -@@ -8605,6 +8656,26 @@ xmit_loser: +@@ -8679,6 +8730,26 @@ ssl3_FinishHandshake(sslSocket * ss) return SECSuccess; } @@ -152,7 +121,7 @@ index 9830e65..ca2793f 100644 /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3 * hanshake message. * Caller must hold Handshake and RecvBuf locks. -@@ -8699,14 +8770,42 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +@@ -8773,14 +8844,42 @@ ssl3_HandleHandshakeMessage(sslSocket *s rv = ssl3_HandleServerHello(ss, b, length); break; case certificate: @@ -195,7 +164,7 @@ index 9830e65..ca2793f 100644 rv = ssl3_HandleServerKeyExchange(ss, b, length); break; case certificate_request: -@@ -8715,6 +8814,9 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +@@ -8789,6 +8888,9 @@ ssl3_HandleHandshakeMessage(sslSocket *s PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST); return SECFailure; } @@ -205,7 +174,7 @@ index 9830e65..ca2793f 100644 rv = ssl3_HandleCertificateRequest(ss, b, length); break; case server_hello_done: -@@ -8728,6 +8830,9 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) +@@ -8802,6 +8904,9 @@ ssl3_HandleHandshakeMessage(sslSocket *s PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); return SECFailure; } @@ -215,7 +184,7 @@ index 9830e65..ca2793f 100644 rv = ssl3_HandleServerHelloDone(ss); break; case certificate_verify: -@@ -9578,6 +9683,12 @@ ssl3_DestroySSL3Info(sslSocket *ss) +@@ -9646,6 +9751,12 @@ ssl3_DestroySSL3Info(sslSocket *ss) ss->ssl3.hs.messages.len = 0; ss->ssl3.hs.messages.space = 0; } @@ -228,29 +197,28 @@ index 9830e65..ca2793f 100644 /* free the SSL3Buffer (msg_body) */ PORT_Free(ss->ssl3.hs.msg_body.buf); -diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c -index fbd5a91..4e3d9cc 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3ext.c -+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c -@@ -247,6 +247,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { +diff -up a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c +--- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-15 13:52:08.000000000 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 19:14:28.617352538 -0800 +@@ -253,6 +253,7 @@ static const ssl3HelloExtensionHandler s { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, { -1, NULL } }; -@@ -270,7 +271,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { +@@ -276,7 +277,8 @@ ssl3HelloExtensionSender clientHelloSend { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, #endif { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, -- { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } -+ { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, +- { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn } ++ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } /* any extra entries will appear as { 0, NULL } */ }; -@@ -654,6 +656,80 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, +@@ -659,6 +661,80 @@ loser: return -1; } @@ -331,10 +299,9 @@ index fbd5a91..4e3d9cc 100644 /* * NewSessionTicket * Called from ssl3_HandleFinished -diff --git a/mozilla/security/nss/lib/ssl/ssl3prot.h b/mozilla/security/nss/lib/ssl/ssl3prot.h -index f3c950e..aeaacdd 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3prot.h -+++ b/mozilla/security/nss/lib/ssl/ssl3prot.h +diff -up a/src/net/third_party/nss/ssl/ssl3prot.h b/src/net/third_party/nss/ssl/ssl3prot.h +--- a/src/net/third_party/nss/ssl/ssl3prot.h 2011-10-28 17:29:11.000000000 -0700 ++++ b/src/net/third_party/nss/ssl/ssl3prot.h 2012-02-28 19:12:51.845953454 -0800 @@ -158,6 +158,7 @@ typedef enum { certificate_verify = 15, client_key_exchange = 16, @@ -343,33 +310,31 @@ index f3c950e..aeaacdd 100644 next_proto = 67 } SSL3HandshakeType; -diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ssl/sslerr.h -index a2f6524..c940f95 100644 ---- a/mozilla/security/nss/lib/ssl/sslerr.h -+++ b/mozilla/security/nss/lib/ssl/sslerr.h -@@ -203,6 +203,8 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114), - - SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115), +diff -up a/src/net/third_party/nss/ssl/sslerr.h b/src/net/third_party/nss/ssl/sslerr.h +--- a/src/net/third_party/nss/ssl/sslerr.h 2012-02-11 04:55:58.000000000 -0800 ++++ b/src/net/third_party/nss/ssl/sslerr.h 2012-02-28 18:58:06.733056235 -0800 +@@ -211,6 +211,8 @@ SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2 + SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS = (SSL_ERROR_BASE + 118), + SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS = (SSL_ERROR_BASE + 119), -+SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 116), ++SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 120), + SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ } SSLErrorCodes; #endif /* NO_SECURITY_ERROR_ENUM */ -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index 48d6d83..8e2bd14 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 17:48:46.326209244 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 19:05:14.299310096 -0800 @@ -339,6 +339,7 @@ typedef struct sslOptionsStr { - unsigned int enableRenegotiation : 2; /* 20-21 */ unsigned int requireSafeNegotiation : 1; /* 22 */ unsigned int enableFalseStart : 1; /* 23 */ -+ unsigned int enableOCSPStapling : 1; /* 24 */ + unsigned int cbcRandomIV : 1; /* 24 */ ++ unsigned int enableOCSPStapling : 1; /* 25 */ } sslOptions; typedef enum { sslHandshakingUndetermined = 0, @@ -782,6 +783,14 @@ const ssl3CipherSuiteDef *suite_def; - * when this one finishes */ + PRBool isResuming; /* are we resuming a session */ PRBool usedStepDownKey; /* we did a server key exchange. */ PRBool sendingSCSV; /* instead of empty RI */ + PRBool may_get_cert_status; /* the server echoed a @@ -383,16 +348,16 @@ index 48d6d83..8e2bd14 100644 sslBuffer msgState; /* current state for handshake messages*/ /* protected by recvBufLock */ sslBuffer messages; /* Accumulated handshake messages */ -@@ -1515,6 +1524,8 @@ extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, +@@ -1527,6 +1536,8 @@ extern SECStatus ssl3_HandleSupportedPoi PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, + extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); +extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, -@@ -1526,6 +1537,8 @@ extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, + +@@ -1536,6 +1547,8 @@ extern SECStatus ssl3_ServerHandleSessio */ extern PRInt32 ssl3_SendSessionTicketXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); @@ -401,20 +366,21 @@ index 48d6d83..8e2bd14 100644 /* ClientHello and ServerHello extension senders. * The code is in ssl3ext.c. -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c -index b7e32a2..4c4df3f 100644 ---- a/mozilla/security/nss/lib/ssl/sslsock.c -+++ b/mozilla/security/nss/lib/ssl/sslsock.c -@@ -185,6 +185,7 @@ static sslOptions ssl_defaults = { +diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 16:15:34.790321976 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 19:12:51.845953454 -0800 +@@ -185,7 +185,8 @@ static sslOptions ssl_defaults = { 2, /* enableRenegotiation (default: requires extension) */ PR_FALSE, /* requireSafeNegotiation */ PR_FALSE, /* enableFalseStart */ +- PR_TRUE /* cbcRandomIV */ ++ PR_TRUE, /* cbcRandomIV */ + PR_FALSE, /* enableOCSPStapling */ }; sslSessionIDLookupFunc ssl_sid_lookup; -@@ -738,6 +739,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) - ss->opt.enableFalseStart = on; +@@ -741,6 +742,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh + ss->opt.cbcRandomIV = on; break; + case SSL_ENABLE_OCSP_STAPLING: @@ -424,26 +390,26 @@ index b7e32a2..4c4df3f 100644 default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; -@@ -802,6 +807,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) - case SSL_REQUIRE_SAFE_NEGOTIATION: +@@ -806,6 +811,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh on = ss->opt.requireSafeNegotiation; break; case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; + case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; + case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -853,6 +859,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) - on = ssl_defaults.requireSafeNegotiation; +@@ -860,6 +866,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBo break; case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break; + case SSL_CBC_RANDOM_IV: on = ssl_defaults.cbcRandomIV; break; + case SSL_ENABLE_OCSP_STAPLING: + on = ssl_defaults.enableOCSPStapling; + break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -1000,6 +1009,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) - ssl_defaults.enableFalseStart = on; +@@ -1019,6 +1028,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo + ssl_defaults.cbcRandomIV = on; break; + case SSL_ENABLE_OCSP_STAPLING: @@ -453,7 +419,7 @@ index b7e32a2..4c4df3f 100644 default: PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; -@@ -1453,6 +1466,36 @@ loser: +@@ -1537,6 +1550,36 @@ loser: #endif } @@ -490,10 +456,9 @@ index b7e32a2..4c4df3f 100644 /************************************************************************/ /* The following functions are the TOP LEVEL SSL functions. ** They all get called through the NSPRIOMethods table below. -diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h -index f6e0b62..917c093 100644 ---- a/mozilla/security/nss/lib/ssl/sslt.h -+++ b/mozilla/security/nss/lib/ssl/sslt.h +diff -up a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/sslt.h +--- a/src/net/third_party/nss/ssl/sslt.h 2012-02-15 13:52:08.000000000 -0800 ++++ b/src/net/third_party/nss/ssl/sslt.h 2012-02-28 19:12:51.845953454 -0800 @@ -198,6 +198,7 @@ typedef enum { /* Update SSL_MAX_EXTENSIONS whenever a new extension type is added. */ typedef enum { diff --git a/net/third_party/nss/patches/origin_bound_certs.patch b/net/third_party/nss/patches/origin_bound_certs.patch index ae0913e..18d60ad 100644 --- a/net/third_party/nss/patches/origin_bound_certs.patch +++ b/net/third_party/nss/patches/origin_bound_certs.patch @@ -1,59 +1,44 @@ -From 68d651bb679cd9da8f162774c5dcf40aad5ae3f1 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:25:10 -0400 -Subject: [PATCH] origin_bound_certs.patch - ---- - mozilla/security/nss/lib/ssl/ssl.h | 1 + - mozilla/security/nss/lib/ssl/ssl3ext.c | 82 +++++++++++++++++++++++++++++++- - mozilla/security/nss/lib/ssl/sslimpl.h | 7 +++ - mozilla/security/nss/lib/ssl/sslsock.c | 13 +++++- - mozilla/security/nss/lib/ssl/sslt.h | 5 +- - 5 files changed, 104 insertions(+), 4 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index c32438d..1115fa9 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -142,6 +142,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); - #define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */ - #define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */ - /* extension, off by default. */ +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 14:41:25.755295547 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 16:45:47.368569394 -0800 +@@ -168,6 +168,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi + */ + #define SSL_CBC_RANDOM_IV 23 + #define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ +#define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */ #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ -diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c -index 17898fb..887344b 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3ext.c -+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c -@@ -237,6 +237,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { +diff -up a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c +--- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 20:34:50.114663722 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-29 17:05:21.684414824 -0800 +@@ -242,6 +242,7 @@ static const ssl3HelloExtensionHandler c + { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, + { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, { -1, NULL } }; -@@ -250,6 +251,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { - { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn }, +@@ -254,6 +255,7 @@ static const ssl3HelloExtensionHandler s + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, + { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, { -1, NULL } }; -@@ -275,7 +277,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { +@@ -278,7 +280,8 @@ ssl3HelloExtensionSender clientHelloSend + #endif { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, - { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, + { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } /* any extra entries will appear as { 0, NULL } */ }; -@@ -1973,3 +1976,80 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +@@ -1723,3 +1726,80 @@ ssl3_HandleRenegotiationInfoXtn(sslSocke return rv; } @@ -134,19 +119,18 @@ index 17898fb..887344b 100644 + + return SECSuccess; +} -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index f1e9a3e..973a3c9 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h -@@ -341,6 +341,7 @@ typedef struct sslOptionsStr { +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 20:34:50.114663722 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 16:57:21.097919853 -0800 +@@ -349,6 +349,7 @@ typedef struct sslOptionsStr { unsigned int enableFalseStart : 1; /* 23 */ - unsigned int enableOCSPStapling : 1; /* 24 */ - unsigned int enableCachedInfo : 1; /* 25 */ + unsigned int cbcRandomIV : 1; /* 24 */ + unsigned int enableOCSPStapling : 1; /* 25 */ + unsigned int enableOBCerts : 1; /* 26 */ } sslOptions; typedef enum { sslHandshakingUndetermined = 0, -@@ -1547,10 +1548,14 @@ extern SECStatus ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, +@@ -1563,8 +1564,12 @@ extern SECStatus ssl3_ClientHandleSessio PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); @@ -154,36 +138,33 @@ index f1e9a3e..973a3c9 100644 + PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); - extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); +extern SECStatus ssl3_ServerHandleOBCertXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); /* ClientHello and ServerHello extension senders. * Note that not all extension senders are exposed here; only those that -@@ -1570,6 +1575,8 @@ extern PRInt32 ssl3_ClientSendCachedInfoXtn(sslSocket *ss, PRBool append, +@@ -1580,6 +1585,8 @@ extern PRInt32 ssl3_ClientSendStatusRequ + */ + extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); - extern PRInt32 ssl3_ServerSendCachedInfoXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); +extern PRInt32 ssl3_SendOBCertXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); /* Assigns new cert, cert chain and keys to ss->serverCerts * struct. If certChain is NULL, tries to find one. Aborts if -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c -index 11b53da..7d12bfe 100644 ---- a/mozilla/security/nss/lib/ssl/sslsock.c -+++ b/mozilla/security/nss/lib/ssl/sslsock.c +diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 14:41:25.755295547 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:03:16.272715683 -0800 @@ -187,6 +187,7 @@ static sslOptions ssl_defaults = { PR_FALSE, /* enableFalseStart */ + PR_TRUE, /* cbcRandomIV */ PR_FALSE, /* enableOCSPStapling */ - PR_FALSE, /* enableCachedInfo */ + PR_FALSE, /* enableOBCerts */ }; sslSessionIDLookupFunc ssl_sid_lookup; -@@ -748,6 +749,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) - ss->opt.enableCachedInfo = on; +@@ -750,6 +751,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh + ss->opt.enableOCSPStapling = on; break; + case SSL_ENABLE_OB_CERTS: @@ -193,26 +174,24 @@ index 11b53da..7d12bfe 100644 default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; -@@ -813,7 +818,8 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) - on = ss->opt.requireSafeNegotiation; break; +@@ -816,6 +821,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; + case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; -- case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break; -+ case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break; + case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -869,6 +875,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) +@@ -873,6 +879,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBo + case SSL_ENABLE_OCSP_STAPLING: on = ssl_defaults.enableOCSPStapling; break; - case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break; + case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); -@@ -1024,6 +1031,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) - ssl_defaults.enableCachedInfo = on; +@@ -1036,6 +1043,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo + ssl_defaults.enableOCSPStapling = on; break; + case SSL_ENABLE_OB_CERTS: @@ -222,20 +201,19 @@ index 11b53da..7d12bfe 100644 default: PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; -diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h -index bca7496..5f852fe 100644 ---- a/mozilla/security/nss/lib/ssl/sslt.h -+++ b/mozilla/security/nss/lib/ssl/sslt.h -@@ -206,9 +206,10 @@ typedef enum { +diff -up a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/sslt.h +--- a/src/net/third_party/nss/ssl/sslt.h 2012-02-28 19:26:04.057351342 -0800 ++++ b/src/net/third_party/nss/ssl/sslt.h 2012-02-29 17:05:03.744171015 -0800 +@@ -205,9 +205,10 @@ typedef enum { + #endif ssl_session_ticket_xtn = 35, - ssl_next_proto_neg_xtn = 13172, - ssl_cached_info_xtn = 13173, + ssl_next_proto_nego_xtn = 13172, - ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ + ssl_renegotiation_info_xtn = 0xff01, /* experimental number */ + ssl_ob_cert_xtn = 13175 /* experimental number */ } SSLExtensionType; --#define SSL_MAX_EXTENSIONS 8 -+#define SSL_MAX_EXTENSIONS 9 +-#define SSL_MAX_EXTENSIONS 7 ++#define SSL_MAX_EXTENSIONS 8 #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/patches/peercertchain.patch b/net/third_party/nss/patches/peercertchain.patch index 4615ba7..4a3966a 100644 --- a/net/third_party/nss/patches/peercertchain.patch +++ b/net/third_party/nss/patches/peercertchain.patch @@ -1,62 +1,60 @@ -From 40714671513378227413d1542c2911c2f62e3840 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:20:43 -0400 -Subject: [PATCH] peercertchain.patch - ---- - mozilla/security/nss/lib/ssl/ssl.def | 1 + - mozilla/security/nss/lib/ssl/ssl.h | 11 +++++++++ - mozilla/security/nss/lib/ssl/sslauth.c | 36 ++++++++++++++++++++++++++++++++ - 3 files changed, 48 insertions(+), 0 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def -index a1f4b51..0fa8777 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.def -+++ b/mozilla/security/nss/lib/ssl/ssl.def -@@ -155,6 +155,7 @@ SSL_SNISocketConfigHook; - ;+NSS_CHROMIUM { - ;+ global: - SSL_GetNextProto; -+SSL_PeerCertificateChain; - SSL_SetNextProtoNego; - ;+ local: - ;+*; -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index ffa973c..cccb49a 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -264,6 +264,17 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher, +Index: mozilla/security/nss/lib/ssl/ssl.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v +retrieving revision 1.49 +diff -u -p -8 -r1.49 ssl.h +--- mozilla/security/nss/lib/ssl/ssl.h 15 Feb 2012 21:52:08 -0000 1.49 ++++ mozilla/security/nss/lib/ssl/ssl.h 29 Feb 2012 02:12:05 -0000 +@@ -331,16 +331,28 @@ SSL_IMPORT SECStatus SSL_SecurityStatus( + ** it will always return the server's certificate. If the server calls + ** this, it may return NULL if client authentication is not enabled or + ** if the client had no certificate when asked. + ** "fd" the socket "file" descriptor + */ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd); /* -+** Return references to the certificates presented by the SSL peer. On entry, -+** |*certs_size| must contain the size of the |certs| array. On successful -+** return, |*certs_size| contains the number of certificates available and ++** Return references to the certificates presented by the SSL peer. ++** |maxNumCerts| must contain the size of the |certs| array. On successful ++** return, |*numCerts| contains the number of certificates available and +** |certs| will contain references to as many certificates as would fit. -+** Therefore if, on exit, |*certs_size| contains a value less than, or equal to, -+** the entry value then all certificates were returned. ++** Therefore if |*numCerts| contains a value less than or equal to ++** |maxNumCerts|, then all certificates were returned. +*/ +SSL_IMPORT SECStatus SSL_PeerCertificateChain( -+ PRFileDesc *fd, CERTCertificate **certs, unsigned int *certs_size); ++ PRFileDesc *fd, CERTCertificate **certs, ++ unsigned int *numCerts, unsigned int maxNumCerts); + +/* ** Authenticate certificate hook. Called when a certificate comes in ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the ** certificate. -diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/ssl/sslauth.c -index 6d1eab0..df40f30 100644 ---- a/mozilla/security/nss/lib/ssl/sslauth.c -+++ b/mozilla/security/nss/lib/ssl/sslauth.c -@@ -60,6 +60,42 @@ SSL_PeerCertificate(PRFileDesc *fd) + ** + ** The authenticate certificate hook must return SECSuccess to indicate the + ** certificate is valid, SECFailure to indicate the certificate is invalid, + ** or SECWouldBlock if the application will authenticate the certificate + ** asynchronously. SECWouldBlock is only supported for non-blocking sockets. +Index: mozilla/security/nss/lib/ssl/sslauth.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslauth.c,v +retrieving revision 1.17 +diff -u -p -8 -r1.17 sslauth.c +--- mozilla/security/nss/lib/ssl/sslauth.c 3 Aug 2010 18:48:45 -0000 1.17 ++++ mozilla/security/nss/lib/ssl/sslauth.c 29 Feb 2012 02:12:05 -0000 +@@ -55,16 +55,51 @@ SSL_PeerCertificate(PRFileDesc *fd) + } + if (ss->opt.useSecurity && ss->sec.peerCert) { + return CERT_DupCertificate(ss->sec.peerCert); + } + return 0; } /* NEED LOCKS IN HERE. */ +SECStatus +SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs, -+ unsigned int *certsSize) ++ unsigned int *numCerts, unsigned int maxNumCerts) +{ + sslSocket *ss; -+ unsigned int inSize = *certsSize; + ssl3CertNode* cur; + + ss = ssl_FindSocket(fd); @@ -69,18 +67,18 @@ index 6d1eab0..df40f30 100644 + return SECFailure; + + if (ss->sec.peerCert == NULL) { -+ *certsSize = 0; ++ *numCerts = 0; + return SECSuccess; + } + -+ *certsSize = 1; /* for the leaf certificate */ -+ if (inSize > 0) ++ *numCerts = 1; /* for the leaf certificate */ ++ if (maxNumCerts > 0) + certs[0] = CERT_DupCertificate(ss->sec.peerCert); + + for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { -+ if (*certsSize < inSize) -+ certs[*certsSize] = CERT_DupCertificate(cur->cert); -+ (*certsSize)++; ++ if (*numCerts < maxNumCerts) ++ certs[*numCerts] = CERT_DupCertificate(cur->cert); ++ (*numCerts)++; + } + + return SECSuccess; @@ -90,3 +88,8 @@ index 6d1eab0..df40f30 100644 CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd) { + sslSocket *ss; + + ss = ssl_FindSocket(fd); + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", diff --git a/net/third_party/nss/patches/restartclientauth.patch b/net/third_party/nss/patches/restartclientauth.patch index f90825c..098e401 100644 --- a/net/third_party/nss/patches/restartclientauth.patch +++ b/net/third_party/nss/patches/restartclientauth.patch @@ -1,20 +1,7 @@ -From 3c9aa423a3e721fc2223dc5f64d21cc5b4898d4e Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:27:03 -0400 -Subject: [PATCH] restartclientauth.patch - ---- - mozilla/security/nss/lib/ssl/ssl.h | 5 ++ - mozilla/security/nss/lib/ssl/ssl3con.c | 70 +++++++++++++++++++++---------- - mozilla/security/nss/lib/ssl/sslimpl.h | 4 -- - mozilla/security/nss/lib/ssl/sslsecur.c | 35 ++++++++++++--- - 4 files changed, 80 insertions(+), 34 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index 835d3cf..7e748bd 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -236,6 +236,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd); +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:49:08.431530583 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 19:07:19.298439815 -0800 +@@ -306,6 +306,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake( SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, PRIntervalTime timeout); @@ -26,50 +13,48 @@ index 835d3cf..7e748bd 100644 /* ** Query security status of socket. *on is set to one if security is ** enabled. *keySize will contain the stream key size used. *issuer will -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index f8838d6..d372ee2 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -5667,9 +5667,10 @@ done: - * reference count. The caller should drop its reference - * without calling CERT_DestroyCert after calling this function. - * -- * key Private key associated with cert. This function makes a -- * copy of the private key, so the caller remains responsible -- * for destroying its copy after this function returns. +diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:49:08.431530583 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 18:55:27.038466043 -0800 +@@ -5769,6 +5769,84 @@ done: + return rv; + } + ++/* ++ * attempt to restart the handshake after asynchronously handling ++ * a request for the client's certificate. ++ * ++ * inputs: ++ * cert Client cert chosen by application. ++ * Note: ssl takes this reference, and does not bump the ++ * reference count. The caller should drop its reference ++ * without calling CERT_DestroyCert after calling this function. ++ * + * key Private key associated with cert. This function takes + * ownership of the private key, so the caller should drop its + * reference without destroying the private key after this + * function returns. - * - * certChain DER-encoded certs, client cert and its signers. - * Note: ssl takes this reference, and does not copy the chain. -@@ -5689,27 +5690,50 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, - SECKEYPrivateKey * key, - CERTCertificateList *certChain) - { -- SECStatus rv = SECSuccess; -+ SECStatus rv = SECFailure; - -- if (MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0)) { -- /* XXX This code only works on the initial handshake on a connection, -- ** XXX It does not work on a subsequent handshake (redo). -- */ -- if (ss->handshake != 0) { -- ss->handshake = ssl_GatherRecord1stHandshake; -- ss->ssl3.clientCertificate = cert; -- ss->ssl3.clientCertChain = certChain; -- if (key == NULL) { -- (void)SSL3_SendAlert(ss, alert_warning, no_certificate); -- ss->ssl3.clientPrivateKey = NULL; -- } else { -- ss->ssl3.clientPrivateKey = SECKEY_CopyPrivateKey(key); -- } -- ssl_GetRecvBufLock(ss); -- if (ss->ssl3.hs.msgState.buf != NULL) { -- rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); -- } -- ssl_ReleaseRecvBufLock(ss); ++ * ++ * certChain DER-encoded certs, client cert and its signers. ++ * Note: ssl takes this reference, and does not copy the chain. ++ * The caller should drop its reference without destroying the ++ * chain. SSL will free the chain when it is done with it. ++ * ++ * Return value: XXX ++ * ++ * XXX This code only works on the initial handshake on a connection, XXX ++ * It does not work on a subsequent handshake (redo). ++ * ++ * Caller holds 1stHandshakeLock. ++ */ ++SECStatus ++ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, ++ CERTCertificate * cert, ++ SECKEYPrivateKey * key, ++ CERTCertificateList *certChain) ++{ ++ SECStatus rv = SECSuccess; ++ + /* XXX This code only works on the initial handshake on a connection, + ** XXX It does not work on a subsequent handshake (redo). + */ @@ -98,11 +83,6 @@ index f8838d6..d372ee2 100644 + (void)SSL3_SendAlert(ss, alert_warning, no_certificate); + } + } -+ ssl_GetRecvBufLock(ss); -+ if (ss->ssl3.hs.msgState.buf != NULL) { -+ rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); -+ } -+ ssl_ReleaseRecvBufLock(ss); + } else { + if (cert) { + CERT_DestroyCertificate(cert); @@ -112,17 +92,22 @@ index f8838d6..d372ee2 100644 + } + if (certChain) { + CERT_DestroyCertificateList(certChain); - } - } - return rv; -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index 906874a..70ff4c3 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h -@@ -1356,10 +1356,6 @@ extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, ++ } ++ rv = SECFailure; ++ } ++ return rv; ++} ++ + PRBool + ssl3_CanFalseStart(sslSocket *ss) { + PRBool rv; +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:49:08.431530583 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 19:05:27.766882356 -0800 +@@ -1392,15 +1392,16 @@ extern SECStatus ssl3_MasterKeyDeriveBy + /* These functions are called from secnav, even though they're "private". */ extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error); - extern int SSL_RestartHandshakeAfterServerCert(struct sslSocketStr *ss); -extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss, - CERTCertificate *cert, - SECKEYPrivateKey *key, @@ -130,31 +115,50 @@ index 906874a..70ff4c3 100644 extern sslSocket *ssl_FindSocket(PRFileDesc *fd); extern void ssl_FreeSocket(struct sslSocketStr *ssl); extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, -diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ssl/sslsecur.c -index dc374e0..bb5f0eb 100644 ---- a/mozilla/security/nss/lib/ssl/sslsecur.c -+++ b/mozilla/security/nss/lib/ssl/sslsecur.c -@@ -1460,11 +1460,13 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) - * cert Client cert chosen by application. - * Note: ssl takes this reference, and does not bump the - * reference count. The caller should drop its reference -- * without calling CERT_DestroyCert after calling this function. + SSL3AlertDescription desc); + ++extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, ++ CERTCertificate * cert, ++ SECKEYPrivateKey * key, ++ CERTCertificateList *certChain); ++ + extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error); + + /* +diff -up a/src/net/third_party/nss/ssl/sslsecur.c b/src/net/third_party/nss/ssl/sslsecur.c +--- a/src/net/third_party/nss/ssl/sslsecur.c 2012-02-28 16:15:34.790321976 -0800 ++++ b/src/net/third_party/nss/ssl/sslsecur.c 2012-02-29 19:01:32.303586125 -0800 +@@ -1468,17 +1468,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT + return SECSuccess; + } + +-/* DO NOT USE. This function was exported in ssl.def with the wrong signature; +- * this implementation exists to maintain link-time compatibility. ++/* ++ * attempt to restart the handshake after asynchronously handling ++ * a request for the client's certificate. ++ * ++ * inputs: ++ * cert Client cert chosen by application. ++ * Note: ssl takes this reference, and does not bump the ++ * reference count. The caller should drop its reference + * without calling CERT_DestroyCertificate after calling this + * function. - * -- * key Private key associated with cert. This function makes a -- * copy of the private key, so the caller remains responsible -- * for destroying its copy after this function returns. ++ * + * key Private key associated with cert. This function takes + * ownership of the private key, so the caller should drop its + * reference without destroying the private key after this + * function returns. - * - * certChain Chain of signers for cert. - * Note: ssl takes this reference, and does not copy the chain. -@@ -1476,19 +1478,38 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) - * XXX This code only works on the initial handshake on a connection, XXX - * It does not work on a subsequent handshake (redo). ++ * ++ * certChain Chain of signers for cert. ++ * Note: ssl takes this reference, and does not copy the chain. ++ * The caller should drop its reference without destroying the ++ * chain. SSL will free the chain when it is done with it. ++ * ++ * Return value: XXX ++ * ++ * XXX This code only works on the initial handshake on a connection, XXX ++ * It does not work on a subsequent handshake (redo). */ -int -SSL_RestartHandshakeAfterCertReq(sslSocket * ss, @@ -164,7 +168,8 @@ index dc374e0..bb5f0eb 100644 SECKEYPrivateKey * key, CERTCertificateList *certChain) { -- int ret; +- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); +- return -1; + sslSocket * ss = ssl_FindSocket(fd); + SECStatus ret; + @@ -182,15 +187,21 @@ index dc374e0..bb5f0eb 100644 + } + return SECFailure; + } - - ssl_Get1stHandshakeLock(ss); /************************************/ - - if (ss->version >= SSL_LIBRARY_VERSION_3_0) { - ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); - } else { ++ ++ ssl_Get1stHandshakeLock(ss); /************************************/ ++ ++ if (ss->version >= SSL_LIBRARY_VERSION_3_0) { ++ ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); ++ } else { + if (certChain != NULL) { + CERT_DestroyCertificateList(certChain); + } - ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key); - } ++ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); ++ ret = SECFailure; ++ } ++ ++ ssl_Release1stHandshakeLock(ss); /************************************/ ++ return ret; + } + /* DO NOT USE. This function was exported in ssl.def with the wrong signature; diff --git a/net/third_party/nss/patches/secret_exporter.patch b/net/third_party/nss/patches/secret_exporter.patch index c6dc0e4..10f1776 100644 --- a/net/third_party/nss/patches/secret_exporter.patch +++ b/net/third_party/nss/patches/secret_exporter.patch @@ -1,33 +1,7 @@ -From a30a1a87579d0a0d2950ee685a41bae428f38284 Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Mon, 3 Oct 2011 12:25:44 -0400 -Subject: [PATCH] secret_exporter.patch - ---- - mozilla/security/nss/lib/ssl/ssl.def | 1 + - mozilla/security/nss/lib/ssl/ssl.h | 13 ++++++ - mozilla/security/nss/lib/ssl/ssl3con.c | 63 ++++++++++++++++++++----------- - mozilla/security/nss/lib/ssl/sslimpl.h | 6 +++ - mozilla/security/nss/lib/ssl/sslinfo.c | 64 ++++++++++++++++++++++++++++++++ - 5 files changed, 125 insertions(+), 22 deletions(-) - -diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def -index 7ef15db..1993d3e 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.def -+++ b/mozilla/security/nss/lib/ssl/ssl.def -@@ -154,6 +154,7 @@ SSL_SNISocketConfigHook; - ;+}; - ;+NSS_CHROMIUM { - ;+ global: -+SSL_ExportKeyingMaterial; - SSL_GetNextProto; - SSL_GetStapledOCSPResponse; - SSL_HandshakeResumedSession; -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h -index 1115fa9..835d3cf 100644 ---- a/mozilla/security/nss/lib/ssl/ssl.h -+++ b/mozilla/security/nss/lib/ssl/ssl.h -@@ -653,6 +653,19 @@ SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:12:15.720044263 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:18:04.824794558 -0800 +@@ -774,6 +774,19 @@ SSL_IMPORT SECStatus SSL_GetCipherSuiteI /* Returnes negotiated through SNI host info. */ SSL_IMPORT SECItem *SSL_GetNegotiatedHostInfo(PRFileDesc *fd); @@ -47,11 +21,10 @@ index 1115fa9..835d3cf 100644 /* ** Return a new reference to the certificate that was most recently sent ** to the peer on this SSL/TLS connection, or NULL if none has been sent. -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c -index 2648cbe..f8838d6 100644 ---- a/mozilla/security/nss/lib/ssl/ssl3con.c -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c -@@ -8371,33 +8371,33 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss) +diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 20:34:50.114663722 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:18:04.824794558 -0800 +@@ -8368,33 +8368,33 @@ done: return rv; } @@ -101,7 +74,7 @@ index 2648cbe..f8838d6 100644 PK11_DestroyContext(prf_context, PR_TRUE); } else { -@@ -8406,17 +8406,36 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, +@@ -8403,17 +8403,36 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec * SECItem outData = { siBuffer, }; PRBool isFIPS = PR_FALSE; @@ -144,11 +117,10 @@ index 2648cbe..f8838d6 100644 /* called from ssl3_HandleServerHelloDone */ static SECStatus -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h -index 973a3c9..906874a 100644 ---- a/mozilla/security/nss/lib/ssl/sslimpl.h -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h -@@ -1680,6 +1680,12 @@ SECStatus SSL_DisableDefaultExportCipherSuites(void); +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:12:15.720044263 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:16:59.143900589 -0800 +@@ -1709,6 +1709,11 @@ SECStatus SSL_DisableDefaultExportCipher SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite); @@ -157,14 +129,12 @@ index 973a3c9..906874a 100644 + unsigned int labelLen, const unsigned char *val, + unsigned int valLen, unsigned char *out, + unsigned int outLen); -+ - /********************** FNV hash *********************/ - void FNV1A64_Init(PRUint64 *digest); -diff --git a/mozilla/security/nss/lib/ssl/sslinfo.c b/mozilla/security/nss/lib/ssl/sslinfo.c -index 96377b0..cf870c7 100644 ---- a/mozilla/security/nss/lib/ssl/sslinfo.c -+++ b/mozilla/security/nss/lib/ssl/sslinfo.c + #ifdef TRACE + #define SSL_TRACE(msg) ssl_Trace msg +diff -up a/src/net/third_party/nss/ssl/sslinfo.c b/src/net/third_party/nss/ssl/sslinfo.c +--- a/src/net/third_party/nss/ssl/sslinfo.c 2010-09-01 18:12:57.000000000 -0700 ++++ b/src/net/third_party/nss/ssl/sslinfo.c 2012-02-29 17:18:04.824794558 -0800 @@ -20,6 +20,7 @@ * * Contributor(s): @@ -173,7 +143,7 @@ index 96377b0..cf870c7 100644 * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or -@@ -316,6 +317,69 @@ SSL_IsExportCipherSuite(PRUint16 cipherSuite) +@@ -316,6 +317,69 @@ SSL_IsExportCipherSuite(PRUint16 cipherS return PR_FALSE; } diff --git a/net/third_party/nss/ssl.gyp b/net/third_party/nss/ssl.gyp index ada0bf0..8694d40 100644 --- a/net/third_party/nss/ssl.gyp +++ b/net/third_party/nss/ssl.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -27,7 +27,6 @@ 'ssl/authcert.c', 'ssl/cmpcert.c', 'ssl/derive.c', - 'ssl/fnv1a64.c', 'ssl/nsskea.c', 'ssl/os2_err.c', 'ssl/os2_err.h', @@ -45,9 +44,12 @@ 'ssl/sslenum.c', 'ssl/sslerr.c', 'ssl/sslerr.h', + 'ssl/SSLerrs.h', + 'ssl/sslerrstrs.c', 'ssl/sslgathr.c', 'ssl/sslimpl.h', 'ssl/sslinfo.c', + 'ssl/sslinit.c', 'ssl/sslmutex.c', 'ssl/sslmutex.h', 'ssl/sslnonce.c', diff --git a/net/third_party/nss/ssl/SSLerrs.h b/net/third_party/nss/ssl/SSLerrs.h new file mode 100644 index 0000000..be25978 --- /dev/null +++ b/net/third_party/nss/ssl/SSLerrs.h @@ -0,0 +1,419 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* SSL-specific security error codes */ +/* caller must include "sslerr.h" */ + +ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0, +"Unable to communicate securely. Peer does not support high-grade encryption.") + +ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1, +"Unable to communicate securely. Peer requires high-grade encryption which is not supported.") + +ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2, +"Cannot communicate securely with peer: no common encryption algorithm(s).") + +ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3, +"Unable to find the certificate or key necessary for authentication.") + +ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4, +"Unable to communicate securely with peer: peers's certificate was rejected.") + +ER3(SSL_ERROR_UNUSED_5, SSL_ERROR_BASE + 5, +"Unrecognized SSL error code.") + +ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6, +"The server has encountered bad data from the client.") + +ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7, +"The client has encountered bad data from the server.") + +ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8, +"Unsupported certificate type.") + +ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9, +"Peer using unsupported version of security protocol.") + +ER3(SSL_ERROR_UNUSED_10, SSL_ERROR_BASE + 10, +"Unrecognized SSL error code.") + +ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11, +"Client authentication failed: private key in key database does not match public key in certificate database.") + +ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12, +"Unable to communicate securely with peer: requested domain name does not match the server's certificate.") + +ER3(SSL_ERROR_POST_WARNING, SSL_ERROR_BASE + 13, +"Unrecognized SSL error code.") + +ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14), +"Peer only supports SSL version 2, which is locally disabled.") + + +ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15), +"SSL received a record with an incorrect Message Authentication Code.") + +ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16), +"SSL peer reports incorrect Message Authentication Code.") + +ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17), +"SSL peer cannot verify your certificate.") + +ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18), +"SSL peer rejected your certificate as revoked.") + +ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19), +"SSL peer rejected your certificate as expired.") + +ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20), +"Cannot connect: SSL is disabled.") + +ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21), +"Cannot connect: SSL peer is in another FORTEZZA domain.") + +ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22), +"An unknown SSL cipher suite has been requested.") + +ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23), +"No cipher suites are present and enabled in this program.") + +ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24), +"SSL received a record with bad block padding.") + +ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25), +"SSL received a record that exceeded the maximum permissible length.") + +ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26), +"SSL attempted to send a record that exceeded the maximum permissible length.") + +/* + * Received a malformed (too long or short or invalid content) SSL handshake. + */ +ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27), +"SSL received a malformed Hello Request handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28), +"SSL received a malformed Client Hello handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29), +"SSL received a malformed Server Hello handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30), +"SSL received a malformed Certificate handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31), +"SSL received a malformed Server Key Exchange handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32), +"SSL received a malformed Certificate Request handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33), +"SSL received a malformed Server Hello Done handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34), +"SSL received a malformed Certificate Verify handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35), +"SSL received a malformed Client Key Exchange handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36), +"SSL received a malformed Finished handshake message.") + +/* + * Received a malformed (too long or short) SSL record. + */ +ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37), +"SSL received a malformed Change Cipher Spec record.") + +ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38), +"SSL received a malformed Alert record.") + +ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39), +"SSL received a malformed Handshake record.") + +ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40), +"SSL received a malformed Application Data record.") + +/* + * Received an SSL handshake that was inappropriate for the state we're in. + * E.g. Server received message from server, or wrong state in state machine. + */ +ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41), +"SSL received an unexpected Hello Request handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42), +"SSL received an unexpected Client Hello handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43), +"SSL received an unexpected Server Hello handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44), +"SSL received an unexpected Certificate handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45), +"SSL received an unexpected Server Key Exchange handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46), +"SSL received an unexpected Certificate Request handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47), +"SSL received an unexpected Server Hello Done handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48), +"SSL received an unexpected Certificate Verify handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49), +"SSL received an unexpected Client Key Exchange handshake message.") + +ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50), +"SSL received an unexpected Finished handshake message.") + +/* + * Received an SSL record that was inappropriate for the state we're in. + */ +ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51), +"SSL received an unexpected Change Cipher Spec record.") + +ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52), +"SSL received an unexpected Alert record.") + +ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53), +"SSL received an unexpected Handshake record.") + +ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54), +"SSL received an unexpected Application Data record.") + +/* + * Received record/message with unknown discriminant. + */ +ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55), +"SSL received a record with an unknown content type.") + +ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56), +"SSL received a handshake message with an unknown message type.") + +ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57), +"SSL received an alert record with an unknown alert description.") + +/* + * Received an alert reporting what we did wrong. (more alerts above) + */ +ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58), +"SSL peer has closed this connection.") + +ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59), +"SSL peer was not expecting a handshake message it received.") + +ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60), +"SSL peer was unable to successfully decompress an SSL record it received.") + +ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61), +"SSL peer was unable to negotiate an acceptable set of security parameters.") + +ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62), +"SSL peer rejected a handshake message for unacceptable content.") + +ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63), +"SSL peer does not support certificates of the type it received.") + +ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64), +"SSL peer had some unspecified issue with the certificate it received.") + + +ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65), +"SSL experienced a failure of its random number generator.") + +ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66), +"Unable to digitally sign data required to verify your certificate.") + +ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67), +"SSL was unable to extract the public key from the peer's certificate.") + +ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68), +"Unspecified failure while processing SSL Server Key Exchange handshake.") + +ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69), +"Unspecified failure while processing SSL Client Key Exchange handshake.") + +ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70), +"Bulk data encryption algorithm failed in selected cipher suite.") + +ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71), +"Bulk data decryption algorithm failed in selected cipher suite.") + +ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72), +"Attempt to write encrypted data to underlying socket failed.") + +ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73), +"MD5 digest function failed.") + +ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74), +"SHA-1 digest function failed.") + +ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75), +"MAC computation failed.") + +ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76), +"Failure to create Symmetric Key context.") + +ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77), +"Failure to unwrap the Symmetric key in Client Key Exchange message.") + +ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78), +"SSL Server attempted to use domestic-grade public key with export cipher suite.") + +ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79), +"PKCS11 code failed to translate an IV into a param.") + +ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80), +"Failed to initialize the selected cipher suite.") + +ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81), +"Client failed to generate session keys for SSL session.") + +ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82), +"Server has no key for the attempted key exchange algorithm.") + +ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83), +"PKCS#11 token was inserted or removed while operation was in progress.") + +ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84), +"No PKCS#11 token could be found to do a required operation.") + +ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85), +"Cannot communicate securely with peer: no common compression algorithm(s).") + +ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86), +"Cannot initiate another SSL handshake until current handshake is complete.") + +ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87), +"Received incorrect handshakes hash values from peer.") + +ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88), +"The certificate provided cannot be used with the selected key exchange algorithm.") + +ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89), +"No certificate authority is trusted for SSL client authentication.") + +ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90), +"Client's SSL session ID not found in server's session cache.") + +ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91), +"Peer was unable to decrypt an SSL record it received.") + +ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92), +"Peer received an SSL record that was longer than is permitted.") + +ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93), +"Peer does not recognize and trust the CA that issued your certificate.") + +ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94), +"Peer received a valid certificate, but access was denied.") + +ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95), +"Peer could not decode an SSL handshake message.") + +ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96), +"Peer reports failure of signature verification or key exchange.") + +ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97), +"Peer reports negotiation not in compliance with export regulations.") + +ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98), +"Peer reports incompatible or unsupported protocol version.") + +ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99), +"Server requires ciphers more secure than those supported by client.") + +ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100), +"Peer reports it experienced an internal error.") + +ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101), +"Peer user canceled handshake.") + +ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102), +"Peer does not permit renegotiation of SSL security parameters.") + +ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103), +"SSL server cache not configured and not disabled for this socket.") + +ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104), +"SSL peer does not support requested TLS hello extension.") + +ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105), +"SSL peer could not obtain your certificate from the supplied URL.") + +ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106), +"SSL peer has no certificate for the requested DNS name.") + +ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107), +"SSL peer was unable to get an OCSP response for its certificate.") + +ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108), +"SSL peer reported bad certificate hash value.") + +ER3(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 109), +"SSL received an unexpected New Session Ticket handshake message.") + +ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110), +"SSL received a malformed New Session Ticket handshake message.") + +ER3(SSL_ERROR_DECOMPRESSION_FAILURE, (SSL_ERROR_BASE + 111), +"SSL received a compressed record that could not be decompressed.") + +ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, (SSL_ERROR_BASE + 112), +"Renegotiation is not allowed on this SSL socket.") + +ER3(SSL_ERROR_UNSAFE_NEGOTIATION, (SSL_ERROR_BASE + 113), +"Peer attempted old style (potentially vulnerable) handshake.") + +ER3(SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD, (SSL_ERROR_BASE + 114), +"SSL received an unexpected uncompressed record.") + +ER3(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY, (SSL_ERROR_BASE + 115), +"SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message.") + +ER3(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID, (SSL_ERROR_BASE + 116), +"SSL received invalid NPN extension data.") + +ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2, (SSL_ERROR_BASE + 117), +"SSL feature not supported for SSL 2.0 connections.") + +ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS, (SSL_ERROR_BASE + 118), +"SSL feature not supported for servers.") + +ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS, (SSL_ERROR_BASE + 119), +"SSL feature not supported for clients.") diff --git a/net/third_party/nss/ssl/bodge/blapi.h b/net/third_party/nss/ssl/bodge/blapi.h index 21e9353..17350cf 100644 --- a/net/third_party/nss/ssl/bodge/blapi.h +++ b/net/third_party/nss/ssl/bodge/blapi.h @@ -46,6 +46,10 @@ #include "hasht.h" #include "alghmac.h" +#ifndef AES_256_KEY_LENGTH +#define AES_256_KEY_LENGTH 32 /* bytes */ +#endif + SEC_BEGIN_PROTOS /* diff --git a/net/third_party/nss/ssl/derive.c b/net/third_party/nss/ssl/derive.c index 84d7da0..d4a1d14 100644 --- a/net/third_party/nss/ssl/derive.c +++ b/net/third_party/nss/ssl/derive.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: derive.c,v 1.12 2008/06/06 01:16:31 wtc%google.com Exp $ */ +/* $Id: derive.c,v 1.13 2011/03/22 22:15:22 alexei.volkov.bugs%sun.com Exp $ */ #include "ssl.h" /* prereq to sslimpl.h */ #include "certt.h" /* prereq to sslimpl.h */ @@ -604,6 +604,9 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, PRBool testrsa_export = PR_FALSE; PRBool testecdh = PR_FALSE; PRBool testecdhe = PR_FALSE; +#ifdef NSS_ENABLE_ECC + SECKEYECParams ecParams = { siBuffer, NULL, 0 }; +#endif if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -703,10 +706,15 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, /* now wrap it */ enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); + if (enc_pms.data == NULL) { + PORT_SetError(PR_OUT_OF_MEMORY_ERROR); + break; + } irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); if (irv != SECSuccess) break; PK11_FreeSymKey(pms); + pms = NULL; /* now do the server side--check the triple bypass first */ rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, sizeof rsaPmsBuf, @@ -727,6 +735,13 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, goto done; break; } + + /* Check for NULL to avoid double free. + * SECItem_FreeItem sets data NULL in secitem.c#265 + */ + if (enc_pms.data != NULL) { + SECITEM_FreeItem(&enc_pms, PR_FALSE); + } #ifdef NSS_ENABLE_ECC for (; (privKeytype == ecKey && ( testecdh || testecdhe)) || (privKeytype == rsaKey && testecdhe); ) { @@ -735,8 +750,7 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, SECKEYPrivateKey *keapriv; SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ SECKEYPrivateKey *cpriv = NULL; - SECKEYECParams ecParams = { siBuffer, NULL, 0 }, - *pecParams; + SECKEYECParams *pecParams = NULL; if (privKeytype == ecKey && testecdhe) { /* TLS_ECDHE_ECDSA */ @@ -821,13 +835,16 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, if (testecdhe) { SECKEY_DestroyPrivateKey(keapriv); SECKEY_DestroyPublicKey(keapub); - if (privKeytype == rsaKey) - PORT_Free(ecParams.data); } if (rv == SECSuccess && *pcanbypass == PR_FALSE) goto done; break; } + /* Check for NULL to avoid double free. */ + if (ecParams.data != NULL) { + PORT_Free(ecParams.data); + ecParams.data = NULL; + } #endif /* NSS_ENABLE_ECC */ if (pms) PK11_FreeSymKey(pms); @@ -840,7 +857,18 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, if (pms) PK11_FreeSymKey(pms); - SECITEM_FreeItem(&enc_pms, PR_FALSE); + /* Check for NULL to avoid double free. + * SECItem_FreeItem sets data NULL in secitem.c#265 + */ + if (enc_pms.data != NULL) { + SECITEM_FreeItem(&enc_pms, PR_FALSE); + } +#ifdef NSS_ENABLE_ECC + if (ecParams.data != NULL) { + PORT_Free(ecParams.data); + ecParams.data = NULL; + } +#endif /* NSS_ENABLE_ECC */ if (srvPubkey) { SECKEY_DestroyPublicKey(srvPubkey); diff --git a/net/third_party/nss/ssl/manifest.mn b/net/third_party/nss/ssl/manifest.mn index f09d770..0c0370c 100644 --- a/net/third_party/nss/ssl/manifest.mn +++ b/net/third_party/nss/ssl/manifest.mn @@ -51,7 +51,6 @@ MAPFILE = $(OBJDIR)/ssl.def CSRCS = \ derive.c \ - fnv1a64.c \ prelib.c \ ssl3con.c \ ssl3gthr.c \ @@ -60,6 +59,8 @@ CSRCS = \ ssldef.c \ sslenum.c \ sslerr.c \ + sslerrstrs.c \ + sslinit.c \ ssl3ext.c \ sslgathr.c \ sslmutex.c \ diff --git a/net/third_party/nss/ssl/notes.txt b/net/third_party/nss/ssl/notes.txt index 772da4d..44731bc 100644 --- a/net/third_party/nss/ssl/notes.txt +++ b/net/third_party/nss/ssl/notes.txt @@ -91,8 +91,8 @@ user dialog to finish). It is not the same as EWOULDBLOCK. Rank (order) of locks -[ReadLock ->]\ [firstHandshake ->] [ssl3Handshake ->] recvbuf \ -> "spec" -[WriteLock->]/ xmitbuf / +recvLock ->\ firstHandshake -> recvbuf -> ssl3Handshake -> xmitbuf -> "spec" +sendLock ->/ crypto and hash Data that must be protected while turning plaintext into ciphertext: diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h index 12896b1..9f41e62 100644 --- a/net/third_party/nss/ssl/ssl.h +++ b/net/third_party/nss/ssl/ssl.h @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: ssl.h,v 1.38.2.1 2010/07/31 04:33:52 wtc%google.com Exp $ */ +/* $Id: ssl.h,v 1.49 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ #ifndef __ssl_h_ #define __ssl_h_ @@ -100,7 +100,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); /* (off by default) */ #define SSL_HANDSHAKE_AS_SERVER 6 /* force connect to hs as server */ /* (off by default) */ -#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (on by default) */ +#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (off by default) */ #define SSL_ENABLE_SSL3 8 /* enable ssl v3 (on by default) */ #define SSL_NO_CACHE 9 /* don't use the session cache */ /* (off by default) */ @@ -109,7 +109,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); #define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */ /* (off by default) */ #define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */ - /* (on by default) */ + /* (off by default) */ #define SSL_ENABLE_TLS 13 /* enable TLS (on by default) */ #define SSL_ROLLBACK_DETECTION 14 /* for compatibility, default: on */ #define SSL_NO_STEP_DOWN 15 /* Disable export cipher suites */ @@ -139,9 +139,35 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); /* occur on RSA or DH ciphersuites where the cipher's key length is >= 80 */ /* bits. The advantage of False Start is that it saves a round trip for */ /* client-speaks-first protocols when performing a full handshake. */ -#define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */ -#define SSL_ENABLE_CACHED_INFO 24 /* Enable TLS cached information */ - /* extension, off by default. */ + +/* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks + * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting + * non-empty application_data records into two records; the first record has + * only the first byte of plaintext, and the second has the rest. + * + * This only prevents the attack in the sending direction; the connection may + * still be vulnerable to such attacks if the peer does not implement a similar + * countermeasure. + * + * This protection mechanism is on by default; the default can be overridden by + * setting NSS_SSL_CBC_RANDOM_IV=0 in the environment prior to execution, + * and/or by the application setting the option SSL_CBC_RANDOM_IV to PR_FALSE. + * + * The per-record IV in TLS 1.1 and later adds one block of overhead per + * record, whereas this hack will add at least two blocks of overhead per + * record, so TLS 1.1+ will always be more efficient. + * + * Other implementations (e.g. some versions of OpenSSL, in some + * configurations) prevent the same attack by prepending an empty + * application_data record to every application_data record they send; we do + * not do that because some implementations cannot handle empty + * application_data records. Also, we only split application_data records and + * not other types of records, because some implementations will not accept + * fragmented records of some other types (e.g. some versions of NSS do not + * accept fragmented alerts). + */ +#define SSL_CBC_RANDOM_IV 23 +#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ #define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */ #define SSL_ENCRYPT_CLIENT_CERTS 26 /* Enable encrypted client certs. */ @@ -158,20 +184,24 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on); SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle); -/* SSLNextProtoCallback is called, during the handshake, when the server has - * sent a Next Protocol Negotiation extension. |protos| and |protosLen| define - * a buffer which contains the server's advertisement. This data is guaranteed - * to be well formed per the NPN spec. |protoOut| is a buffer provided by the - * caller, of length 255 (the maximum allowed by the protocol). - * On successful return, the protocol to be announced to the server will be in - * |protoOut| and its length in |*protoOutLen|. */ +/* SSLNextProtoCallback is called during the handshake for the client, when a + * Next Protocol Negotiation (NPN) extension has been received from the server. + * |protos| and |protosLen| define a buffer which contains the server's + * advertisement. This data is guaranteed to be well formed per the NPN spec. + * |protoOut| is a buffer provided by the caller, of length 255 (the maximum + * allowed by the protocol). On successful return, the protocol to be announced + * to the server will be in |protoOut| and its length in |*protoOutLen|. + * + * The callback must return SECFailure or SECSuccess (not SECWouldBlock). + */ typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)( void *arg, PRFileDesc *fd, const unsigned char* protos, unsigned int protosLen, unsigned char* protoOut, - unsigned int* protoOutLen); + unsigned int* protoOutLen, + unsigned int protoMaxOut); /* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol * Negotiation. It causes a client to advertise NPN. */ @@ -190,24 +220,25 @@ SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd, SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, unsigned int length); -/* SSL_GetNextProto can be used after a handshake on a socket where - * SSL_SetNextProtoNego was called to retrieve the result of the Next Protocol - * negotiation. + +typedef enum SSLNextProtoState { + SSL_NEXT_PROTO_NO_SUPPORT = 0, /* No peer support */ + SSL_NEXT_PROTO_NEGOTIATED = 1, /* Mutual agreement */ + SSL_NEXT_PROTO_NO_OVERLAP = 2 /* No protocol overlap found */ +} SSLNextProtoState; + +/* SSL_GetNextProto can be used in the HandshakeCallback or any time after + * a handshake to retrieve the result of the Next Protocol negotiation. * - * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated - * protocol, if any, is written into buf, which must be at least buf_len bytes - * long. If the negotiated protocol is longer than this, it is truncated. The - * number of bytes copied is written into *length. */ + * The length of the negotiated protocol, if any, is written into *bufLen. + * If the negotiated protocol is longer than bufLenMax, then SECFailure is + * returned. Otherwise, the negotiated protocol, if any, is written into buf, + * and SECSuccess is returned. */ SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, - int *state, + SSLNextProtoState *state, unsigned char *buf, - unsigned int *length, - unsigned int buf_len); - -/* TODO(wtc): it may be a good idea to define these as an enum type. */ -#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */ -#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */ -#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */ + unsigned int *bufLen, + unsigned int bufLenMax); /* ** Control ciphers that SSL uses. If on is non-zero then the named cipher @@ -304,12 +335,6 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher, #define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */ /* -** Returns true if the server's Certificate message contained a hash of the -** certificate chain due to the TLS cached info extension. -*/ -SSL_IMPORT PRBool SSL_CertChainDigestReceived(PRFileDesc *fd); - -/* ** Return the certificate for our SSL peer. If the client calls this ** it will always return the server's certificate. If the server calls ** this, it may return NULL if client authentication is not enabled or @@ -319,22 +344,16 @@ SSL_IMPORT PRBool SSL_CertChainDigestReceived(PRFileDesc *fd); SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd); /* -** Return references to the certificates presented by the SSL peer. On entry, -** |*certs_size| must contain the size of the |certs| array. On successful -** return, |*certs_size| contains the number of certificates available and +** Return references to the certificates presented by the SSL peer. +** |maxNumCerts| must contain the size of the |certs| array. On successful +** return, |*numCerts| contains the number of certificates available and ** |certs| will contain references to as many certificates as would fit. -** Therefore if, on exit, |*certs_size| contains a value less than, or equal to, -** the entry value then all certificates were returned. +** Therefore if |*numCerts| contains a value less than or equal to +** |maxNumCerts|, then all certificates were returned. */ SSL_IMPORT SECStatus SSL_PeerCertificateChain( - PRFileDesc *fd, CERTCertificate **certs, unsigned int *certs_size); - -/* -** Set the predicted cert chain to be used in the cached info extension. -*/ -SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates(PRFileDesc *fd, - CERTCertificate **certs, - unsigned int len); + PRFileDesc *fd, CERTCertificate **certs, + unsigned int *numCerts, unsigned int maxNumCerts); /* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by * the TLS server. The resulting data is copied to |out_data|. On entry, |*len| @@ -357,6 +376,22 @@ SSL_IMPORT SECStatus SSL_GetStapledOCSPResponse(PRFileDesc *fd, ** Authenticate certificate hook. Called when a certificate comes in ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the ** certificate. +** +** The authenticate certificate hook must return SECSuccess to indicate the +** certificate is valid, SECFailure to indicate the certificate is invalid, +** or SECWouldBlock if the application will authenticate the certificate +** asynchronously. SECWouldBlock is only supported for non-blocking sockets. +** +** If the authenticate certificate hook returns SECFailure, then the bad cert +** hook will be called. The bad cert handler is NEVER called if the +** authenticate certificate hook returns SECWouldBlock. If the application +** needs to handle and/or override a bad cert, it should do so before it +** calls SSL_AuthCertificateComplete (modifying the error it passes to +** SSL_AuthCertificateComplete as needed). +** +** See the documentation for SSL_AuthCertificateComplete for more information +** about the asynchronous behavior that occurs when the authenticate +** certificate hook returns SECWouldBlock. */ typedef SECStatus (PR_CALLBACK *SSLAuthCertificate)(void *arg, PRFileDesc *fd, PRBool checkSig, @@ -499,23 +534,22 @@ SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a); ** This is a callback for dealing with server certs that are not authenticated ** by the client. The client app can decide that it actually likes the ** cert by some external means and restart the connection. +** +** The bad cert hook must return SECSuccess to override the result of the +** authenticate certificate hook, SECFailure if the certificate should still be +** considered invalid, or SECWouldBlock if the application will authenticate +** the certificate asynchronously. SECWouldBlock is only supported for +** non-blocking sockets. +** +** See the documentation for SSL_AuthCertificateComplete for more information +** about the asynchronous behavior that occurs when the bad cert hook returns +** SECWouldBlock. */ typedef SECStatus (PR_CALLBACK *SSLBadCertHandler)(void *arg, PRFileDesc *fd); SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg); /* - ** Set the predicted chain of certificates for the peer. This is used for the - ** TLS Cached Info extension. Note that the SSL_ENABLE_CACHED_INFO option must - ** be set for this to occur. - ** - ** This function takes a reference to each of the given certificates. - */ - SSL_IMPORT SECStatus SSL_SetPredictedPeerCertificates( - PRFileDesc *fd, CERTCertificate **certs, - unsigned int numCerts); - -/* ** Configure SSL socket for running a secure server. Needs the ** certificate for the server and the servers private key. The arguments ** are copied. @@ -525,6 +559,15 @@ SSL_IMPORT SECStatus SSL_ConfigSecureServer( SECKEYPrivateKey *key, SSLKEAType kea); /* +** Allows SSL socket configuration with caller-supplied certificate chain. +** If certChainOpt is NULL, tries to find one. +*/ +SSL_IMPORT SECStatus +SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, + const CERTCertificateList *certChainOpt, + SECKEYPrivateKey *key, SSLKEAType kea); + +/* ** Configure a secure server's session-id cache. Define the maximum number ** of entries in the cache, the longevity of the entires, and the directory ** where the cache files will be placed. These values can be zero, and @@ -611,6 +654,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, PRBool flushCache, PRIntervalTime timeout); +/* Returns a SECItem containing the certificate_types field of the +** CertificateRequest message. Each byte of the data is a TLS +** ClientCertificateType value, and they are ordered from most preferred to +** least. This function should only be called from the +** SSL_GetClientAuthDataHook callback, and will return NULL if called at any +** other time. The returned value is valid only until the callback returns, and +** should not be freed. +*/ +SSL_IMPORT const SECItem * +SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd); #ifdef SSL_DEPRECATED_FUNCTION /* deprecated! @@ -798,17 +851,86 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *last_handshake_resumed); -/* Returns a SECItem containing the certificate_types field of the -** CertificateRequest message. Each byte of the data is a TLS -** ClientCertificateType value, and they are ordered from most preferred to -** least. This function should only be called from the -** SSL_GetClientAuthDataHook callback, and will return NULL if called at any -** other time. The returned value is valid only until the callback returns, and -** should not be freed. -*/ -SSL_IMPORT const SECItem * -SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd); +/* + * Return a boolean that indicates whether the underlying library + * will perform as the caller expects. + * + * The only argument is a string, which should be the version + * identifier of the NSS library. That string will be compared + * against a string that represents the actual build version of + * the SSL library. It also invokes the version checking functions + * of the dependent libraries such as NSPR. + */ +extern PRBool NSSSSL_VersionCheck(const char *importedVersion); + +/* + * Returns a const string of the SSL library version. + */ +extern const char *NSSSSL_GetVersion(void); +/* Restart an SSL connection that was paused to do asynchronous certificate + * chain validation (when the auth certificate hook or bad cert handler + * returned SECWouldBlock). + * + * This function only works for non-blocking sockets; Do not use it for + * blocking sockets. Currently, this function works only for the client role of + * a connection; it does not work for the server role. + * + * The application must call SSL_AuthCertificateComplete with 0 as the value of + * the error parameter after it has successfully validated the peer's + * certificate, in order to continue the SSL handshake. + * + * The application may call SSL_AuthCertificateComplete with a non-zero value + * for error (e.g. SEC_ERROR_REVOKED_CERTIFICATE) when certificate validation + * fails, before it closes the connection. If the application does so, an + * alert corresponding to the error (e.g. certificate_revoked) will be sent to + * the peer. See the source code of the internal function + * ssl3_SendAlertForCertError for the current mapping of error to alert. This + * mapping may change in future versions of libssl. + * + * This function will not complete the entire handshake. The application must + * call SSL_ForceHandshake, PR_Recv, PR_Send, etc. after calling this function + * to force the handshake to complete. + * + * On the first handshake of a connection, libssl will wait for the peer's + * certificate to be authenticated before calling the handshake callback, + * sending a client certificate, sending any application data, or returning + * any application data to the application. On subsequent (renegotiation) + * handshakes, libssl will block the handshake unconditionally while the + * certificate is being validated. + * + * libssl may send and receive handshake messages while waiting for the + * application to call SSL_AuthCertificateComplete, and it may call other + * callbacks (e.g, the client auth data hook) before + * SSL_AuthCertificateComplete has been called. + * + * An application that uses this asynchronous mechanism will usually have lower + * handshake latency if it has to do public key operations on the certificate + * chain and/or CRL/OCSP/cert fetching during the authentication, especially if + * it does so in parallel on another thread. However, if the application can + * authenticate the peer's certificate quickly then it may be more efficient + * to use the synchronous mechanism (i.e. returning SECFailure/SECSuccess + * instead of SECWouldBlock from the authenticate certificate hook). + * + * Be careful about converting an application from synchronous cert validation + * to asynchronous certificate validation. A naive conversion is likely to + * result in deadlocks; e.g. the application will wait in PR_Poll for network + * I/O on the connection while all network I/O on the connection is blocked + * waiting for this function to be called. + * + * Returns SECFailure on failure, SECSuccess on success. Never returns + * SECWouldBlock. Note that SSL_AuthCertificateComplete will (usually) return + * SECSuccess; do not interpret the return value of SSL_AuthCertificateComplete + * as an indicator of whether it is OK to continue using the connection. For + * example, SSL_AuthCertificateComplete(fd, SEC_ERROR_REVOKED_CERTIFICATE) will + * return SECSuccess (normally), but that does not mean that the application + * should continue using the connection. If the application passes a non-zero + * value for second argument (error), or if SSL_AuthCertificateComplete returns + * anything other than SECSuccess, then the application should close the + * connection. + */ +SSL_IMPORT SECStatus SSL_AuthCertificateComplete(PRFileDesc *fd, + PRErrorCode error); SEC_END_PROTOS #endif /* __ssl_h_ */ diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index aca77f4..ab17aa1 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -39,7 +39,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: ssl3con.c,v 1.142.2.4 2010/09/01 19:47:11 wtc%google.com Exp $ */ +/* $Id: ssl3con.c,v 1.164 2012/02/17 09:50:04 kaie%kuix.de Exp $ */ #include "cert.h" #include "ssl.h" @@ -88,7 +88,8 @@ static SECStatus ssl3_SendServerHello( sslSocket *ss); static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss); static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss); -static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, unsigned char *b, +static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, + const unsigned char *b, unsigned int l); static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, @@ -238,9 +239,6 @@ static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = { #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */ -/* This is a hack to make sure we don't do double handshakes for US policy */ -PRBool ssl3_global_policy_some_restricted = PR_FALSE; - /* This global item is used only in servers. It is is initialized by ** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest(). */ @@ -930,8 +928,7 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, key = CERT_ExtractPublicKey(cert); if (key == NULL) { - /* CERT_ExtractPublicKey doesn't set error code */ - PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); + ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); return SECFailure; } @@ -2042,9 +2039,7 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { return isPresent; } -/* Caller must hold the spec read lock. wrBuf is sometimes, but not always, - * ss->sec.writeBuf. - */ +/* Caller must hold the spec read lock. */ static SECStatus ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, PRBool isServer, @@ -2229,8 +2224,7 @@ ssl3_SendRecord( sslSocket * ss, ssl_GetSpecReadLock(ss); /********************************/ - if (nIn > 1 && - ss->opt.enableFalseStart && + if (nIn > 1 && ss->opt.cbcRandomIV && ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS && type == content_application_data && ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { @@ -2248,7 +2242,7 @@ ssl3_SendRecord( sslSocket * ss, if (rv != SECSuccess) { SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", SSL_GETPID(), ss->fd, spaceNeeded)); - goto spec_locked_loser; /* sslBuffer_Grow set a memory error code. */ + goto spec_locked_loser; /* sslBuffer_Grow set error code. */ } } @@ -2281,7 +2275,7 @@ ssl3_SendRecord( sslSocket * ss, ss->sec.isServer, type, pIn, contentLen, wrBuf); if (rv == SECSuccess) { - PRINT_BUF(50, (ss, "send (encrypted) record data [1/1]:", + PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len)); } } @@ -2617,6 +2611,40 @@ ssl3_HandshakeFailure(sslSocket *ss) return SECFailure; } +static void +ssl3_SendAlertForCertError(sslSocket * ss, PRErrorCode errCode) +{ + SSL3AlertDescription desc = bad_certificate; + PRBool isTLS = ss->version >= SSL_LIBRARY_VERSION_3_1_TLS; + + switch (errCode) { + case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break; + case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break; + case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break; + case SEC_ERROR_INADEQUATE_KEY_USAGE: + case SEC_ERROR_INADEQUATE_CERT_TYPE: + desc = certificate_unknown; break; + case SEC_ERROR_UNTRUSTED_CERT: + desc = isTLS ? access_denied : certificate_unknown; break; + case SEC_ERROR_UNKNOWN_ISSUER: + case SEC_ERROR_UNTRUSTED_ISSUER: + desc = isTLS ? unknown_ca : certificate_unknown; break; + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + desc = isTLS ? unknown_ca : certificate_expired; break; + + case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: + case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: + case SEC_ERROR_CA_CERT_INVALID: + case SEC_ERROR_BAD_SIGNATURE: + default: desc = bad_certificate; break; + } + SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d", + SSL_GETPID(), ss->fd, errCode)); + + (void) SSL3_SendAlert(ss, alert_fatal, desc); +} + + /* * Send handshake_Failure alert. Set generic error number. */ @@ -3233,7 +3261,8 @@ loser: ** Caller must hold the ssl3Handshake lock. */ static SECStatus -ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l) +ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, + unsigned int l) { SECStatus rv = SECSuccess; @@ -3773,7 +3802,6 @@ done: **************************************************************************/ /* Called from ssl3_HandleHelloRequest(), - * ssl3_HandleFinished() (for step-up) * ssl3_RedoHandshake() * ssl2_BeginClientHandshake (when resuming ssl3 session) */ @@ -4346,6 +4374,12 @@ getWrappingKey( sslSocket * ss, SECStatus rv; SECItem wrappedKey; SSLWrappedSymWrappingKey wswk; +#ifdef NSS_ENABLE_ECC + PK11SymKey * Ks = NULL; + SECKEYPublicKey *pubWrapKey = NULL; + SECKEYPrivateKey *privWrapKey = NULL; + ECCWrappedKeyInfo *ecWrapped; +#endif /* NSS_ENABLE_ECC */ svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEY; PORT_Assert(svrPrivKey != NULL); @@ -4422,13 +4456,6 @@ getWrappingKey( sslSocket * ss, /* wrap symmetric wrapping key in server's public key. */ switch (exchKeyType) { -#ifdef NSS_ENABLE_ECC - PK11SymKey * Ks = NULL; - SECKEYPublicKey *pubWrapKey = NULL; - SECKEYPrivateKey *privWrapKey = NULL; - ECCWrappedKeyInfo *ecWrapped; -#endif /* NSS_ENABLE_ECC */ - case kt_rsa: asymWrapMechanism = CKM_RSA_PKCS; rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey, @@ -4796,7 +4823,7 @@ ssl3_SendClientKeyExchange(sslSocket *ss) if (ss->sec.peerKey == NULL) { serverKey = CERT_ExtractPublicKey(ss->sec.peerCert); if (serverKey == NULL) { - PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); + ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); return SECFailure; } } else { @@ -5226,6 +5253,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl3_CopyPeerCertsFromSID(ss, sid); } + /* NULL value for PMS signifies re-use of the old MS */ rv = ssl3_InitPendingCipherSpec(ss, NULL); if (rv != SECSuccess) { @@ -5640,7 +5668,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) #endif /* NSS_PLATFORM_CLIENT_AUTH */ switch (rv) { case SECWouldBlock: /* getClientAuthData has put up a dialog box. */ - ssl_SetAlwaysBlock(ss); + ssl3_SetAlwaysBlock(ss); break; /* not an error */ case SECSuccess: @@ -5786,7 +5814,7 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, SECKEYPrivateKey * key, CERTCertificateList *certChain) { - SECStatus rv = SECFailure; + SECStatus rv = SECSuccess; /* XXX This code only works on the initial handshake on a connection, ** XXX It does not work on a subsequent handshake (redo). @@ -5816,11 +5844,6 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, (void)SSL3_SendAlert(ss, alert_warning, no_certificate); } } - ssl_GetRecvBufLock(ss); - if (ss->ssl3.hs.msgState.buf != NULL) { - rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); - } - ssl_ReleaseRecvBufLock(ss); } else { if (cert) { CERT_DestroyCertificate(cert); @@ -5831,22 +5854,38 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, if (certChain) { CERT_DestroyCertificateList(certChain); } + rv = SECFailure; } return rv; } PRBool ssl3_CanFalseStart(sslSocket *ss) { - return ss->opt.enableFalseStart && - !ss->sec.isServer && - !ss->ssl3.hs.isResuming && - ss->ssl3.cwSpec && - ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && - (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa || - ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh || - ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh); + PRBool rv; + + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); + + /* XXX: does not take into account whether we are waiting for + * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when + * that is done, this function could return different results each time it + * would be called. + */ + + ssl_GetSpecReadLock(ss); + rv = ss->opt.enableFalseStart && + !ss->sec.isServer && + !ss->ssl3.hs.isResuming && + ss->ssl3.cwSpec && + ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && + (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa || + ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh || + ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh); + ssl_ReleaseSpecReadLock(ss); + return rv; } +static SECStatus ssl3_SendClientSecondRound(sslSocket *ss); + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete * ssl3 Server Hello Done message. * Caller must hold Handshake and RecvBuf locks. @@ -5856,10 +5895,6 @@ ssl3_HandleServerHelloDone(sslSocket *ss) { SECStatus rv; SSL3WaitState ws = ss->ssl3.hs.ws; - PRBool sendEmptyCert, sendCert; - int n = 0, i; - typedef SECStatus (*SendFunction)(sslSocket*); - SendFunction send_funcs[5]; SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake", SSL_GETPID(), ss->fd)); @@ -5875,14 +5910,72 @@ ssl3_HandleServerHelloDone(sslSocket *ss) return SECFailure; } + rv = ssl3_SendClientSecondRound(ss); + + return rv; +} + +/* Called from ssl3_HandleServerHelloDone and ssl3_AuthCertificateComplete. + * + * Caller must hold Handshake and RecvBuf locks. + */ +static SECStatus +ssl3_SendClientSecondRound(sslSocket *ss) +{ + SECStatus rv; + PRBool sendClientCert; + PRBool sendEmptyCert; + int n = 0, i; + typedef SECStatus (*SendFunction)(sslSocket*); + SendFunction send_funcs[5]; + + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); + + sendClientCert = !ss->ssl3.sendEmptyCert && + ss->ssl3.clientCertChain != NULL && + (ss->ssl3.platformClientKey || + ss->ssl3.clientPrivateKey != NULL); + + /* We must wait for the server's certificate to be authenticated before + * sending the client certificate in order to disclosing the client + * certificate to an attacker that does not have a valid cert for the + * domain we are connecting to. + * + * XXX: We should do the same for the NPN extension, but for that we + * need an option to give the application the ability to leak the NPN + * information to get better performance. + * + * During the initial handshake on a connection, we never send/receive + * application data until we have authenticated the server's certificate; + * i.e. we have fully authenticated the handshake before using the cipher + * specs agreed upon for that handshake. During a renegotiation, we may + * continue sending and receiving application data during the handshake + * interleaved with the handshake records. If we were to send the client's + * second round for a renegotiation before the server's certificate was + * authenticated, then the application data sent/received after this point + * would be using cipher spec that hadn't been authenticated. By waiting + * until the server's certificate has been authenticated during + * renegotiations, we ensure that renegotiations have the same property + * as initial handshakes; i.e. we have fully authenticated the handshake + * before using the cipher specs agreed upon for that handshake for + * application data. + */ + if (ss->ssl3.hs.restartTarget) { + PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget"); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + if (ss->ssl3.hs.authCertificatePending && + (sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) { + ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound; + return SECWouldBlock; + } + ssl_GetXmitBufLock(ss); /*******************************/ sendEmptyCert = ss->ssl3.sendEmptyCert; ss->ssl3.sendEmptyCert = PR_FALSE; - sendCert = !sendEmptyCert && - ss->ssl3.clientCertChain != NULL && - (ss->ssl3.platformClientKey || - ss->ssl3.clientPrivateKey != NULL); if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { send_funcs[n++] = ssl3_SendClientKeyExchange; @@ -5890,7 +5983,7 @@ ssl3_HandleServerHelloDone(sslSocket *ss) if (sendEmptyCert) { send_funcs[n++] = ssl3_SendEmptyCertificate; } - if (sendCert) { + if (sendClientCert) { send_funcs[n++] = ssl3_SendCertificate; send_funcs[n++] = ssl3_SendCertificateVerify; } @@ -5898,11 +5991,11 @@ ssl3_HandleServerHelloDone(sslSocket *ss) if (sendEmptyCert) { send_funcs[n++] = ssl3_SendEmptyCertificate; } - if (sendCert) { + if (sendClientCert) { send_funcs[n++] = ssl3_SendCertificate; } send_funcs[n++] = ssl3_SendClientKeyExchange; - if (sendCert) { + if (sendClientCert) { send_funcs[n++] = ssl3_SendCertificateVerify; } send_funcs[n++] = ssl3_SendChangeCipherSpecs; @@ -5917,8 +6010,9 @@ ssl3_HandleServerHelloDone(sslSocket *ss) } } - /* We don't send NPN in a renegotiation as it's explicitly disallowed by - * the spec. */ + /* XXX: If the server's certificate hasn't been authenticated by this + * point, then we may be leaking this NPN message to an attacker. + */ if (!ss->firstHsDone) { rv = ssl3_SendNextProto(ss); if (rv != SECSuccess) { @@ -7899,69 +7993,6 @@ ssl3_SendCertificate(sslSocket *ss) } } - if (ss->ssl3.cachedInfoCertChainDigestReceived) { - /* Compute hash. */ - PRUint64 certChainHash; - int i; - FNV1A64_Init(&certChainHash); - for (i = 0; i < certChain->len; i++) { - unsigned int certLen = certChain->certs[i].len; - unsigned char certLenArray[3] = { - certLen >> 16, - certLen >> 8, - certLen - }; - FNV1A64_Update(&certChainHash, certLenArray, sizeof(certLenArray)); - FNV1A64_Update(&certChainHash, certChain->certs[i].data, certLen); - } - FNV1A64_Final(&certChainHash); - - /* Both |&certChainHash| and |ss->ssl3.certChainDigest| should be in - * network byte order since both are computed with the FNV1A64 hash, - * which calls the function htonll. - */ - if (memcmp(&certChainHash, ss->ssl3.certChainDigest, - sizeof(certChainHash)) == 0) { - /* The client correctly predicted the certificate chain. */ - - /* Handshake type: certificate. */ - rv = ssl3_AppendHandshakeNumber(ss, certificate, 1); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - /* Handshake message length. */ - rv = ssl3_AppendHandshakeNumber(ss, 15, 3); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - /* CertChainLen(3) + ASN.1CertLen(3) + DigestLen(1) + Digest(8) */ - rv = ssl3_AppendHandshakeNumber(ss, 12, 3); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - /* ASN.1CertLen(3) + DigestLen(1) + Digest(8) */ - rv = ssl3_AppendHandshakeNumber(ss, 9, 3); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - /* Digest Length Byte */ - rv = ssl3_AppendHandshakeNumber(ss, sizeof(certChainHash), 1); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - /* Digest */ - rv = ssl3_AppendHandshake(ss, &certChainHash, - sizeof(certChainHash)); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - - return SECSuccess; - } - } - - /* Send the entire certificate as usual. */ - rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ @@ -8109,15 +8140,13 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { ssl3CertNode * c; ssl3CertNode * lastCert = NULL; - ssl3CertNode * certs = NULL; - PRArenaPool * arena = NULL; - CERTCertificate *cert; PRInt32 remaining = 0; PRInt32 size; SECStatus rv; PRBool isServer = (PRBool)(!!ss->sec.isServer); + PRBool trusted = PR_FALSE; PRBool isTLS; - SSL3AlertDescription desc = bad_certificate; + SSL3AlertDescription desc; int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; SECItem certItem; @@ -8167,54 +8196,43 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) errCode = PORT_GetError(); goto loser; } - goto cert_block; + goto server_no_cert; } - ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { + ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (ss->ssl3.peerCertArena == NULL) { goto loser; /* don't send alerts on memory errors */ } - if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) { - /* We are dealing with a certificate_chain digest */ - int i; + /* First get the peer cert. */ + remaining -= 3; + if (remaining < 0) + goto decode_loser; - ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE; + size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); + if (size <= 0) + goto loser; /* fatal alert already sent by ConsumeHandshake. */ - /* Make sure the digests match. */ - if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) { - desc = handshake_failure; - goto alert_loser; - } + if (remaining < size) + goto decode_loser; - /* First get the peer cert. */ - if (ss->ssl3.predictedCertChain[0] == NULL) { - desc = handshake_failure; - goto alert_loser; - } - ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); + certItem.data = b; + certItem.len = size; + b += size; + length -= size; + remaining -= size; - /* Now get all of the CA certs. */ - ss->ssl3.peerCertChain = NULL; - for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) { - c = PORT_ArenaNew(arena, ssl3CertNode); - if (c == NULL) { - goto loser; /* don't send alerts on memory errors */ - } - c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]); - c->next = NULL; - if (lastCert) { - lastCert->next = c; - } else { - ss->ssl3.peerCertChain = c; - } - lastCert = c; - } - } else { - /* We are dealing with a regular certificate message */ - ss->ssl3.cachedInfoCertChainDigestReceived = PR_FALSE; + ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, + PR_FALSE, PR_TRUE); + if (ss->sec.peerCert == NULL) { + /* We should report an alert if the cert was bad, but not if the + * problem was just some local problem, like memory error. + */ + goto ambiguous_err; + } - /* First get the peer cert. */ + /* Now get all of the CA certs. */ + while (remaining > 0) { remaining -= 3; if (remaining < 0) goto decode_loser; @@ -8228,66 +8246,40 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) certItem.data = b; certItem.len = size; - b += size; + b += size; length -= size; remaining -= size; - ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, - NULL, PR_FALSE, PR_TRUE); - if (ss->sec.peerCert == NULL) { - /* We should report an alert if the cert was bad, but not if the - * problem was just some local problem, like memory error. - */ - goto ambiguous_err; + c = PORT_ArenaNew(ss->ssl3.peerCertArena, ssl3CertNode); + if (c == NULL) { + goto loser; /* don't send alerts on memory errors */ } - /* Now get all of the CA certs. */ - while (remaining > 0) { - remaining -= 3; - if (remaining < 0) - goto decode_loser; - - size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); - if (size <= 0) - goto loser; /* fatal alert already sent by ConsumeHandshake. */ - - if (remaining < size) - goto decode_loser; - - certItem.data = b; - certItem.len = size; - b += size; - length -= size; - remaining -= size; - - c = PORT_ArenaNew(arena, ssl3CertNode); - if (c == NULL) { - goto loser; /* don't send alerts on memory errors */ - } - - c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, - PR_FALSE, PR_TRUE); - if (c->cert == NULL) { - goto ambiguous_err; - } - - c->next = NULL; - if (lastCert) { - lastCert->next = c; - } else { - certs = c; - } - lastCert = c; + c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, + PR_FALSE, PR_TRUE); + if (c->cert == NULL) { + goto ambiguous_err; } - if (remaining != 0) - goto decode_loser; + if (c->cert->trust) + trusted = PR_TRUE; - ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; + c->next = NULL; + if (lastCert) { + lastCert->next = c; + } else { + ss->ssl3.peerCertChain = c; + } + lastCert = c; } + if (remaining != 0) + goto decode_loser; + SECKEY_UpdateCertPQG(ss->sec.peerCert); + ss->ssl3.hs.authCertificatePending = PR_FALSE; + /* * Ask caller-supplied callback function to validate cert chain. */ @@ -8295,42 +8287,42 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PR_TRUE, isServer); if (rv) { errCode = PORT_GetError(); - if (!ss->handleBadCert) { - goto bad_cert; - } - rv = (SECStatus)(*ss->handleBadCert)(ss->badCertArg, ss->fd); - if ( rv ) { - if ( rv == SECWouldBlock ) { - /* someone will handle this connection asynchronously*/ - SSL_DBG(("%d: SSL3[%d]: go to async cert handler", - SSL_GETPID(), ss->fd)); - ssl_SetAlwaysBlock(ss); - goto cert_block; + if (rv != SECWouldBlock) { + if (ss->handleBadCert) { + rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); } - /* cert is bad */ - goto bad_cert; } - /* cert is good */ - } - /* start SSL Step Up, if appropriate */ - cert = ss->sec.peerCert; - if (!isServer && - ssl3_global_policy_some_restricted && - ss->ssl3.policy == SSL_ALLOWED && - anyRestrictedEnabled(ss) && - SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert, - PR_FALSE, /* checkSig */ - certUsageSSLServerWithStepUp, -/*XXX*/ ss->authCertificateArg) ) { - ss->ssl3.policy = SSL_RESTRICTED; - ss->ssl3.hs.rehandshake = PR_TRUE; + if (rv == SECWouldBlock) { + if (ss->sec.isServer) { + errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS; + rv = SECFailure; + goto loser; + } + + ss->ssl3.hs.authCertificatePending = PR_TRUE; + rv = SECSuccess; + + /* XXX: Async cert validation and False Start don't work together + * safely yet; if we leave False Start enabled, we may end up false + * starting (sending application data) before we + * SSL_AuthCertificateComplete has been called. + */ + ss->opt.enableFalseStart = PR_FALSE; + } + + if (rv != SECSuccess) { + ssl3_SendAlertForCertError(ss, errCode); + goto loser; + } } ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); if (!ss->sec.isServer) { + CERTCertificate *cert = ss->sec.peerCert; + /* set the server authentication and key exchange types and sizes ** from the value in the cert. If the key exchange key is different, ** it will get fixed when we handle the server key exchange message. @@ -8371,16 +8363,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) SECKEY_DestroyPublicKey(pubKey); pubKey = NULL; } - } -cert_block: - if (ss->sec.isServer) { - if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { - ss->ssl3.hs.ws = wait_cert_verify; - } else { - ss->ssl3.hs.ws = wait_client_key; - } - } else { ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ if (ss->ssl3.hs.kea_def->is_limited || /* XXX OR server cert is signing only. */ @@ -8391,11 +8374,22 @@ cert_block: ss->ssl3.hs.kea_def->exchKeyType == kt_dh) { ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */ } + } else { +server_no_cert: + if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + ss->ssl3.hs.ws = wait_cert_verify; + } else { + ss->ssl3.hs.ws = wait_client_key; + } + } + + PORT_Assert(rv == SECSuccess); + if (rv != SECSuccess) { + errCode = SEC_ERROR_LIBRARY_FAILURE; + rv = SECFailure; + goto loser; } - /* rv must normally be equal to SECSuccess here. If we called - * handleBadCert, it can also be SECWouldBlock. - */ return rv; ambiguous_err: @@ -8410,34 +8404,8 @@ ambiguous_err: } goto loser; } - /* fall through to bad_cert. */ - -bad_cert: /* caller has set errCode. */ - switch (errCode) { - case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break; - case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break; - case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break; - case SEC_ERROR_INADEQUATE_KEY_USAGE: - case SEC_ERROR_INADEQUATE_CERT_TYPE: - desc = certificate_unknown; break; - case SEC_ERROR_UNTRUSTED_CERT: - desc = isTLS ? access_denied : certificate_unknown; break; - case SEC_ERROR_UNKNOWN_ISSUER: - case SEC_ERROR_UNTRUSTED_ISSUER: - desc = isTLS ? unknown_ca : certificate_unknown; break; - case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: - desc = isTLS ? unknown_ca : certificate_expired; break; - - case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: - case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: - case SEC_ERROR_CA_CERT_INVALID: - case SEC_ERROR_BAD_SIGNATURE: - default: desc = bad_certificate; break; - } - SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d", - SSL_GETPID(), ss->fd, errCode)); - - goto alert_loser; + ssl3_SendAlertForCertError(ss, errCode); + goto loser; decode_loser: desc = isTLS ? decode_error : bad_certificate; @@ -8446,10 +8414,6 @@ alert_loser: (void)SSL3_SendAlert(ss, alert_fatal, desc); loser: - if (ss->ssl3.peerCertChain == NULL) { - ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; - } - PORT_Assert(certs == NULL); ssl3_CleanupPeerCerts(ss); if (ss->sec.peerCert != NULL) { @@ -8460,61 +8424,63 @@ loser: return SECFailure; } +static SECStatus ssl3_FinishHandshake(sslSocket *ss); -/* restart an SSL connection that we stopped to run certificate dialogs -** XXX Need to document here how an application marks a cert to show that -** the application has accepted it (overridden CERT_VerifyCert). - * - * XXX This code only works on the initial handshake on a connection, XXX - * It does not work on a subsequent handshake (redo). - * - * Return value: XXX - * - * Caller holds 1stHandshakeLock. +static SECStatus +ssl3_AlwaysFail(sslSocket * ss) +{ + PORT_SetError(PR_INVALID_STATE_ERROR); + return SECFailure; +} + +/* Caller must hold 1stHandshakeLock. */ -int -ssl3_RestartHandshakeAfterServerCert(sslSocket *ss) +SECStatus +ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error) { - CERTCertificate * cert; - int rv = SECSuccess; + SECStatus rv; - if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) { - SET_ERROR_CODE - return SECFailure; - } - if (!ss->ssl3.initialized) { - SET_ERROR_CODE - return SECFailure; + PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); + + if (ss->sec.isServer) { + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS); + return SECFailure; } - cert = ss->sec.peerCert; + ssl_GetRecvBufLock(ss); + ssl_GetSSL3HandshakeLock(ss); - /* Permit step up if user decided to accept the cert */ - if (!ss->sec.isServer && - ssl3_global_policy_some_restricted && - ss->ssl3.policy == SSL_ALLOWED && - anyRestrictedEnabled(ss) && - (SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert, - PR_FALSE, /* checksig */ - certUsageSSLServerWithStepUp, -/*XXX*/ ss->authCertificateArg) )) { - ss->ssl3.policy = SSL_RESTRICTED; - ss->ssl3.hs.rehandshake = PR_TRUE; + if (!ss->ssl3.hs.authCertificatePending) { + PORT_SetError(PR_INVALID_STATE_ERROR); + rv = SECFailure; + goto done; } - if (ss->handshake != NULL) { - ss->handshake = ssl_GatherRecord1stHandshake; - ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); - ssl3_CopyPeerCertsToSID((ssl3CertNode *)ss->ssl3.peerCertChain, - ss->sec.ci.sid); + ss->ssl3.hs.authCertificatePending = PR_FALSE; - ssl_GetRecvBufLock(ss); - if (ss->ssl3.hs.msgState.buf != NULL) { - rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); + if (error != 0) { + ss->ssl3.hs.restartTarget = ssl3_AlwaysFail; + ssl3_SendAlertForCertError(ss, error); + rv = SECSuccess; + } else if (ss->ssl3.hs.restartTarget != NULL) { + sslRestartTarget target = ss->ssl3.hs.restartTarget; + ss->ssl3.hs.restartTarget = NULL; + rv = target(ss); + /* Even if we blocked here, we have accomplished enough to claim + * success. Any remaining work will be taken care of by subsequent + * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. + */ + if (rv == SECWouldBlock) { + rv = SECSuccess; } - ssl_ReleaseRecvBufLock(ss); + } else { + rv = SECSuccess; } +done: + ssl_ReleaseSSL3HandshakeLock(ss); + ssl_ReleaseRecvBufLock(ss); + return rv; } @@ -8779,7 +8745,6 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, SECStatus rv = SECSuccess; PRBool isServer = ss->sec.isServer; PRBool isTLS; - PRBool doStepUp; SSL3KEAType effectiveExchKeyType; PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); @@ -8835,8 +8800,6 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, } } - doStepUp = (PRBool)(!isServer && ss->ssl3.hs.rehandshake); - ssl_GetXmitBufLock(ss); /*************************************/ if ((isServer && !ss->ssl3.hs.isResuming) || @@ -8862,19 +8825,18 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, goto xmit_loser; /* err is set. */ } /* If this thread is in SSL_SecureSend (trying to write some data) - ** or if it is going to step up, ** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the ** last two handshake messages (change cipher spec and finished) ** will be sent in the same send/write call as the application data. */ - if (doStepUp || ss->writerThread == PR_GetCurrentThread()) { + if (ss->writerThread == PR_GetCurrentThread()) { flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; } if (!isServer && !ss->firstHsDone) { rv = ssl3_SendNextProto(ss); if (rv != SECSuccess) { - goto xmit_loser; /* err code was set. */ + goto xmit_loser; /* err code was set. */ } } @@ -8884,22 +8846,12 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, } } - /* Optimization: don't cache this connection if we're going to step up. */ - if (doStepUp) { - ssl_FreeSID(sid); - ss->sec.ci.sid = sid = NULL; - ss->ssl3.hs.rehandshake = PR_FALSE; - rv = ssl3_SendClientHello(ss); xmit_loser: - ssl_ReleaseXmitBufLock(ss); - return rv; /* err code is set if appropriate. */ - } - ssl_ReleaseXmitBufLock(ss); /*************************************/ + if (rv != SECSuccess) { + return rv; + } - /* The first handshake is now completed. */ - ss->handshake = NULL; - ss->firstHsDone = PR_TRUE; ss->gs.writeOffset = 0; ss->gs.readOffset = 0; @@ -8949,10 +8901,42 @@ xmit_loser: /* If the wrap failed, we don't cache the sid. * The connection continues normally however. */ - if (rv == SECSuccess) { - (*ss->sec.cache)(sid); + ss->ssl3.hs.cacheSID = rv == SECSuccess; + } + + if (ss->ssl3.hs.authCertificatePending) { + if (ss->ssl3.hs.restartTarget) { + PR_NOT_REACHED("ssl3_HandleFinished: unexpected restartTarget"); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } + + ss->ssl3.hs.restartTarget = ssl3_FinishHandshake; + return SECWouldBlock; + } + + rv = ssl3_FinishHandshake(ss); + return rv; +} + +SECStatus +ssl3_FinishHandshake(sslSocket * ss) +{ + SECStatus rv; + + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); + PORT_Assert( ss->ssl3.hs.restartTarget == NULL ); + + /* The first handshake is now completed. */ + ss->handshake = NULL; + ss->firstHsDone = PR_TRUE; + + if (ss->sec.ci.sid->cached == never_cached && + !ss->opt.noCache && ss->sec.cache && ss->ssl3.hs.cacheSID) { + (*ss->sec.cache)(ss->sec.ci.sid); } + ss->ssl3.hs.ws = idle_handshake; /* Do the handshake callback for sslv3 here, if we cannot false start. */ @@ -9317,7 +9301,6 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) * * Called from ssl3_GatherCompleteHandshake * ssl3_RestartHandshakeAfterCertReq - * ssl3_RestartHandshakeAfterServerCert * * Caller must hold the RecvBufLock. * @@ -9667,7 +9650,6 @@ ssl3_InitState(sslSocket *ss) ssl_GetSpecWriteLock(ss); ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0]; ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1]; - ss->ssl3.hs.rehandshake = PR_FALSE; ss->ssl3.hs.sendingSCSV = PR_FALSE; ssl3_InitCipherSpec(ss, ss->ssl3.crSpec); ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); @@ -9776,10 +9758,6 @@ ssl3_SetPolicy(ssl3CipherSuite which, int policy) } suite->policy = policy; - if (policy == SSL_RESTRICTED) { - ssl3_global_policy_some_restricted = PR_TRUE; - } - return SECSuccess; } @@ -9956,21 +9934,6 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) return rv; } -static void -ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) { - unsigned int i; - - if (!ss->ssl3.predictedCertChain) - return; - - for (i = 0; ss->ssl3.predictedCertChain[i]; i++) { - CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]); - } - - PORT_Free(ss->ssl3.predictedCertChain); - ss->ssl3.predictedCertChain = NULL; -} - /* Called from ssl_DestroySocketContents() in sslsock.c */ void ssl3_DestroySSL3Info(sslSocket *ss) @@ -9994,9 +9957,6 @@ ssl3_DestroySSL3Info(sslSocket *ss) ss->ssl3.clientCertChain = NULL; } - if (ss->ssl3.predictedCertChain != NULL) - ssl3_CleanupPredictedPeerCertificates(ss); - /* clean up handshake */ if (ss->opt.bypassPKCS11) { SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); @@ -10030,10 +9990,7 @@ ssl3_DestroySSL3Info(sslSocket *ss) ss->ssl3.initialized = PR_FALSE; - if (ss->ssl3.nextProto.data) { - PORT_Free(ss->ssl3.nextProto.data); - ss->ssl3.nextProto.data = NULL; - } + SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); } /* End of ssl3con.c */ diff --git a/net/third_party/nss/ssl/ssl3ecc.c b/net/third_party/nss/ssl/ssl3ecc.c index 778c7ab..b9150f8 100644 --- a/net/third_party/nss/ssl/ssl3ecc.c +++ b/net/third_party/nss/ssl/ssl3ecc.c @@ -40,7 +40,7 @@ * ***** END LICENSE BLOCK ***** */ /* ECC code moved here from ssl3con.c */ -/* $Id: ssl3ecc.c,v 1.24 2010/03/15 08:03:14 nelson%bolyard.com Exp $ */ +/* $Id: ssl3ecc.c,v 1.26 2012/02/13 17:19:40 kaie%kuix.de Exp $ */ #include "nss.h" #include "cert.h" @@ -317,7 +317,7 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) } /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, - &pubKey, NULL); + &pubKey, ss->pkcs11PinArg); if (!privKey || !pubKey) { ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); rv = SECFailure; @@ -968,6 +968,7 @@ ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss) case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c index 6590ffc..412e799 100644 --- a/net/third_party/nss/ssl/ssl3ext.c +++ b/net/third_party/nss/ssl/ssl3ext.c @@ -41,7 +41,7 @@ * ***** END LICENSE BLOCK ***** */ /* TLS extension code moved here from ssl3ecc.c */ -/* $Id: ssl3ext.c,v 1.14 2010/04/03 19:19:07 nelson%bolyard.com Exp $ */ +/* $Id: ssl3ext.c,v 1.21 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ #include "nssrenam.h" #include "nss.h" @@ -56,7 +56,7 @@ static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL; static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL; -static unsigned char session_ticket_enc_key[32]; +static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH]; static unsigned char session_ticket_mac_key[SHA256_LENGTH]; static PRBool session_ticket_keys_initialized = PR_FALSE; @@ -78,6 +78,12 @@ static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes); static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); +static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); +static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); +static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, @@ -242,8 +248,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, { -1, NULL } }; @@ -256,8 +261,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, { -1, NULL } @@ -284,8 +288,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { #endif { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, - { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, - { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } /* any extra entries will appear as { 0, NULL } */ @@ -555,11 +558,12 @@ ssl3_SendSessionTicketXtn( } /* handle an incoming Next Protocol Negotiation extension. */ -SECStatus +static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) { - if (data->len != 0) { + if (ss->firstHsDone || data->len != 0) { /* Clients MUST send an empty NPN extension, if any. */ + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; } @@ -570,16 +574,20 @@ ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat * of the lengths may be 0 and the sum of the lengths must equal the length of * the block. */ SECStatus -ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length) { unsigned int offset = 0; while (offset < length) { - if (data[offset] == 0) { + unsigned int newOffset = offset + 1 + (unsigned int) data[offset]; + /* Reject embedded nulls to protect against buggy applications that + * store protocol identifiers in null-terminated strings. + */ + if (newOffset > length || data[offset] == 0) { PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; } - offset += (unsigned int)data[offset] + 1; + offset = newOffset; } if (offset > length) { @@ -590,39 +598,51 @@ ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) return SECSuccess; } -SECStatus +static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, - SECItem *data) + SECItem *data) { SECStatus rv; - unsigned char result[255]; - unsigned int result_len; + unsigned char resultBuffer[255]; + SECItem result = { siBuffer, resultBuffer, 0 }; + + if (ss->firstHsDone) { + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return SECFailure; + } rv = ssl3_ValidateNextProtoNego(data->data, data->len); if (rv != SECSuccess) return rv; - rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, - data->data, data->len, - result, &result_len); + /* ss->nextProtoCallback cannot normally be NULL if we negotiated the + * extension. However, It is possible that an application erroneously + * cleared the callback between the time we sent the ClientHello and now. + */ + PORT_Assert(ss->nextProtoCallback != NULL); + if (!ss->nextProtoCallback) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, + result.data, &result.len, sizeof resultBuffer); if (rv != SECSuccess) return rv; /* If the callback wrote more than allowed to |result| it has corrupted our * stack. */ - PORT_Assert(result_len <= sizeof(result)); + if (result.len > sizeof result) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + return SECFailure; + } - if (ss->ssl3.nextProto.data) - PORT_Free(ss->ssl3.nextProto.data); - ss->ssl3.nextProto.data = PORT_Alloc(result_len); - PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); - ss->ssl3.nextProto.len = result_len; - return SECSuccess; + SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); + return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); } -PRInt32 -ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, - PRBool append, - PRUint32 maxBytes) +static PRInt32 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append, + PRUint32 maxBytes) { PRInt32 extension_length; @@ -635,21 +655,21 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, if (append && maxBytes >= extension_length) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); if (rv != SECSuccess) goto loser; rv = ssl3_AppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) goto loser; ss->xtnData.advertised[ss->xtnData.numAdvertised++] = - ssl_next_proto_neg_xtn; + ssl_next_proto_nego_xtn; } else if (maxBytes < extension_length) { return 0; } return extension_length; - loser: +loser: return -1; } @@ -673,261 +693,6 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, return SECSuccess; } -/* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the - * client side. */ -PRInt32 -ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append, - PRUint32 maxBytes) -{ - PRInt32 extension_length; - PRBool send_empty; - CERTCertificate ** predictedCertChain; - - if (!ss->opt.enableCachedInfo) - return 0; - - predictedCertChain = ss->ssl3.predictedCertChain; - send_empty = (predictedCertChain == NULL); - - /* minimum extension: - * extension_type (2-bytes) + - * length(extension_data) (2-bytes) + - * length(cached_info) (2-bytes) + - */ - extension_length = send_empty ? 6 : 16; - - if (append && maxBytes >= extension_length) { - SECStatus rv; - - /* ExtensionType */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); - if (rv != SECSuccess) - return -1; - /* Extension Length */ - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - return -1; - if (send_empty) { - /* Cached Information Length */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; - } else { - PRUint64 certChainHash; - int i; - PRUint8* digestPtr = (PRUint8*) &certChainHash; - - /* Cached Information Length */ - rv = ssl3_AppendHandshakeNumber(ss, 10, 2); - if (rv != SECSuccess) - return -1; - /* Cached Information Type */ - rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); - if (rv != SECSuccess) - return -1; - /* hash length */ - rv = ssl3_AppendHandshakeNumber(ss, 8, 1); - if (rv != SECSuccess) - return -1; - /* hash */ - FNV1A64_Init(&certChainHash); - for (i = 0; predictedCertChain[i] != NULL; i++) { - unsigned int certLen = predictedCertChain[i]->derCert.len; - unsigned char certLenArray[3] = { - certLen >> 16, - certLen >> 8, - certLen - }; - FNV1A64_Update(&certChainHash, certLenArray, 3); - FNV1A64_Update(&certChainHash, - predictedCertChain[i]->derCert.data, certLen); - } - FNV1A64_Final(&certChainHash); - rv = ssl3_AppendHandshake(ss, &certChainHash, 8); - if (rv != SECSuccess) - return -1; - for (i = 0; i < 8; i++) { - ss->ssl3.certChainDigest[i] = digestPtr[i]; - } - } - - } else if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; - } - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = - ssl_cached_info_xtn; - return extension_length; -} - -SECStatus -ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, - SECItem *data) -{ - SECStatus rv; - unsigned char *cached_info = data->data; - unsigned int remaining_len; - - /* Ignore the extension if it isn't enabled. */ - if (!ss->opt.enableCachedInfo) - return SECSuccess; - - if (data->len < 2) - return SECFailure; - remaining_len = (cached_info[0] << 8) | cached_info[1]; - if (remaining_len > 2048 || remaining_len != data->len - 2) - return SECFailure; - cached_info += 2; - - /* Handle reconnaissance case. */ - if (remaining_len == 0) { - /* The client supports information caching, but provides no information - * about what information types it supports */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, - ssl3_ServerSendCachedInfoXtn); - return rv; - } - - /* Iterate over the CachedObjects and pick the first item of type - * certificate_chain, while ignoring everything else. */ - while (remaining_len >= 2) { - unsigned char cached_object_type = *cached_info++; - unsigned int cached_object_length = *cached_info++; - remaining_len -= 2; - if (remaining_len < cached_object_length) - return SECFailure; - if (cached_object_length != 8) /* The digest must be present. */ - return SECFailure; - if (cached_object_type == cached_info_certificate_chain && - !ss->ssl3.cachedInfoCertChainDigestReceived) { - ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE; - memcpy(ss->ssl3.certChainDigest, cached_info, 8); - } - remaining_len -= cached_object_length; - cached_info += cached_object_length; - } - - if (remaining_len != 0) - return SECFailure; - - if (ss->ssl3.cachedInfoCertChainDigestReceived) { - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, - ssl3_ServerSendCachedInfoXtn); - return SECSuccess; - } - - return SECSuccess; -} - -/* ssl3_ServerSendCachedInfoXtn builds the cached_info extension on the - * server side. */ -PRInt32 -ssl3_ServerSendCachedInfoXtn(sslSocket * ss, PRBool append, - PRUint32 maxBytes) -{ - PRInt32 extension_length = 2 /* extension type */ + - 2 /* extension length */ + - 2 /* cached_info length */ + - 1 /* CachedInformationType */ + - 1 /* hash value length (0) */; - SECStatus rv; - - PORT_Assert(ss->opt.enableCachedInfo); - - if (append && maxBytes >= extension_length) { - /* ExtensionType */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); - if (rv != SECSuccess) - return -1; - /* Extension Length */ - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - return -1; - /* Cached Information Length */ - rv = ssl3_AppendHandshakeNumber(ss, 2, 2); - if (rv != SECSuccess) - return -1; - /* Cached Information Type */ - rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); - if (rv != SECSuccess) - return -1; - /* hash length */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 1); - if (rv != SECSuccess) - return -1; - } else if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; - } - - return extension_length; -} - -SECStatus -ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, - SECItem *data) -{ - unsigned char * cached_info = data->data; - unsigned int remaining_cached_info_length; - PRBool has_correct_cert_chain = PR_FALSE; - - /* If we didn't request this extension, then the server may not echo it. */ - if (!ss->opt.enableCachedInfo) - return SECFailure; - - if (data->len == 0) { - /* The server supports information caching, but provides no information - * about what information types it supports */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - return SECSuccess; - } - - if (data->len < 2) - return SECFailure; - remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1]; - if (remaining_cached_info_length != data->len - 2) - return SECFailure; - cached_info += 2; - while (remaining_cached_info_length >= 2) { - /* The server supports only those CachedInformationType types that are - * identified by a present CachedObject */ - unsigned char cached_object_type; - unsigned int cached_object_length; - unsigned char cached_object_digest[8]; - cached_object_type = *cached_info++; - cached_object_length = *cached_info++; - remaining_cached_info_length -= 2; - if (remaining_cached_info_length < cached_object_length) - return SECFailure; - if (cached_object_length != 0 && cached_object_length != 8) - return SECFailure; - remaining_cached_info_length -= cached_object_length; - if (cached_object_type == cached_info_certificate_chain) { - if (cached_object_length == 0) - has_correct_cert_chain = PR_TRUE; - else { /* Hashes must match */ - int i; - for (i = 0; i < 8; i++) - cached_object_digest[i] = *cached_info++; - if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8)) - has_correct_cert_chain = PR_TRUE; - } - } - } - - if (remaining_cached_info_length != 0) - return SECFailure; - - if (has_correct_cert_chain) { - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - return SECSuccess; - } - - return SECFailure; -} - /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the * client side. See RFC 4366 section 3.6. */ PRInt32 @@ -1726,14 +1491,17 @@ no_ticket: SSL_GETPID(), ss->fd)); ssl3stats = SSL_GetStatistics(); SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures ); - if (sid) { - ssl_FreeSID(sid); - sid = NULL; - } } rv = SECSuccess; loser: + /* ss->sec.ci.sid == sid if it did NOT come here via goto statement + * in that case do not free sid + */ + if (sid && (ss->sec.ci.sid != sid)) { + ssl_FreeSID(sid); + sid = NULL; + } if (decrypted_state != NULL) { SECITEM_FreeItem(decrypted_state, PR_TRUE); decrypted_state = NULL; diff --git a/net/third_party/nss/ssl/ssl3gthr.c b/net/third_party/nss/ssl/ssl3gthr.c index 65d96f8..c6b09c7 100644 --- a/net/third_party/nss/ssl/ssl3gthr.c +++ b/net/third_party/nss/ssl/ssl3gthr.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: ssl3gthr.c,v 1.9.20.1 2010/07/31 04:33:52 wtc%google.com Exp $ */ +/* $Id: ssl3gthr.c,v 1.12 2012/02/11 12:57:28 kaie%kuix.de Exp $ */ #include "cert.h" #include "ssl.h" @@ -192,21 +192,53 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); do { - /* bring in the next sslv3 record. */ - rv = ssl3_GatherData(ss, &ss->gs, flags); - if (rv <= 0) { - return rv; + /* Without this, we may end up wrongly reporting + * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the + * peer while we are waiting to be restarted. + */ + ssl_GetSSL3HandshakeLock(ss); + rv = ss->ssl3.hs.restartTarget == NULL ? SECSuccess : SECFailure; + ssl_ReleaseSSL3HandshakeLock(ss); + if (rv != SECSuccess) { + PORT_SetError(PR_WOULD_BLOCK_ERROR); + return (int) SECFailure; } - - /* decipher it, and handle it if it's a handshake. - * If it's application data, ss->gs.buf will not be empty upon return. - * If it's a change cipher spec, alert, or handshake message, - * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess. + + /* Treat an empty msgState like a NULL msgState. (Most of the time + * when ssl3_HandleHandshake returns SECWouldBlock, it leaves + * behind a non-NULL but zero-length msgState). + * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record */ - cText.type = (SSL3ContentType)ss->gs.hdr[0]; - cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; - cText.buf = &ss->gs.inbuf; - rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); + if (ss->ssl3.hs.msgState.buf != NULL) { + if (ss->ssl3.hs.msgState.len == 0) { + ss->ssl3.hs.msgState.buf = NULL; + } + } + + if (ss->ssl3.hs.msgState.buf != NULL) { + /* ssl3_HandleHandshake previously returned SECWouldBlock and the + * as-yet-unprocessed plaintext of that previous handshake record. + * We need to process it now before we overwrite it with the next + * handshake record. + */ + rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); + } else { + /* bring in the next sslv3 record. */ + rv = ssl3_GatherData(ss, &ss->gs, flags); + if (rv <= 0) { + return rv; + } + + /* decipher it, and handle it if it's a handshake. + * If it's application data, ss->gs.buf will not be empty upon return. + * If it's a change cipher spec, alert, or handshake message, + * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess. + */ + cText.type = (SSL3ContentType)ss->gs.hdr[0]; + cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; + cText.buf = &ss->gs.inbuf; + rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); + } if (rv < 0) { return ss->recvdCloseNotify ? 0 : rv; } diff --git a/net/third_party/nss/ssl/ssl3prot.h b/net/third_party/nss/ssl/ssl3prot.h index aeaacdd..a350a3d 100644 --- a/net/third_party/nss/ssl/ssl3prot.h +++ b/net/third_party/nss/ssl/ssl3prot.h @@ -38,7 +38,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: ssl3prot.h,v 1.19 2010/06/24 09:24:18 nelson%bolyard.com Exp $ */ +/* $Id: ssl3prot.h,v 1.20 2011/10/29 00:29:11 bsmith%mozilla.com Exp $ */ #ifndef __ssl3proto_h_ #define __ssl3proto_h_ diff --git a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth.c index 8da5c66..8ccd1a4 100644 --- a/net/third_party/nss/ssl/sslauth.c +++ b/net/third_party/nss/ssl/sslauth.c @@ -33,7 +33,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslauth.c,v 1.16.66.1 2010/08/03 18:52:13 wtc%google.com Exp $ */ +/* $Id: sslauth.c,v 1.17 2010/08/03 18:48:45 wtc%google.com Exp $ */ #include "cert.h" #include "secitem.h" #include "ssl.h" @@ -62,10 +62,9 @@ SSL_PeerCertificate(PRFileDesc *fd) /* NEED LOCKS IN HERE. */ SECStatus SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs, - unsigned int *certsSize) + unsigned int *numCerts, unsigned int maxNumCerts) { sslSocket *ss; - unsigned int inSize = *certsSize; ssl3CertNode* cur; ss = ssl_FindSocket(fd); @@ -78,63 +77,23 @@ SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs, return SECFailure; if (ss->sec.peerCert == NULL) { - *certsSize = 0; + *numCerts = 0; return SECSuccess; } - *certsSize = 1; /* for the leaf certificate */ - if (inSize > 0) + *numCerts = 1; /* for the leaf certificate */ + if (maxNumCerts > 0) certs[0] = CERT_DupCertificate(ss->sec.peerCert); for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { - if (*certsSize < inSize) - certs[*certsSize] = CERT_DupCertificate(cur->cert); - (*certsSize)++; + if (*numCerts < maxNumCerts) + certs[*numCerts] = CERT_DupCertificate(cur->cert); + (*numCerts)++; } return SECSuccess; } -SECStatus -SSL_SetPredictedPeerCertificates(PRFileDesc *fd, CERTCertificate **certs, - unsigned int numCerts) -{ - sslSocket *ss; - unsigned int i; - - ss = ssl_FindSocket(fd); - if (!ss) { - SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedPeerCertificates", - SSL_GETPID(), fd)); - return SECFailure; - } - - ss->ssl3.predictedCertChain = - PORT_NewArray(CERTCertificate*, numCerts + 1); - if (!ss->ssl3.predictedCertChain) - return SECFailure; /* error code was set */ - for (i = 0; i < numCerts; i++) - ss->ssl3.predictedCertChain[i] = CERT_DupCertificate(certs[i]); - ss->ssl3.predictedCertChain[numCerts] = NULL; - - return SECSuccess; -} - -PRBool -SSL_CertChainDigestReceived(PRFileDesc *fd) -{ - sslSocket *ss; - - ss = ssl_FindSocket(fd); - if (!ss) { - SSL_DBG(("%d: SSL[%d]: bad socket in SSL_CertChainDigestReceived", - SSL_GETPID(), fd)); - return SECFailure; - } - - return ss->ssl3.cachedInfoCertChainDigestReceived; -} - /* NEED LOCKS IN HERE. */ CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd) diff --git a/net/third_party/nss/ssl/sslcon.c b/net/third_party/nss/ssl/sslcon.c index be626a4..500ea5d 100644 --- a/net/third_party/nss/ssl/sslcon.c +++ b/net/third_party/nss/ssl/sslcon.c @@ -37,7 +37,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslcon.c,v 1.40 2010/04/25 23:37:38 nelson%bolyard.com Exp $ */ +/* $Id: sslcon.c,v 1.45 2011/11/19 21:58:21 bsmith%mozilla.com Exp $ */ #include "nssrenam.h" #include "cert.h" @@ -518,7 +518,6 @@ ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) * ssl2_HandleMessage() <- ssl_Do1stHandshake() * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake() after ssl2_BeginClientHandshake() - * ssl2_RestartHandshakeAfterCertReq() <- Called from certdlgs.c in nav. * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() after ssl2_BeginServerHandshake() * @@ -765,7 +764,6 @@ done: } /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() - * ssl2_RestartHandshakeAfterCertReq() <- (application) * Acquires and releases the socket's xmitBufLock. */ static int @@ -1177,7 +1175,6 @@ loser: /* ** Called from: ssl2_HandleServerHelloMessage, ** ssl2_HandleClientSessionKeyMessage, -** ssl2_RestartHandshakeAfterServerCert, ** ssl2_HandleClientHelloMessage, ** */ @@ -1237,9 +1234,7 @@ ssl2_UseClearSendFunc(sslSocket *ss) * ssl2_HandleServerHelloMessage * ssl2_BeginClientHandshake * ssl2_HandleClientSessionKeyMessage - * ssl2_RestartHandshakeAfterCertReq * ssl3_RestartHandshakeAfterCertReq - * ssl2_RestartHandshakeAfterServerCert * ssl3_RestartHandshakeAfterServerCert * ssl2_HandleClientHelloMessage * ssl2_BeginServerHandshake @@ -2232,8 +2227,6 @@ ssl2_TriggerNextMessage(sslSocket *ss) ** ssl2_HandleVerifyMessage ** ssl2_HandleServerHelloMessage ** ssl2_HandleClientSessionKeyMessage -** ssl2_RestartHandshakeAfterCertReq -** ssl2_RestartHandshakeAfterServerCert */ static SECStatus ssl2_TryToFinish(sslSocket *ss) @@ -2267,7 +2260,6 @@ ssl2_TryToFinish(sslSocket *ss) /* ** Called from ssl2_HandleRequestCertificate -** ssl2_RestartHandshakeAfterCertReq */ static SECStatus ssl2_SignResponse(sslSocket *ss, @@ -2354,8 +2346,9 @@ ssl2_HandleRequestCertificate(sslSocket *ss) ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd, NULL, &cert, &key); if ( ret == SECWouldBlock ) { - ssl_SetAlwaysBlock(ss); - goto done; + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); + ret = -1; + goto loser; } if (ret) { @@ -2715,8 +2708,7 @@ ssl2_HandleMessage(sslSocket *ss) /************************************************************************/ -/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage or -** ssl2_RestartHandshakeAfterServerCert. +/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage. */ static SECStatus ssl2_HandleVerifyMessage(sslSocket *ss) @@ -2936,19 +2928,16 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); if ( rv ) { if ( rv == SECWouldBlock ) { - /* someone will handle this connection asynchronously*/ - - SSL_DBG(("%d: SSL[%d]: go to async cert handler", - SSL_GETPID(), ss->fd)); - ssl_ReleaseRecvBufLock(ss); - ssl_SetAlwaysBlock(ss); - return SECWouldBlock; + SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned " + "SECWouldBlock", SSL_GETPID(), ss->fd)); + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); + rv = SECFailure; + } else { + /* cert is bad */ + SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", + SSL_GETPID(), ss->fd, PORT_GetError())); } - /* cert is bad */ - SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", - SSL_GETPID(), ss->fd, PORT_GetError())); goto loser; - } /* cert is good */ } else { @@ -3125,11 +3114,11 @@ ssl2_BeginClientHandshake(sslSocket *ss) /* ssl3_SendClientHello will override this if it succeeds. */ ss->version = SSL_LIBRARY_VERSION_3_0; - ssl_GetXmitBufLock(ss); /***************************************/ ssl_GetSSL3HandshakeLock(ss); + ssl_GetXmitBufLock(ss); rv = ssl3_SendClientHello(ss); + ssl_ReleaseXmitBufLock(ss); ssl_ReleaseSSL3HandshakeLock(ss); - ssl_ReleaseXmitBufLock(ss); /***************************************/ return rv; } @@ -3331,133 +3320,6 @@ loser: } /* - * attempt to restart the handshake after asynchronously handling - * a request for the client's certificate. - * - * inputs: - * cert Client cert chosen by application. - * key Private key associated with cert. - * - * XXX: need to make ssl2 and ssl3 versions of this function agree on whether - * they take the reference, or bump the ref count! - * - * Return value: XXX - * - * Caller holds 1stHandshakeLock. - */ -int -ssl2_RestartHandshakeAfterCertReq(sslSocket * ss, - CERTCertificate * cert, - SECKEYPrivateKey * key) -{ - int ret; - SECStatus rv = SECSuccess; - SECItem response; - - if (ss->version >= SSL_LIBRARY_VERSION_3_0) - return SECFailure; - - response.data = NULL; - - /* generate error if no cert or key */ - if ( ( cert == NULL ) || ( key == NULL ) ) { - goto no_cert; - } - - /* generate signed response to the challenge */ - rv = ssl2_SignResponse(ss, key, &response); - if ( rv != SECSuccess ) { - goto no_cert; - } - - /* Send response message */ - ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response); - if (ret) { - goto no_cert; - } - - /* try to finish the handshake */ - ret = ssl2_TryToFinish(ss); - if (ret) { - goto loser; - } - - /* done with handshake */ - if (ss->handshake == 0) { - ret = SECSuccess; - goto done; - } - - /* continue handshake */ - ssl_GetRecvBufLock(ss); - ss->gs.recordLen = 0; - ssl_ReleaseRecvBufLock(ss); - - ss->handshake = ssl_GatherRecord1stHandshake; - ss->nextHandshake = ssl2_HandleMessage; - ret = ssl2_TriggerNextMessage(ss); - goto done; - -no_cert: - /* no cert - send error */ - ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE); - goto done; - -loser: - ret = SECFailure; -done: - /* free allocated data */ - if ( response.data ) { - PORT_Free(response.data); - } - - return ret; -} - - -/* restart an SSL connection that we stopped to run certificate dialogs -** XXX Need to document here how an application marks a cert to show that -** the application has accepted it (overridden CERT_VerifyCert). - * - * Return value: XXX - * - * Caller holds 1stHandshakeLock. -*/ -int -ssl2_RestartHandshakeAfterServerCert(sslSocket *ss) -{ - int rv = SECSuccess; - - if (ss->version >= SSL_LIBRARY_VERSION_3_0) - return SECFailure; - - /* SSL 2 - ** At this point we have a completed session key and our session - ** cipher is setup and ready to go. Switch to encrypted write routine - ** as all future message data is to be encrypted. - */ - ssl2_UseEncryptedSendFunc(ss); - - rv = ssl2_TryToFinish(ss); - if (rv == SECSuccess && ss->handshake != NULL) { - /* handshake is not yet finished. */ - - SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", - SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, - ss->sec.ci.elements)); - - ssl_GetRecvBufLock(ss); - ss->gs.recordLen = 0; /* mark it all used up. */ - ssl_ReleaseRecvBufLock(ss); - - ss->handshake = ssl_GatherRecord1stHandshake; - ss->nextHandshake = ssl2_HandleVerifyMessage; - } - - return rv; -} - -/* ** Handle the initial hello message from the client ** ** not static because ssl2_GatherData() tests ss->nextHandshake for this value. @@ -3852,3 +3714,9 @@ NSSSSL_VersionCheck(const char *importedVersion) c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; return NSS_VersionCheck(importedVersion); } + +const char * +NSSSSL_GetVersion(void) +{ + return NSS_VERSION; +} diff --git a/net/third_party/nss/ssl/sslerr.h b/net/third_party/nss/ssl/sslerr.h index 8710a43..9be063b 100644 --- a/net/third_party/nss/ssl/sslerr.h +++ b/net/third_party/nss/ssl/sslerr.h @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslerr.h,v 1.11.2.2 2010/09/01 19:47:11 wtc%google.com Exp $ */ +/* $Id: sslerr.h,v 1.19 2012/02/11 12:55:58 kaie%kuix.de Exp $ */ #ifndef __SSL_ERR_H_ #define __SSL_ERR_H_ @@ -57,11 +57,13 @@ SSL_ERROR_NO_CYPHER_OVERLAP = (SSL_ERROR_BASE + 2), */ SSL_ERROR_NO_CERTIFICATE /*_ALERT */ = (SSL_ERROR_BASE + 3), SSL_ERROR_BAD_CERTIFICATE = (SSL_ERROR_BASE + 4), +SSL_ERROR_UNUSED_5 = (SSL_ERROR_BASE + 5), /* error 5 is obsolete */ SSL_ERROR_BAD_CLIENT = (SSL_ERROR_BASE + 6), SSL_ERROR_BAD_SERVER = (SSL_ERROR_BASE + 7), SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE = (SSL_ERROR_BASE + 8), SSL_ERROR_UNSUPPORTED_VERSION = (SSL_ERROR_BASE + 9), +SSL_ERROR_UNUSED_10 = (SSL_ERROR_BASE + 10), /* error 10 is obsolete */ SSL_ERROR_WRONG_CERTIFICATE = (SSL_ERROR_BASE + 11), SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12), @@ -203,8 +205,13 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114), SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115), -SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 116), -SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 117), +SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 116), + +SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2 = (SSL_ERROR_BASE + 117), +SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS = (SSL_ERROR_BASE + 118), +SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS = (SSL_ERROR_BASE + 119), + +SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 120), SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ } SSLErrorCodes; diff --git a/net/third_party/nss/ssl/sslerrstrs.c b/net/third_party/nss/ssl/sslerrstrs.c new file mode 100644 index 0000000..a06f99e --- /dev/null +++ b/net/third_party/nss/ssl/sslerrstrs.c @@ -0,0 +1,66 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Red Hat, Inc + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "prerror.h" +#include "sslerr.h" +#include "prinit.h" +#include "nssutil.h" +#include "ssl.h" + +#define ER3(name, value, str) {#name, str}, + +static const struct PRErrorMessage ssltext[] = { +#include "SSLerrs.h" + {0,0} +}; + +static const struct PRErrorTable ssl_et = { + ssltext, "sslerr", SSL_ERROR_BASE, + (sizeof ssltext)/(sizeof ssltext[0]) +}; + +static PRStatus +ssl_InitializePRErrorTableOnce(void) { + return PR_ErrorInstallTable(&ssl_et); +} + +static PRCallOnceType once; + +SECStatus +ssl_InitializePRErrorTable(void) +{ + return (PR_SUCCESS == PR_CallOnce(&once, ssl_InitializePRErrorTableOnce)) + ? SECSuccess : SECFailure; +} diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h index ba17ed7..8f78670 100644 --- a/net/third_party/nss/ssl/sslimpl.h +++ b/net/third_party/nss/ssl/sslimpl.h @@ -39,7 +39,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslimpl.h,v 1.77.2.1 2010/07/31 04:33:52 wtc%google.com Exp $ */ +/* $Id: sslimpl.h,v 1.94 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ #ifndef __sslimpl_h_ #define __sslimpl_h_ @@ -324,7 +324,7 @@ typedef struct { typedef struct sslOptionsStr { /* If SSL_SetNextProtoNego has been called, then this contains the * list of supported protocols. */ - SECItem nextProtoNego; + SECItem nextProtoNego; unsigned int useSecurity : 1; /* 1 */ unsigned int useSocks : 1; /* 2 */ @@ -347,8 +347,8 @@ typedef struct sslOptionsStr { unsigned int enableRenegotiation : 2; /* 20-21 */ unsigned int requireSafeNegotiation : 1; /* 22 */ unsigned int enableFalseStart : 1; /* 23 */ - unsigned int enableOCSPStapling : 1; /* 24 */ - unsigned int enableCachedInfo : 1; /* 25 */ + unsigned int cbcRandomIV : 1; /* 24 */ + unsigned int enableOCSPStapling : 1; /* 25 */ unsigned int enableOBCerts : 1; /* 26 */ unsigned int encryptClientCerts : 1; /* 27 */ } sslOptions; @@ -773,10 +773,7 @@ struct TLSExtensionDataStr { PRUint32 sniNameArrSize; }; -typedef enum { - cached_info_certificate_chain = 1, - cached_info_trusted_cas = 2 -} TLSCachedInfoType; +typedef SECStatus (*sslRestartTarget)(sslSocket *); /* ** This is the "hs" member of the "ssl3" struct. @@ -803,8 +800,6 @@ const ssl3CipherSuiteDef *suite_def; unsigned long msg_len; SECItem ca_list; /* used only by client */ PRBool isResuming; /* are we resuming a session */ - PRBool rehandshake; /* immediately start another handshake - * when this one finishes */ PRBool usedStepDownKey; /* we did a server key exchange. */ PRBool sendingSCSV; /* instead of empty RI */ PRBool may_get_cert_status; /* the server echoed a @@ -827,6 +822,14 @@ const ssl3CipherSuiteDef *suite_def; #ifdef NSS_ENABLE_ECC PRUint32 negotiatedECCurves; /* bit mask */ #endif /* NSS_ENABLE_ECC */ + + PRBool authCertificatePending; + /* Which function should SSL_RestartHandshake* call if we're blocked? + * One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake, + * or ssl3_AlwaysFail */ + sslRestartTarget restartTarget; + /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */ + PRBool cacheSID; } SSL3HandshakeState; @@ -859,14 +862,6 @@ struct ssl3StateStr { CERTCertificateList *clientCertChain; /* used by client */ PRBool sendEmptyCert; /* used by client */ - /* TLS Cached Info Extension */ - CERTCertificate ** predictedCertChain; - /* An array terminated with a NULL. */ - PRUint8 certChainDigest[8]; - /* Used in cached info extension. Stored in network - * byte order. */ - PRBool cachedInfoCertChainDigestReceived; - int policy; /* This says what cipher suites we can do, and should * be either SSL_ALLOWED or SSL_RESTRICTED @@ -874,10 +869,7 @@ struct ssl3StateStr { PRArenaPool * peerCertArena; /* These are used to keep track of the peer CA */ void * peerCertChain; - /* Chain while we are trying to validate it. This - * does not include the leaf cert. It is actually a - * linked list of ssl3CertNode structs. - */ + /* chain while we are trying to validate it. */ CERTDistNames * ca_list; /* used by server. trusted CAs for this socket. */ PRBool initialized; @@ -886,10 +878,9 @@ struct ssl3StateStr { /* In a client: if the server supports Next Protocol Negotiation, then * this is the protocol that was negotiated. - * - * If the data pointer is non-NULL, then it is malloced data. */ - SECItem nextProto; - int nextProtoState; /* See NEXT_PROTO_* defines */ + */ + SECItem nextProto; + SSLNextProtoState nextProtoState; }; typedef struct { @@ -1210,7 +1201,6 @@ extern FILE * ssl_keylog_iob; extern CERTDistNames * ssl3_server_ca_list; extern PRUint32 ssl_sid_timeout; extern PRUint32 ssl3_sid_timeout; -extern PRBool ssl3_global_policy_some_restricted; extern const char * const ssl_cipherName[]; extern const char * const ssl3_cipherName[]; @@ -1223,6 +1213,10 @@ extern sslSessionIDUncacheFunc ssl_sid_uncache; SEC_BEGIN_PROTOS +/* Internal initialization and installation of the SSL error tables */ +extern SECStatus ssl_Init(void); +extern SECStatus ssl_InitializePRErrorTable(void); + /* Implementation of ops for default (non socks, non secure) case */ extern int ssl_DefConnect(sslSocket *ss, const PRNetAddr *addr); extern PRFileDesc *ssl_DefAccept(sslSocket *ss, PRNetAddr *addr); @@ -1320,7 +1314,7 @@ extern PRBool ssl_FdIsBlocking(PRFileDesc *fd); extern PRBool ssl_SocketIsBlocking(sslSocket *ss); -extern void ssl_SetAlwaysBlock(sslSocket *ss); +extern void ssl3_SetAlwaysBlock(sslSocket *ss); extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled); @@ -1331,15 +1325,24 @@ extern PRBool ssl3_CanFalseStart(sslSocket *ss); #define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock) #define SSL_UNLOCK_WRITER(ss) if (ss->sendLock) PZ_Unlock(ss->sendLock) +/* firstHandshakeLock -> recvBufLock */ #define ssl_Get1stHandshakeLock(ss) \ - { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->firstHandshakeLock); } + { if (!ss->opt.noLocks) { \ + PORT_Assert(PZ_InMonitor((ss)->firstHandshakeLock) || \ + !ssl_HaveRecvBufLock(ss)); \ + PZ_EnterMonitor((ss)->firstHandshakeLock); \ + } } #define ssl_Release1stHandshakeLock(ss) \ { if (!ss->opt.noLocks) PZ_ExitMonitor((ss)->firstHandshakeLock); } #define ssl_Have1stHandshakeLock(ss) \ (PZ_InMonitor((ss)->firstHandshakeLock)) +/* ssl3HandshakeLock -> xmitBufLock */ #define ssl_GetSSL3HandshakeLock(ss) \ - { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->ssl3HandshakeLock); } + { if (!ss->opt.noLocks) { \ + PORT_Assert(!ssl_HaveXmitBufLock(ss)); \ + PZ_EnterMonitor((ss)->ssl3HandshakeLock); \ + } } #define ssl_ReleaseSSL3HandshakeLock(ss) \ { if (!ss->opt.noLocks) PZ_ExitMonitor((ss)->ssl3HandshakeLock); } #define ssl_HaveSSL3HandshakeLock(ss) \ @@ -1349,6 +1352,8 @@ extern PRBool ssl3_CanFalseStart(sslSocket *ss); { if (!ss->opt.noLocks) NSSRWLock_LockRead((ss)->specLock); } #define ssl_ReleaseSpecReadLock(ss) \ { if (!ss->opt.noLocks) NSSRWLock_UnlockRead((ss)->specLock); } +/* NSSRWLock_HaveReadLock is not exported so there's no + * ssl_HaveSpecReadLock macro. */ #define ssl_GetSpecWriteLock(ss) \ { if (!ss->opt.noLocks) NSSRWLock_LockWrite((ss)->specLock); } @@ -1357,13 +1362,19 @@ extern PRBool ssl3_CanFalseStart(sslSocket *ss); #define ssl_HaveSpecWriteLock(ss) \ (NSSRWLock_HaveWriteLock((ss)->specLock)) +/* recvBufLock -> ssl3HandshakeLock -> xmitBufLock */ #define ssl_GetRecvBufLock(ss) \ - { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->recvBufLock); } + { if (!ss->opt.noLocks) { \ + PORT_Assert(!ssl_HaveSSL3HandshakeLock(ss)); \ + PORT_Assert(!ssl_HaveXmitBufLock(ss)); \ + PZ_EnterMonitor((ss)->recvBufLock); \ + } } #define ssl_ReleaseRecvBufLock(ss) \ { if (!ss->opt.noLocks) PZ_ExitMonitor( (ss)->recvBufLock); } #define ssl_HaveRecvBufLock(ss) \ (PZ_InMonitor((ss)->recvBufLock)) +/* xmitBufLock -> specLock */ #define ssl_GetXmitBufLock(ss) \ { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->xmitBufLock); } #define ssl_ReleaseXmitBufLock(ss) \ @@ -1382,23 +1393,17 @@ extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, /* These functions are called from secnav, even though they're "private". */ extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error); -extern int SSL_RestartHandshakeAfterServerCert(struct sslSocketStr *ss); extern sslSocket *ssl_FindSocket(PRFileDesc *fd); extern void ssl_FreeSocket(struct sslSocketStr *ssl); extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc); -extern int ssl2_RestartHandshakeAfterCertReq(sslSocket * ss, - CERTCertificate * cert, - SECKEYPrivateKey * key); - extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, CERTCertificate * cert, SECKEYPrivateKey * key, CERTCertificateList *certChain); -extern int ssl2_RestartHandshakeAfterServerCert(sslSocket *ss); -extern int ssl3_RestartHandshakeAfterServerCert(sslSocket *ss); +extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error); /* * for dealing with SSL 3.0 clients sending SSL 2.0 format hellos @@ -1563,20 +1568,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ClientHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ServerHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); @@ -1594,10 +1591,6 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append, */ extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); -extern PRInt32 ssl3_ClientSendCachedInfoXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); -extern PRInt32 ssl3_ServerSendCachedInfoXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); extern PRInt32 ssl3_SendOBCertXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); @@ -1606,7 +1599,7 @@ extern PRInt32 ssl3_SendOBCertXtn(sslSocket *ss, PRBool append, * fails to do so. If cert and keyPair are NULL - unconfigures * sslSocket of kea type.*/ extern SECStatus ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, - CERTCertificateList *certChain, + const CERTCertificateList *certChain, ssl3KeyPair *keyPair, SSLKEAType kea); /* Return key type for the cert */ extern SSLKEAType ssl_FindCertKEAType(CERTCertificate * cert); @@ -1617,10 +1610,6 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); #endif -extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); -extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, - unsigned short length); /* call the registered extension handlers. */ extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss, @@ -1642,6 +1631,9 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey, #define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */ #define TLS_EX_SESS_TICKET_VERSION (0x0100) +extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, + unsigned int length); + /* Construct a new NSPR socket for the app to use */ extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd); extern void ssl_FreePRSocket(PRFileDesc *fd); @@ -1729,13 +1721,6 @@ SECStatus ssl3_TLSPRFWithMasterSecret( unsigned int valLen, unsigned char *out, unsigned int outLen); -/********************** FNV hash *********************/ - -void FNV1A64_Init(PRUint64 *digest); -void FNV1A64_Update(PRUint64 *digest, const unsigned char *data, - unsigned int length); -void FNV1A64_Final(PRUint64 *digest); - #ifdef TRACE #define SSL_TRACE(msg) ssl_Trace msg #else diff --git a/net/third_party/nss/ssl/sslinfo.c b/net/third_party/nss/ssl/sslinfo.c index cf870c7..ea51039 100644 --- a/net/third_party/nss/ssl/sslinfo.c +++ b/net/third_party/nss/ssl/sslinfo.c @@ -35,7 +35,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslinfo.c,v 1.23.2.1 2010/09/02 01:13:46 wtc%google.com Exp $ */ +/* $Id: sslinfo.c,v 1.24 2010/09/02 01:12:57 wtc%google.com Exp $ */ #include "ssl.h" #include "sslimpl.h" #include "sslproto.h" diff --git a/net/third_party/nss/ssl/fnv1a64.c b/net/third_party/nss/ssl/sslinit.c index c7c4b08..bd75bbf 100644 --- a/net/third_party/nss/ssl/fnv1a64.c +++ b/net/third_party/nss/ssl/sslinit.c @@ -1,6 +1,5 @@ /* - * FNV1A64 Hash - * http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param + * NSS utility functions * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -18,12 +17,11 @@ * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is - * Netscape Communications Corporation. + * Red Hat Inc. * Portions created by the Initial Developer are Copyright (C) 1994-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Adam Langley, Google Inc. * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -38,35 +36,26 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ - -/* $Id: fnv1a64.c,v 1.0 2010/08/09 13:00:00 agl%google.com Exp $ */ +/* $Id: sslinit.c,v 1.2 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */ #include "prtypes.h" -#include "prnetdb.h" - -/* Older versions of Visual C++ don't support the 'ull' suffix. */ -#ifdef _MSC_VER -static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ui64; -static const PRUint64 FNV1A64_PRIME = 1099511628211ui64; -#else -static const PRUint64 FNV1A64_OFFSET_BASIS = 14695981039346656037ull; -static const PRUint64 FNV1A64_PRIME = 1099511628211ull; -#endif - -void FNV1A64_Init(PRUint64* digest) { - *digest = FNV1A64_OFFSET_BASIS; -} +#include "prinit.h" +#include "seccomon.h" +#include "secerr.h" +#include "ssl.h" +#include "sslimpl.h" -void FNV1A64_Update(PRUint64* digest, const unsigned char *data, - unsigned int length) { - unsigned int i; +static int ssl_inited = 0; - for (i = 0; i < length; i++) { - *digest ^= data[i]; - *digest *= FNV1A64_PRIME; +SECStatus +ssl_Init(void) +{ + if (!ssl_inited) { + if (ssl_InitializePRErrorTable() != SECSuccess) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return (SECFailure); + } + ssl_inited = 1; } -} - -void FNV1A64_Final(PRUint64 *digest) { - *digest = PR_htonll(*digest); + return SECSuccess; } diff --git a/net/third_party/nss/ssl/sslmutex.c b/net/third_party/nss/ssl/sslmutex.c index 8403365..ab612d6 100644 --- a/net/third_party/nss/ssl/sslmutex.c +++ b/net/third_party/nss/ssl/sslmutex.c @@ -33,7 +33,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslmutex.c,v 1.25 2010/04/03 18:27:33 nelson%bolyard.com Exp $ */ +/* $Id: sslmutex.c,v 1.27 2011/10/01 00:11:02 wtc%google.com Exp $ */ #include "seccomon.h" /* This ifdef should match the one in sslsnce.c */ @@ -168,7 +168,7 @@ loser: } SECStatus -sslMutex_Destroy(sslMutex *pMutex) +sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) { if (PR_FALSE == pMutex->isMultiProcess) { return single_process_sslMutex_Destroy(pMutex); @@ -180,6 +180,10 @@ sslMutex_Destroy(sslMutex *pMutex) close(pMutex->u.pipeStr.mPipes[0]); close(pMutex->u.pipeStr.mPipes[1]); + if (processLocal) { + return SECSuccess; + } + pMutex->u.pipeStr.mPipes[0] = -1; pMutex->u.pipeStr.mPipes[1] = -1; pMutex->u.pipeStr.mPipes[2] = -1; @@ -409,7 +413,7 @@ sslMutex_Init(sslMutex *pMutex, int shared) } SECStatus -sslMutex_Destroy(sslMutex *pMutex) +sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) { HANDLE hMutex; int rv; @@ -435,9 +439,10 @@ sslMutex_Destroy(sslMutex *pMutex) } rv = CloseHandle(hMutex); /* ignore error */ - if (rv) { + if (!processLocal && rv) { pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE; - } else { + } + if (!rv) { nss_MD_win32_map_default_error(GetLastError()); retvalue = SECFailure; } @@ -557,12 +562,17 @@ sslMutex_Init(sslMutex *pMutex, int shared) } SECStatus -sslMutex_Destroy(sslMutex *pMutex) +sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) { int rv; if (PR_FALSE == pMutex->isMultiProcess) { return single_process_sslMutex_Destroy(pMutex); } + + /* semaphores are global resources. See SEM_DESTROY(3) man page */ + if (processLocal) { + return SECSuccess; + } do { rv = sem_destroy(&pMutex->u.sem); } while (rv < 0 && errno == EINTR); @@ -623,7 +633,7 @@ sslMutex_Init(sslMutex *pMutex, int shared) } SECStatus -sslMutex_Destroy(sslMutex *pMutex) +sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) { PR_ASSERT(pMutex); if (PR_FALSE == pMutex->isMultiProcess) { diff --git a/net/third_party/nss/ssl/sslmutex.h b/net/third_party/nss/ssl/sslmutex.h index 0fdb685..1ea2465 100644 --- a/net/third_party/nss/ssl/sslmutex.h +++ b/net/third_party/nss/ssl/sslmutex.h @@ -33,7 +33,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslmutex.h,v 1.12 2009/06/05 02:34:15 nelson%bolyard.com Exp $ */ +/* $Id: sslmutex.h,v 1.13 2011/09/30 23:27:08 rrelyea%redhat.com Exp $ */ #ifndef __SSLMUTEX_H_ #define __SSLMUTEX_H_ 1 @@ -138,7 +138,10 @@ SEC_BEGIN_PROTOS extern SECStatus sslMutex_Init(sslMutex *sem, int shared); -extern SECStatus sslMutex_Destroy(sslMutex *sem); +/* If processLocal is set to true, then just free resources which are *only* associated + * with the current process. Leave any shared resources (including the state of + * shared memory) intact. */ +extern SECStatus sslMutex_Destroy(sslMutex *sem, PRBool processLocal); extern SECStatus sslMutex_Unlock(sslMutex *sem); diff --git a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c index 64adc1f..3fd6c8fa 100644 --- a/net/third_party/nss/ssl/sslnonce.c +++ b/net/third_party/nss/ssl/sslnonce.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslnonce.c,v 1.25 2008/03/10 00:01:28 wtc%google.com Exp $ */ +/* $Id: sslnonce.c,v 1.26 2011/03/24 01:40:14 alexei.volkov.bugs%sun.com Exp $ */ #include "cert.h" #include "pk11pub.h" @@ -226,6 +226,9 @@ ssl_DestroySID(sslSessionID *sid) if (sid->u.ssl3.sessionTicket.ticket.data) { SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE); } + if (sid->u.ssl3.srvName.data) { + SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); + } PORT_ZFree(sid, sizeof(sslSessionID)); } diff --git a/net/third_party/nss/ssl/sslreveal.c b/net/third_party/nss/ssl/sslreveal.c index 0b9bb82..a404033 100644 --- a/net/third_party/nss/ssl/sslreveal.c +++ b/net/third_party/nss/ssl/sslreveal.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslreveal.c,v 1.7.2.1 2010/08/03 18:52:13 wtc%google.com Exp $ */ +/* $Id: sslreveal.c,v 1.8 2010/08/03 18:48:45 wtc%google.com Exp $ */ #include "cert.h" #include "ssl.h" diff --git a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c index 7105125..16fd203 100644 --- a/net/third_party/nss/ssl/sslsecur.c +++ b/net/third_party/nss/ssl/sslsecur.c @@ -37,7 +37,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslsecur.c,v 1.43.2.2 2010/08/26 18:06:55 wtc%google.com Exp $ */ +/* $Id: sslsecur.c,v 1.57 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ #include "cert.h" #include "secitem.h" #include "keyhi.h" @@ -84,7 +84,8 @@ * * 3. SECWouldBlock was returned by one of the callback functions, via * one of these paths: - * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> ss->getClientAuthData() + * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> + * ss->getClientAuthData() * * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert() * @@ -117,6 +118,7 @@ ssl_Do1stHandshake(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); + PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); if (ss->handshake == 0) { /* Previous handshake finished. Switch to next one */ @@ -157,6 +159,7 @@ ssl_Do1stHandshake(sslSocket *ss) PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); + PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); if (rv == SECWouldBlock) { PORT_SetError(PR_WOULD_BLOCK_ERROR); @@ -170,7 +173,7 @@ ssl_Do1stHandshake(sslSocket *ss) * retry on a connection on the next read/write. */ static SECStatus -AlwaysBlock(sslSocket *ss) +ssl3_AlwaysBlock(sslSocket *ss) { PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */ return SECWouldBlock; @@ -180,10 +183,10 @@ AlwaysBlock(sslSocket *ss) * set the initial handshake state machine to block */ void -ssl_SetAlwaysBlock(sslSocket *ss) +ssl3_SetAlwaysBlock(sslSocket *ss) { if (!ss->firstHsDone) { - ss->handshake = AlwaysBlock; + ss->handshake = ssl3_AlwaysBlock; ss->nextHandshake = 0; } } @@ -235,7 +238,6 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) /* Reset handshake state */ ssl_Get1stHandshakeLock(ss); - ssl_GetSSL3HandshakeLock(ss); ss->firstHsDone = PR_FALSE; if ( asServer ) { @@ -252,6 +254,8 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) status = ssl_InitGather(&ss->gs); ssl_ReleaseRecvBufLock(ss); + ssl_GetSSL3HandshakeLock(ss); + /* ** Blow away old security state and get a fresh setup. */ @@ -686,7 +690,7 @@ static PRStatus serverCAListSetup(void *arg) SECStatus ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, - CERTCertificateList *certChain, + const CERTCertificateList *certChain, ssl3KeyPair *keyPair, SSLKEAType kea) { CERTCertificateList *localCertChain = NULL; @@ -764,6 +768,15 @@ SECStatus SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, SECKEYPrivateKey *key, SSL3KEAType kea) { + + return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea); +} + +SECStatus +SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, + const CERTCertificateList *certChainOpt, + SECKEYPrivateKey *key, SSL3KEAType kea) +{ sslSocket *ss; SECKEYPublicKey *pubKey = NULL; ssl3KeyPair *keyPair = NULL; @@ -834,7 +847,7 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, } pubKey = NULL; /* adopted by serverKeyPair */ } - if (ssl_ConfigSecureServer(ss, cert, NULL, + if (ssl_ConfigSecureServer(ss, cert, certChainOpt, keyPair, kea) == SECFailure) { goto loser; } @@ -1212,12 +1225,15 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) if (!ss->firstHsDone) { PRBool canFalseStart = PR_FALSE; ssl_Get1stHandshakeLock(ss); - if (ss->version >= SSL_LIBRARY_VERSION_3_0 && - (ss->ssl3.hs.ws == wait_change_cipher || - ss->ssl3.hs.ws == wait_finished || - ss->ssl3.hs.ws == wait_new_session_ticket) && - ssl3_CanFalseStart(ss)) { - canFalseStart = PR_TRUE; + if (ss->version >= SSL_LIBRARY_VERSION_3_0) { + ssl_GetSSL3HandshakeLock(ss); + if ((ss->ssl3.hs.ws == wait_change_cipher || + ss->ssl3.hs.ws == wait_finished || + ss->ssl3.hs.ws == wait_new_session_ticket) && + ssl3_CanFalseStart(ss)) { + canFalseStart = PR_TRUE; + } + ssl_ReleaseSSL3HandshakeLock(ss); } if (!canFalseStart && (ss->handshake || ss->nextHandshake || ss->securityHandshake)) { @@ -1510,37 +1526,51 @@ SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd, if (certChain != NULL) { CERT_DestroyCertificateList(certChain); } - ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key); + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); + ret = SECFailure; } ssl_Release1stHandshakeLock(ss); /************************************/ return ret; } - -/* restart an SSL connection that we stopped to run certificate dialogs -** XXX Need to document here how an application marks a cert to show that -** the application has accepted it (overridden CERT_VerifyCert). - * - * XXX This code only works on the initial handshake on a connection, XXX - * It does not work on a subsequent handshake (redo). - * - * Return value: XXX -*/ +/* DO NOT USE. This function was exported in ssl.def with the wrong signature; + * this implementation exists to maintain link-time compatibility. + */ int -SSL_RestartHandshakeAfterServerCert(sslSocket *ss) +SSL_RestartHandshakeAfterServerCert(sslSocket * ss) { - int rv = SECSuccess; + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return -1; +} - ssl_Get1stHandshakeLock(ss); +/* See documentation in ssl.h */ +SECStatus +SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error) +{ + SECStatus rv; + sslSocket *ss = ssl_FindSocket(fd); - if (ss->version >= SSL_LIBRARY_VERSION_3_0) { - rv = ssl3_RestartHandshakeAfterServerCert(ss); + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete", + SSL_GETPID(), fd)); + return SECFailure; + } + + ssl_Get1stHandshakeLock(ss); + + if (!ss->ssl3.initialized) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; + } else if (ss->version < SSL_LIBRARY_VERSION_3_0) { + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); + rv = SECFailure; } else { - rv = ssl2_RestartHandshakeAfterServerCert(ss); + rv = ssl3_AuthCertificateComplete(ss, error); } ssl_Release1stHandshakeLock(ss); + return rv; } diff --git a/net/third_party/nss/ssl/sslsnce.c b/net/third_party/nss/ssl/sslsnce.c index 6c73f25..9de8d2c 100644 --- a/net/third_party/nss/ssl/sslsnce.c +++ b/net/third_party/nss/ssl/sslsnce.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslsnce.c,v 1.54 2010/07/05 19:31:56 alexei.volkov.bugs%sun.com Exp $ */ +/* $Id: sslsnce.c,v 1.59 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */ /* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server * cache sids! @@ -1026,15 +1026,16 @@ CloseCache(cacheDesc *cache) int locks_initialized = cache->numSIDCacheLocksInitialized; if (cache->cacheMem) { - /* If everInherited is true, this shared cache was (and may still - ** be) in use by multiple processes. We do not wish to destroy - ** the mutexes while they are still in use. - */ - if (cache->sharedCache && - PR_FALSE == cache->sharedCache->everInherited) { + if (cache->sharedCache) { sidCacheLock *pLock = cache->sidCacheLocks; for (; locks_initialized > 0; --locks_initialized, ++pLock ) { - sslMutex_Destroy(&pLock->mutex); + /* If everInherited is true, this shared cache was (and may + ** still be) in use by multiple processes. We do not wish to + ** destroy the mutexes while they are still in use, but we do + ** want to free mutex resources associated with this process. + */ + sslMutex_Destroy(&pLock->mutex, + cache->sharedCache->everInherited); } } if (cache->shared) { @@ -1331,6 +1332,11 @@ ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache, PORT_Assert(sizeof(certCacheEntry) == 4096); PORT_Assert(sizeof(srvNameCacheEntry) == 1072); + rv = ssl_Init(); + if (rv != SECSuccess) { + return rv; + } + myPid = SSL_GETPID(); if (!directory) { directory = DEFAULT_CACHE_DIRECTORY; @@ -1511,6 +1517,11 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString) int locks_initialized = 0; int locks_to_initialize = 0; #endif + SECStatus status = ssl_Init(); + + if (status != SECSuccess) { + return status; + } myPid = SSL_GETPID(); @@ -1863,17 +1874,25 @@ WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey, } static PRBool -GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, - unsigned char *keyName, PK11SymKey **aesKey, - PK11SymKey **macKey) +GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, + PK11SymKey **macKey) { PK11SlotInfo *slot; CK_MECHANISM_TYPE mechanismArray[2]; PK11SymKey *aesKeyTmp = NULL; PK11SymKey *macKeyTmp = NULL; cacheDesc *cache = &globalCache; + uint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN]; + uint8 *ticketKeyNameSuffix; - if (PK11_GenerateRandom(cache->ticketKeyNameSuffix, + if (!cache->cacheMem) { + /* cache is not initalized. Use stack buffer */ + ticketKeyNameSuffix = ticketKeyNameSuffixLocal; + } else { + ticketKeyNameSuffix = cache->ticketKeyNameSuffix; + } + + if (PK11_GenerateRandom(ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) { SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.", SSL_GETPID(), "unknown")); @@ -1885,9 +1904,10 @@ GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg); if (slot) { - aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL, 32, pwArg); - macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL, SHA256_LENGTH, - pwArg); + aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL, + AES_256_KEY_LENGTH, pwArg); + macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL, + SHA256_LENGTH, pwArg); PK11_FreeSlot(slot); } @@ -1896,15 +1916,39 @@ GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, SSL_GETPID(), "unknown")); goto loser; } + PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN); + *aesKey = aesKeyTmp; + *macKey = macKeyTmp; + return PR_TRUE; - /* Export the keys to the shared cache in wrapped form. */ - if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)) - goto loser; - if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)) - goto loser; +loser: + if (aesKeyTmp) + PK11_FreeSymKey(aesKeyTmp); + if (macKeyTmp) + PK11_FreeSymKey(macKeyTmp); + return PR_FALSE; +} - PORT_Memcpy(keyName, cache->ticketKeyNameSuffix, - SESS_TICKET_KEY_VAR_NAME_LEN); +static PRBool +GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, + unsigned char *keyName, PK11SymKey **aesKey, + PK11SymKey **macKey) +{ + PK11SymKey *aesKeyTmp = NULL; + PK11SymKey *macKeyTmp = NULL; + cacheDesc *cache = &globalCache; + + if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) { + goto loser; + } + + if (cache->cacheMem) { + /* Export the keys to the shared cache in wrapped form. */ + if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)) + goto loser; + if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)) + goto loser; + } *aesKey = aesKeyTmp; *macKey = macKeyTmp; return PR_TRUE; @@ -1971,6 +2015,12 @@ ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey, PRBool keysGenerated = PR_FALSE; cacheDesc *cache = &globalCache; + if (!cache->cacheMem) { + /* cache is uninitialized. Generate keys and return them + * without caching. */ + return GenerateTicketKeys(pwArg, keyName, aesKey, macKey); + } + now = LockSidCacheLock(cache->keyCacheLock, now); if (!now) return rv; @@ -2000,33 +2050,58 @@ ssl_GetSessionTicketKeys(unsigned char *keyName, unsigned char *encKey, PRBool rv = PR_FALSE; PRUint32 now = 0; cacheDesc *cache = &globalCache; + uint8 ticketMacKey[AES_256_KEY_LENGTH], ticketEncKey[SHA256_LENGTH]; + uint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN]; + uint8 *ticketMacKeyPtr, *ticketEncKeyPtr, *ticketKeyNameSuffix; + PRBool cacheIsEnabled = PR_TRUE; - /* Grab lock. */ - now = LockSidCacheLock(cache->keyCacheLock, now); - if (!now) - return rv; + if (!cache->cacheMem) { /* cache is uninitialized */ + cacheIsEnabled = PR_FALSE; + ticketKeyNameSuffix = ticketKeyNameSuffixLocal; + ticketEncKeyPtr = ticketEncKey; + ticketMacKeyPtr = ticketMacKey; + } else { + /* these values have constant memory locations in the cache. + * Ok to reference them without holding the lock. */ + ticketKeyNameSuffix = cache->ticketKeyNameSuffix; + ticketEncKeyPtr = cache->ticketEncKey->bytes; + ticketMacKeyPtr = cache->ticketMacKey->bytes; + } - if (!*(cache->ticketKeysValid)) { - if (PK11_GenerateRandom(cache->ticketKeyNameSuffix, + if (cacheIsEnabled) { + /* Grab lock if initialized. */ + now = LockSidCacheLock(cache->keyCacheLock, now); + if (!now) + return rv; + } + /* Going to regenerate keys on every call if cache was not + * initialized. */ + if (!cacheIsEnabled || !*(cache->ticketKeysValid)) { + if (PK11_GenerateRandom(ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) goto loser; - if (PK11_GenerateRandom(cache->ticketEncKey->bytes, 32) != SECSuccess) + if (PK11_GenerateRandom(ticketEncKeyPtr, + AES_256_KEY_LENGTH) != SECSuccess) goto loser; - if (PK11_GenerateRandom(cache->ticketMacKey->bytes, - SHA256_LENGTH) != SECSuccess) + if (PK11_GenerateRandom(ticketMacKeyPtr, + SHA256_LENGTH) != SECSuccess) goto loser; - *(cache->ticketKeysValid) = 1; + if (cacheIsEnabled) { + *(cache->ticketKeysValid) = 1; + } } rv = PR_TRUE; loser: - UnlockSidCacheLock(cache->keyCacheLock); + if (cacheIsEnabled) { + UnlockSidCacheLock(cache->keyCacheLock); + } if (rv) { - PORT_Memcpy(keyName, cache->ticketKeyNameSuffix, - SESS_TICKET_KEY_VAR_NAME_LEN); - PORT_Memcpy(encKey, cache->ticketEncKey->bytes, 32); - PORT_Memcpy(macKey, cache->ticketMacKey->bytes, SHA256_LENGTH); + PORT_Memcpy(keyName, ticketKeyNameSuffix, + SESS_TICKET_KEY_VAR_NAME_LEN); + PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH); + PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH); } return rv; } diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c index eae62bf..c183566 100644 --- a/net/third_party/nss/ssl/sslsock.c +++ b/net/third_party/nss/ssl/sslsock.c @@ -40,7 +40,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslsock.c,v 1.67.2.1 2010/07/31 04:33:52 wtc%google.com Exp $ */ +/* $Id: sslsock.c,v 1.82 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ #include "seccomon.h" #include "cert.h" #include "keyhi.h" @@ -163,19 +163,19 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */ ** default settings for socket enables */ static sslOptions ssl_defaults = { - { siBuffer, NULL, 0 }, /* nextProtoNego */ + { siBuffer, NULL, 0 }, /* nextProtoNego */ PR_TRUE, /* useSecurity */ PR_FALSE, /* useSocks */ PR_FALSE, /* requestCertificate */ 2, /* requireCertificate */ PR_FALSE, /* handshakeAsClient */ PR_FALSE, /* handshakeAsServer */ - PR_TRUE, /* enableSSL2 */ + PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */ PR_TRUE, /* enableSSL3 */ PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */ PR_FALSE, /* noCache */ PR_FALSE, /* fdx */ - PR_TRUE, /* v2CompatibleHello */ + PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */ PR_TRUE, /* detectRollBack */ PR_FALSE, /* noStepDown */ PR_FALSE, /* bypassPKCS11 */ @@ -185,8 +185,8 @@ static sslOptions ssl_defaults = { 2, /* enableRenegotiation (default: requires extension) */ PR_FALSE, /* requireSafeNegotiation */ PR_FALSE, /* enableFalseStart */ + PR_TRUE, /* cbcRandomIV */ PR_FALSE, /* enableOCSPStapling */ - PR_FALSE, /* enableCachedInfo */ PR_FALSE, /* enableOBCerts */ PR_FALSE, /* encryptClientCerts */ }; @@ -211,6 +211,7 @@ char lockStatus[] = "Locks are ENABLED. "; /* forward declarations. */ static sslSocket *ssl_NewSocket(PRBool makeLocks); static SECStatus ssl_MakeLocks(sslSocket *ss); +static void ssl_SetDefaultsFromEnvironment(void); static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id); @@ -447,10 +448,7 @@ ssl_DestroySocketContents(sslSocket *ss) ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); ss->ephemeralECDHKeyPair = NULL; } - if (ss->opt.nextProtoNego.data) { - PORT_Free(ss->opt.nextProtoNego.data); - ss->opt.nextProtoNego.data = NULL; - } + SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE); PORT_Assert(!ss->xtnData.sniNameArr); if (ss->xtnData.sniNameArr) { PORT_Free(ss->xtnData.sniNameArr); @@ -746,12 +744,12 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) ss->opt.enableFalseStart = on; break; - case SSL_ENABLE_OCSP_STAPLING: - ss->opt.enableOCSPStapling = on; + case SSL_CBC_RANDOM_IV: + ss->opt.cbcRandomIV = on; break; - case SSL_ENABLE_CACHED_INFO: - ss->opt.enableCachedInfo = on; + case SSL_ENABLE_OCSP_STAPLING: + ss->opt.enableOCSPStapling = on; break; case SSL_ENABLE_OB_CERTS: @@ -826,8 +824,8 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) case SSL_REQUIRE_SAFE_NEGOTIATION: on = ss->opt.requireSafeNegotiation; break; case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; + case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; - case SSL_ENABLE_CACHED_INFO: on = ss->opt.enableCachedInfo; break; case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; case SSL_ENCRYPT_CLIENT_CERTS: on = ss->opt.encryptClientCerts; break; @@ -855,6 +853,8 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) return SECFailure; } + ssl_SetDefaultsFromEnvironment(); + switch (which) { case SSL_SOCKS: on = PR_FALSE; break; case SSL_SECURITY: on = ssl_defaults.useSecurity; break; @@ -882,10 +882,10 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) on = ssl_defaults.requireSafeNegotiation; break; case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break; + case SSL_CBC_RANDOM_IV: on = ssl_defaults.cbcRandomIV; break; case SSL_ENABLE_OCSP_STAPLING: on = ssl_defaults.enableOCSPStapling; break; - case SSL_ENABLE_CACHED_INFO: on = ssl_defaults.enableCachedInfo; break; case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; case SSL_ENCRYPT_CLIENT_CERTS: on = ssl_defaults.encryptClientCerts; break; @@ -909,6 +909,14 @@ SSL_EnableDefault(int which, PRBool on) SECStatus SSL_OptionSetDefault(PRInt32 which, PRBool on) { + SECStatus status = ssl_Init(); + + if (status != SECSuccess) { + return status; + } + + ssl_SetDefaultsFromEnvironment(); + switch (which) { case SSL_SOCKS: ssl_defaults.useSocks = PR_FALSE; @@ -1036,12 +1044,12 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) ssl_defaults.enableFalseStart = on; break; - case SSL_ENABLE_OCSP_STAPLING: - ssl_defaults.enableOCSPStapling = on; + case SSL_CBC_RANDOM_IV: + ssl_defaults.cbcRandomIV = on; break; - case SSL_ENABLE_CACHED_INFO: - ssl_defaults.enableCachedInfo = on; + case SSL_ENABLE_OCSP_STAPLING: + ssl_defaults.enableOCSPStapling = on; break; case SSL_ENABLE_OB_CERTS: @@ -1095,7 +1103,11 @@ SSL_SetPolicy(long which, int policy) SECStatus SSL_CipherPolicySet(PRInt32 which, PRInt32 policy) { - SECStatus rv; + SECStatus rv = ssl_Init(); + + if (rv != SECSuccess) { + return rv; + } if (ssl_IsRemovedCipherSuite(which)) { rv = SECSuccess; @@ -1150,7 +1162,11 @@ SSL_EnableCipher(long which, PRBool enabled) SECStatus SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled) { - SECStatus rv; + SECStatus rv = ssl_Init(); + + if (rv != SECSuccess) { + return rv; + } if (ssl_IsRemovedCipherSuite(which)) return SECSuccess; @@ -1239,7 +1255,6 @@ SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled) SECStatus NSS_SetDomesticPolicy(void) { -#ifndef EXPORT_VERSION SECStatus status = SECSuccess; cipherPolicy * policy; @@ -1249,37 +1264,18 @@ NSS_SetDomesticPolicy(void) break; } return status; -#else - return NSS_SetExportPolicy(); -#endif } SECStatus NSS_SetExportPolicy(void) { - SECStatus status = SECSuccess; - cipherPolicy * policy; - - for (policy = ssl_ciphers; policy->cipher != 0; ++policy) { - status = SSL_SetPolicy(policy->cipher, policy->export); - if (status != SECSuccess) - break; - } - return status; + return NSS_SetDomesticPolicy(); } SECStatus NSS_SetFrancePolicy(void) { - SECStatus status = SECSuccess; - cipherPolicy * policy; - - for (policy = ssl_ciphers; policy->cipher != 0; ++policy) { - status = SSL_SetPolicy(policy->cipher, policy->france); - if (status != SECSuccess) - break; - } - return status; + return NSS_SetDomesticPolicy(); } @@ -1291,6 +1287,11 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) sslSocket * ns = NULL; PRStatus rv; PRNetAddr addr; + SECStatus status = ssl_Init(); + + if (status != SECSuccess) { + return NULL; + } if (model == NULL) { /* Just create a default socket if we're given NULL for the model */ @@ -1324,15 +1325,14 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) } SECStatus -SSL_SetNextProtoCallback(PRFileDesc *fd, - SSLNextProtoCallback callback, - void *arg) { +SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback, + void *arg) +{ sslSocket *ss = ssl_FindSocket(fd); if (!ss) { - SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID(), - fd)); - PORT_SetError(SEC_ERROR_INVALID_ARGS); + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoCallback", SSL_GETPID(), + fd)); return SECFailure; } @@ -1340,24 +1340,28 @@ SSL_SetNextProtoCallback(PRFileDesc *fd, ss->nextProtoCallback = callback; ss->nextProtoArg = arg; ssl_ReleaseSSL3HandshakeLock(ss); + return SECSuccess; } -/* NextProtoStandardCallback is set as an NPN callback for the case when the - * user of the sockets wants the standard selection algorithm. */ +/* NextProtoStandardCallback is set as an NPN callback for the case when + * SSL_SetNextProtoNego is used. + */ static SECStatus -NextProtoStandardCallback(void *arg, - PRFileDesc *fd, - const unsigned char *protos, - unsigned int protos_len, - unsigned char *protoOut, - unsigned int *protoOutLen) +ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd, + const unsigned char *protos, unsigned int protos_len, + unsigned char *protoOut, unsigned int *protoOutLen, + unsigned int protoMaxLen) { unsigned int i, j; const unsigned char *result; - sslSocket *ss = ssl_FindSocket(fd); - PORT_Assert(ss); + + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in ssl_NextProtoNegoCallback", + SSL_GETPID(), fd)); + return SECFailure; + } if (protos_len == 0) { /* The server supports the extension, but doesn't have any protocols @@ -1369,16 +1373,16 @@ NextProtoStandardCallback(void *arg, for (i = 0; i < protos_len; ) { for (j = 0; j < ss->opt.nextProtoNego.len; ) { if (protos[i] == ss->opt.nextProtoNego.data[j] && - memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1], - protos[i]) == 0) { + PORT_Memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1], + protos[i]) == 0) { /* We found a match. */ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; result = &protos[i]; goto found; } - j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; + j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j]; } - i += (unsigned int)protos[i] + 1; + i += 1 + (unsigned int)protos[i]; } pick_first: @@ -1386,8 +1390,12 @@ pick_first: result = ss->opt.nextProtoNego.data; found: - memcpy(protoOut, result + 1, result[0]); *protoOutLen = result[0]; + if (protoMaxLen < result[0]) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + return SECFailure; + } + memcpy(protoOut, result + 1, result[0]); return SECSuccess; } @@ -1395,14 +1403,14 @@ SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, unsigned int length) { + sslSocket *ss; SECStatus rv; + SECItem dataItem = { siBuffer, (unsigned char *) data, length }; - sslSocket *ss = ssl_FindSocket(fd); - + ss = ssl_FindSocket(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID(), fd)); - PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } @@ -1410,30 +1418,30 @@ SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, return SECFailure; ssl_GetSSL3HandshakeLock(ss); - if (ss->opt.nextProtoNego.data) - PORT_Free(ss->opt.nextProtoNego.data); - ss->opt.nextProtoNego.data = PORT_Alloc(length); - if (!ss->opt.nextProtoNego.data) { - ssl_ReleaseSSL3HandshakeLock(ss); - return SECFailure; - } - memcpy(ss->opt.nextProtoNego.data, data, length); - ss->opt.nextProtoNego.len = length; - ss->opt.nextProtoNego.type = siBuffer; + SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE); + rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem); ssl_ReleaseSSL3HandshakeLock(ss); - return SSL_SetNextProtoCallback(fd, NextProtoStandardCallback, NULL); + if (rv != SECSuccess) + return rv; + + return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL); } SECStatus -SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, - unsigned int *length, unsigned int buf_len) +SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf, + unsigned int *bufLen, unsigned int bufLenMax) { sslSocket *ss = ssl_FindSocket(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(), - fd)); + fd)); + return SECFailure; + } + + if (!state || !buf || !bufLen) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } @@ -1441,12 +1449,15 @@ SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && ss->ssl3.nextProto.data) { - *length = ss->ssl3.nextProto.len; - if (*length > buf_len) - *length = buf_len; - PORT_Memcpy(buf, ss->ssl3.nextProto.data, *length); + *bufLen = ss->ssl3.nextProto.len; + if (*bufLen > bufLenMax) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + *bufLen = 0; + return SECFailure; + } + PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len); } else { - *length = 0; + *bufLen = 0; } return SECSuccess; @@ -1462,8 +1473,8 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) #if 0 sslSocket * sm = NULL, *ss = NULL; int i; - sslServerCerts * mc = sm->serverCerts; - sslServerCerts * sc = ss->serverCerts; + sslServerCerts * mc = NULL; + sslServerCerts * sc = NULL; if (model == NULL) { PR_SetError(SEC_ERROR_INVALID_ARGS, 0); @@ -1492,7 +1503,9 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) /* This int should be SSLKEAType, but CC on Irix complains, * during the for loop. */ - for (i=kt_null; i < kt_kea_size; i++, mc++, sc++) { + for (i=kt_null; i < kt_kea_size; i++) { + mc = &(sm->serverCerts[i]); + sc = &(ss->serverCerts[i]); if (mc->serverCert && mc->serverCertChain) { if (sc->serverCert) { CERT_DestroyCertificate(sc->serverCert); @@ -2053,7 +2066,36 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags) } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) && (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */ new_flags |= PR_POLL_WRITE; /* also select on write. */ - } + } + + if (ss->version >= SSL_LIBRARY_VERSION_3_0 && + ss->ssl3.hs.restartTarget != NULL) { + /* Read and write will block until the asynchronous callback completes + * (e.g. until SSL_AuthCertificateComplete is called), so don't tell + * the caller to poll the socket unless there is pending write data. + */ + if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) { + /* Ignore any newly-received data on the socket, but do wait for + * the socket to become writable again. Here, it is OK for an error + * to be detected, because our logic for sending pending write data + * will allow us to report the error to the caller without the risk + * of the application spinning. + */ + new_flags &= (PR_POLL_WRITE | PR_POLL_EXCEPT); + } else { + /* Unfortunately, clearing new_flags will make it impossible for + * the application to detect errors that it would otherwise be + * able to detect with PR_POLL_EXCEPT, until the asynchronous + * callback completes. However, we must clear all the flags to + * prevent the application from spinning (alternating between + * calling PR_Poll that would return PR_POLL_EXCEPT, and send/recv + * which won't actually report the I/O error while we are waiting + * for the asynchronous callback to complete). + */ + new_flags = 0; + } + } + if (new_flags && (fd->lower->methods->poll != NULL)) { PRInt16 lower_out_flags = 0; PRInt16 lower_new_flags; @@ -2428,7 +2470,9 @@ ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id) PRStatus status; if (!ssl_inited) { - PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer); + status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer); + if (status != PR_SUCCESS) + goto loser; } if (ns == NULL) @@ -2504,13 +2548,9 @@ loser: #define LOWER(x) (x | 0x20) /* cheap ToLower function ignores LOCALE */ -/* -** Create a newsocket structure for a file descriptor. -*/ -static sslSocket * -ssl_NewSocket(PRBool makeLocks) +static void +ssl_SetDefaultsFromEnvironment(void) { - sslSocket *ss; #if defined( NSS_HAVE_GETENV ) static int firsttime = 1; @@ -2579,8 +2619,25 @@ ssl_NewSocket(PRBool makeLocks) SSL_TRACE(("SSL: requireSafeNegotiation set to %d", PR_TRUE)); } + ev = getenv("NSS_SSL_CBC_RANDOM_IV"); + if (ev && ev[0] == '0') { + ssl_defaults.cbcRandomIV = PR_FALSE; + SSL_TRACE(("SSL: cbcRandomIV set to 0")); + } } #endif /* NSS_HAVE_GETENV */ +} + +/* +** Create a newsocket structure for a file descriptor. +*/ +static sslSocket * +ssl_NewSocket(PRBool makeLocks) +{ + sslSocket *ss; + + ssl_SetDefaultsFromEnvironment(); + if (ssl_force_locks) makeLocks = PR_TRUE; @@ -2654,3 +2711,4 @@ loser: } return ss; } + diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h index 4bbe1a0..3535c06 100644 --- a/net/third_party/nss/ssl/sslt.h +++ b/net/third_party/nss/ssl/sslt.h @@ -37,7 +37,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslt.h,v 1.16 2010/02/04 03:21:11 wtc%google.com Exp $ */ +/* $Id: sslt.h,v 1.18 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ #ifndef __sslt_h_ #define __sslt_h_ @@ -204,13 +204,12 @@ typedef enum { ssl_ec_point_formats_xtn = 11, #endif ssl_session_ticket_xtn = 35, - ssl_next_proto_neg_xtn = 13172, - ssl_cached_info_xtn = 13173, + ssl_next_proto_nego_xtn = 13172, ssl_encrypted_client_certs = 13180, /* not IANA assigned. */ ssl_renegotiation_info_xtn = 0xff01, /* experimental number */ ssl_ob_cert_xtn = 13175 /* experimental number */ } SSLExtensionType; -#define SSL_MAX_EXTENSIONS 10 +#define SSL_MAX_EXTENSIONS 9 #endif /* __sslt_h_ */ |