summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-03 15:02:22 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-03 15:02:22 +0000
commit1b5bcd397cf7e5bfb947be72f06138a2ee4be699 (patch)
tree6008c21d4c741cccb8a6bc2cd0c3a26414ddfc64
parent8cf99c80877e6030417a3c2e0fa7cb46cfcef3d3 (diff)
downloadchromium_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
-rw-r--r--net/socket/ssl_client_socket_nss.cc36
-rw-r--r--net/socket/ssl_client_socket_nss.h3
-rw-r--r--net/third_party/nss/README.chromium35
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh20
-rw-r--r--net/third_party/nss/patches/cachecerts.patch35
-rw-r--r--net/third_party/nss/patches/cachedinfo.patch975
-rw-r--r--net/third_party/nss/patches/cbcrandomiv.patch181
-rw-r--r--net/third_party/nss/patches/clientauth.patch188
-rw-r--r--net/third_party/nss/patches/didhandshakeresume.patch48
-rw-r--r--net/third_party/nss/patches/encryptedclientcerts.patch483
-rw-r--r--net/third_party/nss/patches/getrequestedclientcerttypes.patch56
-rw-r--r--net/third_party/nss/patches/handshakeshortwrite.patch40
-rw-r--r--net/third_party/nss/patches/nextproto.patch592
-rw-r--r--net/third_party/nss/patches/ocspstapling.patch169
-rw-r--r--net/third_party/nss/patches/origin_bound_certs.patch122
-rw-r--r--net/third_party/nss/patches/peercertchain.patch97
-rw-r--r--net/third_party/nss/patches/restartclientauth.patch209
-rw-r--r--net/third_party/nss/patches/secret_exporter.patch68
-rw-r--r--net/third_party/nss/ssl.gyp6
-rw-r--r--net/third_party/nss/ssl/SSLerrs.h419
-rw-r--r--net/third_party/nss/ssl/bodge/blapi.h4
-rw-r--r--net/third_party/nss/ssl/derive.c40
-rw-r--r--net/third_party/nss/ssl/manifest.mn3
-rw-r--r--net/third_party/nss/ssl/notes.txt4
-rw-r--r--net/third_party/nss/ssl/ssl.h260
-rw-r--r--net/third_party/nss/ssl/ssl3con.c691
-rw-r--r--net/third_party/nss/ssl/ssl3ecc.c5
-rw-r--r--net/third_party/nss/ssl/ssl3ext.c354
-rw-r--r--net/third_party/nss/ssl/ssl3gthr.c60
-rw-r--r--net/third_party/nss/ssl/ssl3prot.h2
-rw-r--r--net/third_party/nss/ssl/sslauth.c57
-rw-r--r--net/third_party/nss/ssl/sslcon.c174
-rw-r--r--net/third_party/nss/ssl/sslerr.h13
-rw-r--r--net/third_party/nss/ssl/sslerrstrs.c66
-rw-r--r--net/third_party/nss/ssl/sslimpl.h109
-rw-r--r--net/third_party/nss/ssl/sslinfo.c2
-rw-r--r--net/third_party/nss/ssl/sslinit.c (renamed from net/third_party/nss/ssl/fnv1a64.c)49
-rw-r--r--net/third_party/nss/ssl/sslmutex.c24
-rw-r--r--net/third_party/nss/ssl/sslmutex.h7
-rw-r--r--net/third_party/nss/ssl/sslnonce.c5
-rw-r--r--net/third_party/nss/ssl/sslreveal.c2
-rw-r--r--net/third_party/nss/ssl/sslsecur.c92
-rw-r--r--net/third_party/nss/ssl/sslsnce.c149
-rw-r--r--net/third_party/nss/ssl/sslsock.c252
-rw-r--r--net/third_party/nss/ssl/sslt.h7
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_ */