summaryrefslogtreecommitdiffstats
path: root/net/third_party
diff options
context:
space:
mode:
Diffstat (limited to 'net/third_party')
-rw-r--r--net/third_party/nss/README.chromium5
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh3
-rw-r--r--net/third_party/nss/patches/snapstart.patch2131
-rw-r--r--net/third_party/nss/patches/snapstart2.patch93
-rw-r--r--net/third_party/nss/ssl.gyp2
-rw-r--r--net/third_party/nss/ssl/fnv1a64.c72
-rw-r--r--net/third_party/nss/ssl/snapstart.c1061
-rw-r--r--net/third_party/nss/ssl/ssl.def12
-rw-r--r--net/third_party/nss/ssl/ssl.h54
-rw-r--r--net/third_party/nss/ssl/ssl3con.c364
-rw-r--r--net/third_party/nss/ssl/ssl3ext.c13
-rw-r--r--net/third_party/nss/ssl/sslimpl.h79
-rw-r--r--net/third_party/nss/ssl/sslsock.c10
-rw-r--r--net/third_party/nss/ssl/sslt.h16
14 files changed, 146 insertions, 3769 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index f956ffd..193fef0 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -27,11 +27,6 @@ Patches:
patches/cachecerts.patch
https://bugzilla.mozilla.org/show_bug.cgi?id=606049
- * Add Snap Start support
- patches/snapstart.patch
- patches/snapstart2.patch
- http://tools.ietf.org/html/draft-agl-tls-snapstart-00
-
* Add the SSL_PeerCertificateChain function
patches/peercertchain.patch
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index 0a858f8..0c2a687 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -13,9 +13,6 @@ patch -p4 < $patches_dir/renegoscsv.patch
patch -p4 < $patches_dir/cachecerts.patch
-patch -p5 < $patches_dir/snapstart.patch
-patch -p3 < $patches_dir/snapstart2.patch
-
patch -p3 < $patches_dir/peercertchain.patch
patch -p4 < $patches_dir/ocspstapling.patch
diff --git a/net/third_party/nss/patches/snapstart.patch b/net/third_party/nss/patches/snapstart.patch
deleted file mode 100644
index f9c05c8..0000000
--- a/net/third_party/nss/patches/snapstart.patch
+++ /dev/null
@@ -1,2131 +0,0 @@
-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/snapstart.c b/mozilla/security/nss/lib/ssl/snapstart.c
-new file mode 100644
-index 0000000..ca2cafa
---- /dev/null
-+++ b/mozilla/security/nss/lib/ssl/snapstart.c
-@@ -0,0 +1,1062 @@
-+/*
-+ * TLS Snap Start
-+ *
-+ * ***** 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: ssl3snap.c,v 1.0 2010/08/09 13:00:00 agl%google.com Exp $ */
-+
-+
-+/* TODO(agl): Refactor ssl3_CompressMACEncryptRecord so that it can write to
-+** |sendBuf| directly and fix ssl3_AppendSnapStartHandshakeRecord and
-+** ssl3_AppendSnapStartApplicationData.
-+*/
-+
-+/* TODO(agl): Add support for snap starting with compression. */
-+
-+/* TODO(agl): Free snapStartApplicationData as soon as the handshake has
-+** completed.
-+*/
-+
-+#include "pk11pub.h"
-+#include "ssl.h"
-+#include "sslimpl.h"
-+#include "sslproto.h"
-+
-+static unsigned int GetBE16(const void *in)
-+{
-+ const unsigned char *p = in;
-+ return ((unsigned) p[0]) << 8 |
-+ p[1];
-+}
-+
-+static unsigned int GetBE24(const void *in)
-+{
-+ const unsigned char *p = in;
-+ return ((unsigned) p[0]) << 16 |
-+ ((unsigned) p[1]) << 8 |
-+ p[2];
-+}
-+
-+static void PutBE16(void *out, unsigned int value)
-+{
-+ unsigned char *p = out;
-+ p[0] = value >> 8;
-+ p[1] = value;
-+}
-+
-+static void PutBE24(void *out, unsigned int value)
-+{
-+ unsigned char *p = out;
-+ p[0] = value >> 16;
-+ p[1] = value >> 8;
-+ p[2] = value;
-+}
-+
-+/* ssl3_ForEachExtension calls a callback for each TLS extension in |extensions|
-+** extensions: points to a block of extensions which includes the two prefix
-+** length bytes
-+** is_resuming: if true, certain extensions will be omitted
-+** f: a function which is called with the data of each extension, which
-+** includes the four type and length bytes at the beginning.
-+*/
-+static PRBool
-+ssl3_ForEachExtension(const SECItem *extensions, PRBool is_resuming,
-+ void (*f) (const unsigned char *data, unsigned int length,
-+ void *ctx),
-+ void *ctx) {
-+ unsigned int extensions_len, offset;
-+
-+ if (extensions->len == 0)
-+ return PR_TRUE;
-+
-+ if (extensions->len < 2)
-+ goto loser;
-+
-+ extensions_len = GetBE16(extensions->data);
-+ offset = 2;
-+
-+ if (extensions->len != 2 + extensions_len)
-+ goto loser;
-+
-+ while (extensions_len) {
-+ unsigned int extension_num, extension_len;
-+
-+ if (extensions->len - offset < 4)
-+ goto loser;
-+
-+ extension_num = GetBE16(extensions->data + offset);
-+ extension_len = GetBE16(extensions->data + offset + 2);
-+
-+ if (extensions->len - offset < 4 + extension_len)
-+ goto loser;
-+
-+ /* When resuming, the server will omit some extensions from the
-+ * previous non-resume ServerHello. */
-+ if (!is_resuming ||
-+ (extension_num != ssl_server_name_xtn &&
-+ extension_num != ssl_session_ticket_xtn)) {
-+ f(extensions->data + offset, 4 + extension_len, ctx);
-+ }
-+
-+ offset += 4 + extension_len;
-+ extensions_len -= 4 + extension_len;
-+ }
-+
-+ return PR_TRUE;
-+
-+loser:
-+ PORT_SetError(SEC_ERROR_INPUT_LEN);
-+ return PR_FALSE;
-+}
-+
-+static void
-+ssl3_AccumlateLengths(const unsigned char *data, unsigned int length, void *ptr)
-+{
-+ unsigned int *sum = (unsigned int *) ptr;
-+ *sum += length;
-+}
-+
-+/* ssl3_PredictServerResponse predicts the contents of the server's
-+** ServerHello...ServerHelloDone (inclusive) and progressively calls a callback
-+** with the contents of those messages.
-+** previous_server_hello: the contents of a previous ServerHello from the
-+** server where the 'random' field has been replaced with our suggested
-+** server random.
-+** is_resuming: if false, Certificate and ServerHelloDone messages will be
-+** predicted
-+** hashUpdate: a callback which is called repeated with the contents of the
-+** predicted messages.
-+*/
-+static PRBool
-+ssl3_PredictServerResponse(
-+ sslSocket *ss, SECItem *previous_server_hello, PRBool is_resuming,
-+ void (*hashUpdate) (const unsigned char *data, unsigned int length,
-+ void *ctx),
-+ void *ctx) {
-+ unsigned int old_session_id_length, old_extensions_len;
-+ unsigned int extensions_len, server_hello_len;
-+ unsigned char session_id_len, header[4];
-+ SECItem extensions;
-+
-+ /* Keep the structure of a ServerHello in mind when reading the following:
-+ *
-+ * struct ServerHello {
-+ * uint16_t version;
-+ * uint8_t random[32];
-+ * uint8_t session_id_len;
-+ * uint8_t session_id[session_id_len];
-+ * uint16_t cipher
-+ * uint8_t compression
-+ *
-+ * // Optional:
-+ * uint16_t extensions_len;
-+ * struct Extension {
-+ * uint16_t num;
-+ * uint16_t len;
-+ * uint8_t payload[len];
-+ * }
-+ */
-+
-+ /* 38 bytes is the shortest possible ServerHello with a zero-length
-+ * session_id and no extensions. */
-+ if (previous_server_hello->len < 38) {
-+ PORT_SetError(SEC_ERROR_INPUT_LEN);
-+ return PR_FALSE;
-+ }
-+
-+ /* First we need to figure out the length of the predicted ServerHello. Any
-+ * session id in |previous_server_hello| needs to be removed
-+ * (or replaced). */
-+ old_session_id_length = previous_server_hello->data[34];
-+
-+ extensions.len = 0;
-+
-+ if (previous_server_hello->len >= 35 + old_session_id_length + 3 + 2) {
-+ /* Extensions present */
-+ unsigned int offset = 35 + old_session_id_length + 3;
-+ extensions.data = previous_server_hello->data + offset;
-+ extensions.len = previous_server_hello->len - offset;
-+ }
-+
-+ /* Sum the lengths of all the extensions that we wish to include */
-+ extensions_len = 0;
-+ if (!ssl3_ForEachExtension(&extensions, is_resuming, ssl3_AccumlateLengths,
-+ &extensions_len)) {
-+ return PR_FALSE;
-+ }
-+
-+ old_extensions_len =
-+ (previous_server_hello->len - 35 - old_session_id_length - 3 - 2);
-+
-+ session_id_len = 0;
-+ if (ss->sec.ci.sid)
-+ session_id_len = ss->sec.ci.sid->u.ssl3.sessionIDLength;
-+ server_hello_len = previous_server_hello->len +
-+ session_id_len - old_session_id_length +
-+ extensions_len - old_extensions_len;
-+
-+ header[0] = server_hello;
-+ PutBE24(header + 1, server_hello_len);
-+ hashUpdate(header, 4, ctx);
-+
-+ hashUpdate(previous_server_hello->data, 34, ctx);
-+ hashUpdate(&session_id_len, sizeof(session_id_len), ctx);
-+ if (session_id_len)
-+ hashUpdate(ss->sec.ci.sid->u.ssl3.sessionID, session_id_len, ctx);
-+ hashUpdate(previous_server_hello->data + 35 + old_session_id_length, 3,
-+ ctx);
-+
-+ if (extensions.len) {
-+ PutBE16(header, extensions_len);
-+ hashUpdate(header, 2, ctx);
-+
-+ if (!ssl3_ForEachExtension(&extensions, is_resuming, hashUpdate, ctx))
-+ return PR_FALSE;
-+ }
-+
-+ if (!is_resuming) {
-+ unsigned int certificate_message_len = 3, i;
-+ for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
-+ certificate_message_len += 3;
-+ certificate_message_len +=
-+ ss->ssl3.predictedCertChain[i]->derCert.len;
-+ }
-+
-+ header[0] = certificate;
-+ PutBE24(header + 1, certificate_message_len);
-+ hashUpdate(header, 4, ctx);
-+
-+ PutBE24(header, certificate_message_len - 3);
-+ hashUpdate(header, 3, ctx);
-+
-+ for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
-+ unsigned int len = ss->ssl3.predictedCertChain[i]->derCert.len;
-+ PutBE24(header, len);
-+ hashUpdate(header, 3, ctx);
-+ hashUpdate(ss->ssl3.predictedCertChain[i]->derCert.data, len, ctx);
-+ }
-+
-+ header[0] = server_hello_done;
-+ header[1] = header[2] = header[3] = 0;
-+ hashUpdate(header, 4, ctx);
-+ }
-+
-+ return PR_TRUE;
-+}
-+
-+/* ssl3_SnapStartHash is called with the contents of the server's predicted
-+ * response and updates both the Finished hash and an FNV641a hash. */
-+static void
-+ssl3_SnapStartHash(const unsigned char *data, unsigned int len, void *ctx)
-+{
-+ SECStatus rv;
-+ void **ptrs = (void **) ctx;
-+ sslSocket *ss = ptrs[0];
-+ PRUint64 *fnv = ptrs[1];
-+
-+ FNV1A64_Update(fnv, data, len);
-+ rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *) data, len);
-+ if (rv != SECSuccess)
-+ PR_Assert("rv == SECSuccess", __FILE__, __LINE__);
-+}
-+
-+static PRInt32
-+ssl3_SendEmptySnapStartXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
-+{
-+ SECStatus rv;
-+
-+ if (maxBytes < 4)
-+ return 0;
-+
-+ if (append) {
-+ rv = ssl3_AppendHandshakeNumber(ss, ssl_snap_start_xtn, 2);
-+ if (rv != SECSuccess)
-+ return -1;
-+ rv = ssl3_AppendHandshakeNumber(ss, 0 /* empty extension */, 2);
-+ if (rv != SECSuccess)
-+ return -1;
-+ if (!ss->sec.isServer) {
-+ TLSExtensionData *xtnData = &ss->xtnData;
-+ xtnData->advertised[xtnData->numAdvertised++] = ssl_snap_start_xtn;
-+ }
-+ }
-+ return 4;
-+}
-+
-+static SECStatus
-+ssl3_BufferEnsure(sslBuffer *buf, unsigned int extra_bytes)
-+{
-+ if (buf->space < buf->len + extra_bytes)
-+ return sslBuffer_Grow(buf, buf->len + extra_bytes);
-+ return SECSuccess;
-+}
-+
-+/* ssl3_AppendSnapStartRecordHeader appends a 5 byte TLS record header to the
-+ * sendBuf of the given sslSocket. */
-+static SECStatus
-+ssl3_AppendSnapStartRecordHeader(sslSocket *ss, SSL3ContentType type,
-+ unsigned int len)
-+{
-+ SECStatus rv;
-+
-+ rv = ssl3_BufferEnsure(&ss->sec.ci.sendBuf, 5);
-+ if (rv != SECSuccess)
-+ return rv;
-+ ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len + 0] = type;
-+ PutBE16(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len + 1], ss->version);
-+ PutBE16(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len + 3], len);
-+ ss->sec.ci.sendBuf.len += 5;
-+ return SECSuccess;
-+}
-+
-+/* ssl3_AppendSnapStartHandshakeRecord appends a (possibly encrypted) record to
-+** the sendBuf of the given sslSocket.
-+** f: a function which will append the bytes of the record (not including the
-+** 5 byte header) to the sendBuf.
-+*/
-+static SECStatus
-+ssl3_AppendSnapStartHandshakeRecord(sslSocket *ss, SECStatus (*f) (sslSocket*),
-+ PRBool encrypt)
-+{
-+ SECStatus rv;
-+ unsigned int record_offset, record_len;
-+
-+ /* ssl3_CompressMACEncryptRecord will deal with the record header if we are
-+ * encrypting. */
-+ if (!encrypt) {
-+ /* The zero length argument here is a dummy value. We write the real
-+ * length once we know it, below. */
-+ rv = ssl3_AppendSnapStartRecordHeader(ss, content_handshake, 0);
-+ if (rv != SECSuccess)
-+ return rv;
-+ }
-+
-+ record_offset = ss->sec.ci.sendBuf.len;
-+ rv = f(ss);
-+ if (rv != SECSuccess)
-+ return rv;
-+ record_len = ss->sec.ci.sendBuf.len - record_offset;
-+ if (!encrypt) {
-+ PutBE16(&ss->sec.ci.sendBuf.buf[record_offset - 2], record_len);
-+ } else {
-+ /* ssl3_CompressMACEncryptRecord writes to |ss->sec.writeBuf|
-+ * so we copy it back to |ss->sec.ci.sendBuf| */
-+ /* TODO(agl): the buffer copy here is a bodge. See TODO at the top of
-+ * the file. */
-+ rv = ssl3_CompressMACEncryptRecord(
-+ ss, content_handshake,
-+ &ss->sec.ci.sendBuf.buf[record_offset], record_len);
-+ if (rv != SECSuccess)
-+ return rv;
-+ ss->sec.ci.sendBuf.len -= record_len;
-+ ssl3_BufferEnsure(&ss->sec.ci.sendBuf, ss->sec.writeBuf.len);
-+ memcpy(&ss->sec.ci.sendBuf.buf[record_offset], ss->sec.writeBuf.buf,
-+ ss->sec.writeBuf.len);
-+ ss->sec.ci.sendBuf.len += ss->sec.writeBuf.len;
-+ ss->sec.writeBuf.len = 0;
-+ }
-+
-+ return SECSuccess;
-+}
-+
-+/* ssl3_AppendSnapStartApplicationData appends an encrypted Application Data
-+** record the sendBuf of the given sslSocket.
-+*/
-+static SECStatus ssl3_AppendSnapStartApplicationData(
-+ sslSocket *ss, const SSL3Opaque *data, unsigned int len)
-+{
-+ SECStatus rv;
-+
-+ /* TODO(agl): the buffer copy here is a bodge. See TODO at the top of the
-+ * file. */
-+ rv = ssl3_CompressMACEncryptRecord(ss, content_application_data, data, len);
-+ if (rv != SECSuccess)
-+ return rv;
-+ rv = ssl3_BufferEnsure(&ss->sec.ci.sendBuf, ss->sec.writeBuf.len);
-+ if (rv != SECSuccess)
-+ return rv;
-+ memcpy(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len],
-+ ss->sec.writeBuf.buf, ss->sec.writeBuf.len);
-+ ss->sec.ci.sendBuf.len += ss->sec.writeBuf.len;
-+ ss->sec.writeBuf.len = 0;
-+
-+ return SECSuccess;
-+}
-+
-+static SECStatus ssl3_SendSnapStartFinished(sslSocket *ss)
-+{
-+ /* We use ssl_SEND_FLAG_NO_FLUSH here because this finished message is
-+ * going to end up in the middle of the Snap Start extension. So
-+ * transmitting |sendBuf| at this point would result in an incomplete
-+ * ClientHello. */
-+ return ssl3_SendFinished(ss, ssl_SEND_FLAG_NO_FLUSH);
-+}
-+
-+/* ssl3_FindOrbit is called for each extension in a ServerHello message. It
-+** tests for a Snap Start extension and records the server's orbit when found.
-+** data: the extension data (including the four type and length bytes)
-+** length: the length, in bytes, of |data|
-+** ptr: a pointer to a uint8_t[9]. The orbit, if found, is copied into the
-+** first 8 bytes and then the ninth byte is set to one.
-+*/
-+static void
-+ssl3_FindOrbit(const unsigned char *data, unsigned int length, void *ptr)
-+{
-+ unsigned char *orbit = (unsigned char *) ptr;
-+
-+ unsigned int extension_num = GetBE16(data);
-+ if (extension_num == ssl_snap_start_xtn &&
-+ length == 4 + 8 /* orbit */ + 2 /* snap start cipher suite */) {
-+ memcpy(orbit, data + 4, 8);
-+ /* A last byte of 1 indicates that the previous eight are valid. */
-+ orbit[8] = 1;
-+ }
-+}
-+
-+/* ssl3_CanSnapStart returns true if we are able to perform Snap Start on
-+** the given socket.
-+** extensions: on successful return, this is filled in with the contents of
-+** the server's predicted extensions. This points within
-+** |ss->ssl3.serverHelloPredictionData|.
-+** resuming: PR_TRUE iff we wish to attempt a Snap Start resume
-+** out_orbit: if this function returns PR_TRUE, then |out_orbit| is filled
-+** with the server's predicted orbit value.
-+** The |hs.cipher_suite|, |hs.cipher_def| and |hs.compression| fields of |ss|
-+** are set to match the predicted ServerHello on successful exit (and may still
-+** be modified on failure).
-+*/
-+static PRBool
-+ssl3_CanSnapStart(sslSocket *ss, SECItem *extensions, PRBool resuming,
-+ unsigned char out_orbit[8]) {
-+ const unsigned char *server_hello;
-+ unsigned int server_hello_len, session_id_len, cipher_suite_offset;
-+ unsigned int extensions_offset, cipher_suite, compression_method;
-+ unsigned char orbit[9];
-+ SECStatus rv;
-+ SSL3ProtocolVersion version;
-+
-+ /* If we don't have the information needed then we can't perform a Snap
-+ * Start. */
-+ if (!ss->ssl3.predictedCertChain || !ss->ssl3.serverHelloPredictionData.data)
-+ return PR_FALSE;
-+
-+ /* When the sizes of the fields in the ClientHello are calculated, they'll
-+ * take the length of the Snap Start extension to be zero, so currently
-+ * it's as if this extension didn't exist, which is the state that we
-+ * need. */
-+
-+ server_hello = ss->ssl3.serverHelloPredictionData.data;
-+ server_hello_len = ss->ssl3.serverHelloPredictionData.len;
-+
-+ if (server_hello_len < 2 + 32 + 1)
-+ return PR_FALSE;
-+ session_id_len = server_hello[2 + 32];
-+ cipher_suite_offset = 2 + 32 + 1 + session_id_len;
-+ if (server_hello_len < cipher_suite_offset + 3)
-+ return PR_FALSE;
-+ extensions_offset = cipher_suite_offset + 3;
-+
-+ version = (SSL3ProtocolVersion) GetBE16(server_hello);
-+ if (MSB(version) < MSB(SSL_LIBRARY_VERSION_3_0))
-+ return PR_FALSE;
-+ rv = ssl3_NegotiateVersion(ss, version);
-+ if (rv != SECSuccess)
-+ return PR_FALSE;
-+
-+ cipher_suite = GetBE16(&server_hello[cipher_suite_offset]);
-+ ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)cipher_suite;
-+ ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
-+ if (!ss->ssl3.hs.suite_def)
-+ return PR_FALSE;
-+ compression_method = server_hello[cipher_suite_offset + 2];
-+ if (compression_method != ssl_compression_null) {
-+ /* TODO(agl): support compression. */
-+ return PR_FALSE;
-+ }
-+ ss->ssl3.hs.compression = ssl_compression_null;
-+
-+ extensions->data = (unsigned char *) server_hello + extensions_offset;
-+ extensions->len = server_hello_len - extensions_offset;
-+
-+ /* The last byte is used to indictate that the previous eight are valid. */
-+ orbit[8] = 0;
-+ if (!ssl3_ForEachExtension(extensions, resuming, ssl3_FindOrbit, orbit))
-+ return PR_FALSE;
-+
-+ if (!orbit[8])
-+ return PR_FALSE;
-+
-+ memcpy(out_orbit, orbit, 8);
-+
-+ return PR_TRUE;
-+}
-+
-+/* ssl3_UpdateClientHelloLengths rewrites the handshake header length and
-+** extensions length in the ClientHello to reflect the addition of the Snap
-+** Start extension.
-+** snap_start_extension_len_offset: the number of bytes of the ClientHello to
-+** skip in order to find the embedded length of the Snap Start extension.
-+*/
-+static void
-+ssl3_UpdateClientHelloLengths(sslSocket *ss,
-+ unsigned int snap_start_extension_len_offset,
-+ sslSessionID *sid) {
-+ unsigned int extension_length, old_length, new_length, new_session_id_len;
-+ unsigned int offset, ciphers_length, compressions_len;
-+
-+ extension_length =
-+ ss->sec.ci.sendBuf.len - snap_start_extension_len_offset - 2;
-+ PutBE16(&ss->sec.ci.sendBuf.buf[snap_start_extension_len_offset],
-+ extension_length);
-+
-+ /* The length in the handshake header is short by extension_length + 4
-+ * bytes. */
-+ old_length = GetBE24(&ss->sec.ci.sendBuf.buf[1]);
-+ new_length = old_length + extension_length + 4;
-+ PutBE24(&ss->sec.ci.sendBuf.buf[1], new_length);
-+
-+ /* The length of the extensions block is similarly wrong. */
-+ new_session_id_len = 0;
-+ if (sid)
-+ new_session_id_len = sid->u.ssl3.sessionIDLength;
-+ offset = 4 + 2 + 32 + 1 + new_session_id_len;
-+ ciphers_length = GetBE16(&ss->sec.ci.sendBuf.buf[offset]);
-+ offset += 2 + ciphers_length;
-+ compressions_len = ss->sec.ci.sendBuf.buf[offset];
-+ offset += 1 + compressions_len;
-+ old_length = GetBE16(&ss->sec.ci.sendBuf.buf[offset]);
-+ new_length = old_length + extension_length + 4;
-+ PutBE16(&ss->sec.ci.sendBuf.buf[offset], new_length);
-+}
-+
-+/* ssl3_FindServerNPNExtension is a callback function for ssl3_ForEachExtension.
-+ * It looks for a Next Protocol Negotiation and saves the payload of the
-+ * extension in the given SECItem */
-+static void
-+ssl3_FindServerNPNExtension(const unsigned char* data, unsigned int length,
-+ void *ctx)
-+{
-+ SECItem *server_npn_extension = (SECItem*) ctx;
-+
-+ unsigned int extension_num = GetBE16(data);
-+ if (extension_num == ssl_next_proto_neg_xtn && length >= 4) {
-+ server_npn_extension->data = (unsigned char*)data + 4;
-+ server_npn_extension->len = length - 4;
-+ }
-+}
-+
-+/* ssl3_MaybeWriteNextProtocol deals with the interaction of Next Protocol
-+ * Negotiation and Snap Start. It's called just before we serialise the embedded
-+ * Finished message in the extension. At this point, if NPN is enabled, we have
-+ * to include a NextProtocol message. */
-+static SECStatus
-+ssl3_MaybeWriteNextProtocol(sslSocket *ss, SECItem *server_hello_extensions)
-+{
-+ PRUint16 i16;
-+ SECItem server_npn_extension;
-+
-+ for (i16 = 0; i16 < ss->xtnData.numAdvertised; i16++) {
-+ if (ss->xtnData.advertised[i16] == ssl_next_proto_neg_xtn)
-+ break;
-+ }
-+
-+ if (i16 == ss->xtnData.numAdvertised) {
-+ /* We didn't send an NPN extension, so no need to do anything here. */
-+ return SECSuccess;
-+ }
-+
-+ memset(&server_npn_extension, 0, sizeof(server_npn_extension));
-+
-+ ssl3_ForEachExtension(
-+ server_hello_extensions, PR_FALSE /* is_resuming: value doesn't matter
-+ in this case */, ssl3_FindServerNPNExtension, &server_npn_extension);
-+
-+ if (server_npn_extension.data == NULL) {
-+ /* We predicted that the server doesn't support NPN, so nothing to do
-+ * here. */
-+ return SECSuccess;
-+ }
-+
-+ ssl3_ClientHandleNextProtoNegoXtn(ss, ssl_next_proto_neg_xtn,
-+ &server_npn_extension);
-+
-+ if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT) {
-+ /* The server's predicted NPN extension was malformed. We're didn't pick
-+ * a protocol so we won't send a NextProtocol message. However, this is
-+ * probably fatal to the connection. */
-+ return SECSuccess;
-+ }
-+
-+ return ssl3_AppendSnapStartHandshakeRecord(ss, ssl3_SendNextProto,
-+ PR_TRUE /* encrypt */);
-+}
-+
-+/* ssl3_SendSnapStartXtn appends a Snap Start extension. It assumes that the
-+ * inchoate ClientHello is in |ss->sec.ci.sendBuf|. */
-+PRInt32
-+ssl3_SendSnapStartXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
-+{
-+ unsigned char orbit[8];
-+ PRBool resuming = PR_FALSE;
-+ unsigned char suggested_server_random[32];
-+ SECStatus rv;
-+ PRUint64 fnv;
-+ /* The context for |ssl3_SnapStartHash|. The first pointer points to |ss|
-+ * and the second to the running FNV1A64 hash of the predicted server
-+ * response. */
-+ void *ctx[2];
-+ unsigned int snap_start_extension_len_offset, original_sendbuf_len;
-+ ssl3CipherSpec *temp;
-+ sslSessionID *sid;
-+ SECItem server_extensions;
-+
-+ if (!ss->opt.enableSnapStart)
-+ return 0;
-+
-+ original_sendbuf_len = ss->sec.ci.sendBuf.len;
-+
-+ /* This function is called twice for each ClientHello emitted. The first
-+ * time around is to calculate the sizes of the extension (|append| is
-+ * false). The second time around is to actually write out the bytes
-+ * (|append| is true).
-+ *
-+ * We always return 0 bytes in each case because we want to be able to hash
-+ * the inchoate ClientHello as if this extension was missing: that's why
-+ * it's important that this always be the last extension serialised. */
-+ sid = ss->sec.ci.sid;
-+
-+ if (!ss->opt.enableSessionTickets || ss->sec.isServer)
-+ return 0;
-+
-+ /* If we are sending a SessionTicket then the first time around
-+ * ticketTimestampVerified will be true but it's reset after serialising
-+ * the session ticket extension, so we have
-+ * |clientSentNonEmptySessionTicket|. */
-+ if (ss->xtnData.clientSentNonEmptySessionTicket) {
-+ resuming = PR_TRUE;
-+ } else if (sid->u.ssl3.sessionTicket.ticket.data &&
-+ ss->xtnData.ticketTimestampVerified) {
-+ resuming = PR_TRUE;
-+ }
-+
-+ if (!ssl3_CanSnapStart(ss, &server_extensions, resuming, orbit))
-+ return ssl3_SendEmptySnapStartXtn(ss, append, maxBytes);
-+
-+ /* At this point we are happy that we are going to send a non-empty Snap
-+ * Start extension. If we are still calculating length then we lie and
-+ * return 0 so that everything is set up as if the extension didn't exist
-+ * when this function is called again later. */
-+
-+ if (!append)
-+ return 0;
-+
-+ /* |ss->sec.ci.sendBuf.buf| contains the inchoate ClientHello. This copies
-+ * the ClientHello's gmt_unix_time into the suggested server random. */
-+ memcpy(suggested_server_random, ss->sec.ci.sendBuf.buf + 6, 4);
-+ memcpy(suggested_server_random + 4, orbit, 8);
-+ rv = PK11_GenerateRandom(suggested_server_random + 12, 20);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ memcpy(ss->ssl3.serverHelloPredictionData.data + 2, suggested_server_random,
-+ 32);
-+
-+ memcpy(&ss->ssl3.hs.server_random, suggested_server_random, 32);
-+
-+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-+ rv = ssl3_SetupPendingCipherSpec(ss);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ ss->ssl3.hs.isResuming = resuming;
-+
-+ FNV1A64_Init(&fnv);
-+ ctx[0] = ss;
-+ ctx[1] = &fnv;
-+
-+ if (!ssl3_PredictServerResponse(ss, &ss->ssl3.serverHelloPredictionData,
-+ resuming, ssl3_SnapStartHash, ctx)) {
-+ /* It's not a fatal error if the predicted ServerHello was invalid. */
-+ return 0;
-+ }
-+ FNV1A64_Final(&fnv);
-+
-+ /* Now we grow the send buffer to accomodate the extension type and length,
-+ * orbit, suggested random and predicted server response hash without
-+ * calling ssl3_AppendHandshake (which would also update the Finished
-+ * hash). */
-+ if (ssl3_BufferEnsure(&ss->sec.ci.sendBuf, 4 + 8 + 20 + 8) != SECSuccess)
-+ goto loser;
-+
-+ PutBE16(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len],
-+ ssl_snap_start_xtn);
-+ ss->sec.ci.sendBuf.len += 2;
-+ /* Skip over the length for now. */
-+ snap_start_extension_len_offset = ss->sec.ci.sendBuf.len;
-+ ss->sec.ci.sendBuf.len += 2;
-+ memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, orbit, 8);
-+ ss->sec.ci.sendBuf.len += 8;
-+ memcpy(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len],
-+ suggested_server_random + 12, 20);
-+ ss->sec.ci.sendBuf.len += 20;
-+ memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, &fnv, 8);
-+ ss->sec.ci.sendBuf.len += 8;
-+
-+ if (!resuming) {
-+ /* Write ClientKeyExchange */
-+ ss->sec.peerCert =
-+ CERT_DupCertificate(ss->ssl3.predictedCertChain[0]);
-+ rv = ssl3_AppendSnapStartHandshakeRecord(
-+ ss, ssl3_SendClientKeyExchange, PR_FALSE /* do not encrypt */);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ } else {
-+ SSL3Finished hashes;
-+ TLSFinished tlsFinished;
-+ unsigned char hdr[4];
-+
-+ rv = ssl3_SetupMasterSecretFromSessionID(ss);
-+ if (rv == SECFailure)
-+ goto loser;
-+
-+ if (sid->peerCert != NULL) {
-+ ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
-+ ssl3_CopyPeerCertsFromSID(ss, sid);
-+ }
-+
-+ rv = ssl3_InitPendingCipherSpec(ss, NULL /* re-use master secret */);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ /* Need to add the server's predicted Finished message to our handshake
-+ * hash in order to be able to produce our own Finished message. */
-+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes,
-+ 0 /* only for SSL3 */);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ rv = ssl3_ComputeTLSFinished(ss->ssl3.pwSpec, PR_TRUE /* isServer */,
-+ &hashes, &tlsFinished);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ hdr[0] = (unsigned char) finished;
-+ hdr[1] = hdr[2] = 0;
-+ hdr[3] = sizeof(tlsFinished.verify_data);
-+ ssl3_UpdateHandshakeHashes(ss, hdr, sizeof(hdr));
-+ ssl3_UpdateHandshakeHashes(ss, tlsFinished.verify_data,
-+ sizeof(tlsFinished.verify_data));
-+
-+ /* Store the Finished message so that we can verify it later */
-+ memcpy(&ss->ssl3.hs.finishedMsgs.tFinished[1], tlsFinished.verify_data,
-+ sizeof(tlsFinished.verify_data));
-+ }
-+
-+ /* Write ChangeCipherSpec */
-+ rv = ssl3_AppendSnapStartRecordHeader(ss, content_change_cipher_spec, 1);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ rv = ssl3_BufferEnsure(&ss->sec.ci.sendBuf, 1);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len] = change_cipher_spec_choice;
-+ ss->sec.ci.sendBuf.len++;
-+
-+ /* We swap |cwSpec| and |pwSpec| temporarily in order to encrypt some
-+ * records before switching them back so that the whole ClientHello doesn't
-+ * get encrypted. */
-+ ssl_GetSpecWriteLock(ss);
-+ temp = ss->ssl3.cwSpec;
-+ ss->ssl3.cwSpec = ss->ssl3.pwSpec;
-+ ss->ssl3.pwSpec = temp;
-+ ss->ssl3.cwSpec->write_seq_num.high = 0;
-+ ss->ssl3.cwSpec->write_seq_num.low = 0;
-+ ssl_ReleaseSpecWriteLock(ss);
-+
-+ rv = ssl3_MaybeWriteNextProtocol(ss, &server_extensions);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ /* Write Finished */
-+ rv = ssl3_AppendSnapStartHandshakeRecord(ss, ssl3_SendSnapStartFinished,
-+ PR_TRUE /* encrypt */);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ /* Write application data */
-+ if (ss->ssl3.snapStartApplicationData.data) {
-+ rv = ssl3_AppendSnapStartApplicationData(
-+ ss, ss->ssl3.snapStartApplicationData.data,
-+ ss->ssl3.snapStartApplicationData.len);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ }
-+
-+ /* Revert the write cipher spec because the ClientHello will get encrypted
-+ * with it otherwise. */
-+ ssl_GetSpecWriteLock(ss);
-+ temp = ss->ssl3.cwSpec;
-+ ss->ssl3.cwSpec = ss->ssl3.pwSpec;
-+ ss->ssl3.pwSpec = temp;
-+ ssl_ReleaseSpecWriteLock(ss);
-+
-+ /* Update the lengths in the ClientHello to reflect this extension. */
-+ ssl3_UpdateClientHelloLengths(ss, snap_start_extension_len_offset, sid);
-+
-+ /* Keep a copy of the ClientHello around so that we can hash it in the case
-+ * the the Snap Start handshake is rejected. */
-+
-+ if (SECITEM_AllocItem(NULL, &ss->ssl3.hs.origClientHello,
-+ ss->sec.ci.sendBuf.len) == NULL) {
-+ goto loser;
-+ }
-+ memcpy(ss->ssl3.hs.origClientHello.data, ss->sec.ci.sendBuf.buf,
-+ ss->sec.ci.sendBuf.len);
-+ ss->ssl3.hs.origClientHello.len = ss->sec.ci.sendBuf.len;
-+
-+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = ssl_snap_start_xtn;
-+
-+ if (resuming) {
-+ ss->ssl3.hs.snapStartType = snap_start_resume;
-+ } else {
-+ ss->ssl3.hs.snapStartType = snap_start_full;
-+ }
-+
-+ return 0;
-+
-+loser:
-+ /* In the case of an error we revert the length of the sendBuf to remove
-+ * any partial data that we may have appended. */
-+ ss->sec.ci.sendBuf.len = original_sendbuf_len;
-+ return -1;
-+}
-+
-+SECStatus ssl3_ClientHandleSnapStartXtn(sslSocket *ss, PRUint16 ex_type,
-+ SECItem *data) {
-+ /* The work of saving the ServerHello is done in ssl3_HandleServerHello,
-+ * where its contents are available. Here we renognise that the saved
-+ * ServerHello message contains a Snap Start extension and mark it as
-+ * valid. */
-+ ss->ssl3.serverHelloPredictionDataValid = PR_TRUE;
-+ 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;
-+}
-+
-+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;
-+}
-+
-+SECStatus
-+SSL_GetPredictedServerHelloData(PRFileDesc *fd, const unsigned char **data,
-+ unsigned int *data_len)
-+{
-+ sslSocket *ss;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPredictedServerHelloData",
-+ SSL_GETPID(), fd));
-+ *data = NULL;
-+ *data_len = 0;
-+ return SECFailure;
-+ }
-+
-+ if (!ss->ssl3.serverHelloPredictionDataValid) {
-+ *data = NULL;
-+ *data_len = 0;
-+ } else {
-+ *data = ss->ssl3.serverHelloPredictionData.data;
-+ *data_len = ss->ssl3.serverHelloPredictionData.len;
-+ }
-+ return SECSuccess;
-+}
-+
-+SECStatus
-+SSL_SetPredictedServerHelloData(PRFileDesc *fd, const unsigned char *data,
-+ unsigned int data_len)
-+{
-+ sslSocket *ss;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedServerHelloData",
-+ SSL_GETPID(), fd));
-+ return SECFailure;
-+ }
-+
-+ if (ss->ssl3.serverHelloPredictionData.data)
-+ SECITEM_FreeItem(&ss->ssl3.serverHelloPredictionData, PR_FALSE);
-+ if (!SECITEM_AllocItem(NULL, &ss->ssl3.serverHelloPredictionData, data_len))
-+ return SECFailure;
-+ memcpy(ss->ssl3.serverHelloPredictionData.data, data, data_len);
-+ return SECSuccess;
-+}
-+
-+SECStatus
-+SSL_SetSnapStartApplicationData(PRFileDesc *fd, const unsigned char *data,
-+ unsigned int data_len)
-+{
-+ sslSocket *ss;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSnapStartApplicationData",
-+ SSL_GETPID(), fd));
-+ return SECFailure;
-+ }
-+
-+ if (ss->ssl3.snapStartApplicationData.data)
-+ SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
-+ if (!SECITEM_AllocItem(NULL, &ss->ssl3.snapStartApplicationData, data_len))
-+ return SECFailure;
-+ memcpy(ss->ssl3.snapStartApplicationData.data, data, data_len);
-+ return SECSuccess;
-+}
-+
-+SECStatus
-+SSL_GetSnapStartResult(PRFileDesc *fd, SSLSnapStartResult *result)
-+{
-+ sslSocket *ss;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSnapStartResult",
-+ SSL_GETPID(), fd));
-+ return SECFailure;
-+ }
-+
-+ switch (ss->ssl3.hs.snapStartType) {
-+ case snap_start_full:
-+ *result = SSL_SNAP_START_FULL;
-+ break;
-+ case snap_start_recovery:
-+ *result = SSL_SNAP_START_RECOVERY;
-+ break;
-+ case snap_start_resume:
-+ *result = SSL_SNAP_START_RESUME;
-+ break;
-+ case snap_start_resume_recovery:
-+ *result = SSL_SNAP_START_RESUME_RECOVERY;
-+ break;
-+ default:
-+ PORT_Assert(ss->ssl3.hs.snapStartType == snap_start_none);
-+ *result = SSL_SNAP_START_NONE;
-+ break;
-+ }
-+
-+ return SECSuccess;
-+}
-+
-+/* Called form ssl3_HandleServerHello in the case that we sent a Snap Start
-+** ClientHello but received a ServerHello in reply.
-+*/
-+SECStatus
-+ssl3_ResetForSnapStartRecovery(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-+{
-+ SECStatus rv;
-+ PRUint8 hdr[4];
-+
-+ ss->ssl3.hs.ws = wait_server_hello;
-+
-+ /* Need to reset the Finished hashes to include the full ClientHello
-+ * message. */
-+
-+ rv = ssl3_RestartHandshakeHashes(ss);
-+ if (rv != SECSuccess)
-+ return rv;
-+ rv = ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.origClientHello.data,
-+ ss->ssl3.hs.origClientHello.len);
-+ SECITEM_FreeItem(&ss->ssl3.hs.origClientHello, PR_FALSE);
-+ if (rv != SECSuccess)
-+ return rv;
-+
-+ hdr[0] = (PRUint8)server_hello;
-+ hdr[1] = (PRUint8)(length >> 16);
-+ hdr[2] = (PRUint8)(length >> 8);
-+ hdr[3] = (PRUint8)(length );
-+
-+ rv = ssl3_UpdateHandshakeHashes(ss, hdr, sizeof(hdr));
-+ if (rv != SECSuccess)
-+ return rv;
-+ rv = ssl3_UpdateHandshakeHashes(ss, b, length);
-+ if (rv != SECSuccess)
-+ return rv;
-+
-+ if (ss->ssl3.hs.snapStartType == snap_start_full) {
-+ ss->ssl3.hs.snapStartType = snap_start_recovery;
-+ } else {
-+ ss->ssl3.hs.snapStartType = snap_start_resume_recovery;
-+ }
-+
-+ ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_TRUE/*freeSrvName*/);
-+
-+ return SECSuccess;
-+}
-diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def
-index a1f4b51..effc35d 100644
---- a/mozilla/security/nss/lib/ssl/ssl.def
-+++ b/mozilla/security/nss/lib/ssl/ssl.def
-@@ -159,3 +159,13 @@ SSL_SetNextProtoNego;
- ;+ local:
- ;+*;
- ;+};
-+;+NSS_3.13 { # NSS 3.13 release
-+;+ global:
-+SSL_GetPredictedServerHelloData;
-+SSL_GetSnapStartResult;
-+SSL_SetPredictedPeerCertificates;
-+SSL_SetPredictedServerHelloData;
-+SSL_SetSnapStartApplicationData;
-+;+ local:
-+;+*;
-+;+};
-diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
-index d87ae56..8217d2e 100644
---- a/mozilla/security/nss/lib/ssl/ssl.h
-+++ b/mozilla/security/nss/lib/ssl/ssl.h
-@@ -139,6 +139,15 @@ 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_SNAP_START 23 /* Enable SSL snap start (off by */
-+ /* default, applies only to */
-+ /* clients). Snap start is a way */
-+/* of performing TLS handshakes with no round trips. The client's entire */
-+/* handshake is included in the first handshake message, along with */
-+/* optional application data. In order to do this, information from a */
-+/* previous connection to the same server is required. See */
-+/* SSL_GetPredictedServerHelloData, SSL_SetPredictedPeerCertificates and */
-+/* SSL_SetSnapStartApplicationData. */
-
- #ifdef SSL_DEPRECATED_FUNCTION
- /* Old deprecated function names */
-@@ -376,6 +385,49 @@ 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 Snap Start extension. Note that the SSL_ENABLE_SNAP_START 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);
-+
-+/*
-+** Get the data needed to predict the server's hello message in the future. On
-+** return, |*data| will either be NULL (in which case no data is available and
-+** |*data_len| will be zero) or it will point to a buffer within the internal
-+** data of |fd| and |*data_len| will contain the number of bytes available. If
-+** non-NULL, |*data| will persist at least until the next handshake on |fd|.
-+*/
-+SSL_IMPORT SECStatus SSL_GetPredictedServerHelloData(
-+ PRFileDesc *fd, const unsigned char **data,
-+ unsigned int *data_len);
-+
-+/*
-+** Set the predicted server hello data. This is used for the TLS Snap Start
-+** extension. Note that the SSL_ENABLE_SNAP_START option must be set for this
-+** to occur.
-+*/
-+SSL_IMPORT SECStatus SSL_SetPredictedServerHelloData(
-+ PRFileDesc *fd, const unsigned char *data, unsigned int data_len);
-+
-+/* Set the application data which will be transmitted in a Snap Start
-+** handshake. If the Snap Start handshake fails, this data will be
-+* retransmitted automatically. */
-+SSL_IMPORT SECStatus SSL_SetSnapStartApplicationData(
-+ PRFileDesc *fd, const unsigned char *data, unsigned int data_len);
-+
-+/* Get the result of a Snap Start handshake. It's valid to call then even if
-+** SSL_ENABLE_SNAP_START hasn't been set, although the result will always be
-+** SSL_SNAP_START_NONE.
-+*/
-+SSL_IMPORT SECStatus SSL_GetSnapStartResult(PRFileDesc* socket,
-+ SSLSnapStartResult* result);
-+
-+/*
- ** 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 64c3452..9ab2a1c 100644
---- a/mozilla/security/nss/lib/ssl/ssl3con.c
-+++ b/mozilla/security/nss/lib/ssl/ssl3con.c
-@@ -72,7 +72,8 @@
- #endif
-
- static void ssl3_CleanupPeerCerts(sslSocket *ss);
--static void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
-+static void ssl3_CopyPeerCertsToSID(ssl3CertNode *certs,
-+ sslSessionID *sid);
- static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot);
- static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
-@@ -82,14 +83,10 @@ 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);
- static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
- static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss);
--static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, unsigned char *b,
-- unsigned int l);
-
- static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
- int maxOutputLen, const unsigned char *input,
-@@ -583,7 +580,7 @@ void SSL_AtomicIncrementLong(long * x)
-
- /* return pointer to ssl3CipherSuiteDef for suite, or NULL */
- /* XXX This does a linear search. A binary search would be better. */
--static const ssl3CipherSuiteDef *
-+const ssl3CipherSuiteDef *
- ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
- {
- int cipher_suite_def_len =
-@@ -1169,7 +1166,7 @@ ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
- ** ssl3_DestroySSL3Info
- ** Caller must hold SpecWriteLock.
- */
--static void
-+void
- ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
- {
- PRBool freeit = (PRBool)(!spec->bypassCiphers);
-@@ -1211,7 +1208,7 @@ ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
- ** Caller must hold the ssl3 handshake lock.
- ** Acquires & releases SpecWriteLock.
- */
--static SECStatus
-+SECStatus
- ssl3_SetupPendingCipherSpec(sslSocket *ss)
- {
- ssl3CipherSpec * pwSpec;
-@@ -2039,7 +2036,7 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
- return isPresent;
- }
-
--static SECStatus
-+SECStatus
- ssl3_CompressMACEncryptRecord(sslSocket * ss,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
-@@ -3097,7 +3094,7 @@ loser:
- return SECFailure;
- }
-
--static SECStatus
-+SECStatus
- ssl3_RestartHandshakeHashes(sslSocket *ss)
- {
- SECStatus rv = SECSuccess;
-@@ -3175,7 +3172,7 @@ loser:
- ** ssl3_HandleHandshakeMessage()
- ** Caller must hold the ssl3Handshake lock.
- */
--static SECStatus
-+SECStatus
- ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l)
- {
- SECStatus rv = SECSuccess;
-@@ -3434,7 +3431,7 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
- * Caller must hold a read or write lock on the Spec R/W lock.
- * (There is presently no way to assert on a Read lock.)
- */
--static SECStatus
-+SECStatus
- ssl3_ComputeHandshakeHashes(sslSocket * ss,
- ssl3CipherSpec *spec, /* uses ->master_secret */
- SSL3Hashes * hashes, /* output goes here. */
-@@ -4032,7 +4029,18 @@ ssl3_SendClientHello(sslSocket *ss)
- return rv; /* error code set by ssl3_FlushHandshake */
- }
-
-- ss->ssl3.hs.ws = wait_server_hello;
-+ switch (ss->ssl3.hs.snapStartType) {
-+ case snap_start_full:
-+ ss->ssl3.hs.ws = wait_new_session_ticket;
-+ break;
-+ case snap_start_resume:
-+ ss->ssl3.hs.ws = wait_change_cipher;
-+ break;
-+ default:
-+ ss->ssl3.hs.ws = wait_server_hello;
-+ break;
-+ }
-+
- return rv;
- }
-
-@@ -4723,7 +4731,7 @@ loser:
-
-
- /* Called from ssl3_HandleServerHelloDone(). */
--static SECStatus
-+SECStatus
- ssl3_SendClientKeyExchange(sslSocket *ss)
- {
- SECKEYPublicKey * serverKey = NULL;
-@@ -4862,6 +4870,94 @@ done:
- return rv;
- }
-
-+/* Called from ssl3_HandleServerHello to set up the master secret in
-+ * ss->ssl3.pwSpec and the auth algorithm and kea type in ss->sec in the case
-+ * of a successful session resumption. */
-+SECStatus ssl3_SetupMasterSecretFromSessionID(sslSocket* ss) {
-+ sslSessionID *sid = ss->sec.ci.sid;
-+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
-+ SECItem wrappedMS; /* wrapped master secret. */
-+
-+ ss->sec.authAlgorithm = sid->authAlgorithm;
-+ ss->sec.authKeyBits = sid->authKeyBits;
-+ ss->sec.keaType = sid->keaType;
-+ ss->sec.keaKeyBits = sid->keaKeyBits;
-+
-+ /* 3 cases here:
-+ * a) key is wrapped (implies using PKCS11)
-+ * b) key is unwrapped, but we're still using PKCS11
-+ * c) key is unwrapped, and we're bypassing PKCS11.
-+ */
-+ if (sid->u.ssl3.keys.msIsWrapped) {
-+ PK11SlotInfo *slot;
-+ PK11SymKey * wrapKey; /* wrapping key */
-+ CK_FLAGS keyFlags = 0;
-+
-+ if (ss->opt.bypassPKCS11) {
-+ /* we cannot restart a non-bypass session in a
-+ ** bypass socket.
-+ */
-+ return SECFailure;
-+ }
-+ /* unwrap master secret with PKCS11 */
-+ slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
-+ sid->u.ssl3.masterSlotID);
-+ if (slot == NULL) {
-+ return SECFailure;
-+ }
-+ if (!PK11_IsPresent(slot)) {
-+ PK11_FreeSlot(slot);
-+ return SECFailure;
-+ }
-+ wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
-+ sid->u.ssl3.masterWrapMech,
-+ sid->u.ssl3.masterWrapSeries,
-+ ss->pkcs11PinArg);
-+ PK11_FreeSlot(slot);
-+ if (wrapKey == NULL) {
-+ return SECFailure;
-+ }
-+
-+ if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
-+ keyFlags = CKF_SIGN | CKF_VERIFY;
-+ }
-+
-+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
-+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-+ pwSpec->master_secret =
-+ PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
-+ NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
-+ CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
-+ PK11_FreeSymKey(wrapKey);
-+ if (pwSpec->master_secret == NULL) {
-+ return SECFailure;
-+ }
-+ } else if (ss->opt.bypassPKCS11) {
-+ /* MS is not wrapped */
-+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
-+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-+ memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
-+ pwSpec->msItem.data = pwSpec->raw_master_secret;
-+ pwSpec->msItem.len = wrappedMS.len;
-+ } else {
-+ /* We CAN restart a bypass session in a non-bypass socket. */
-+ /* need to import the raw master secret to session object */
-+ PK11SlotInfo *slot = PK11_GetInternalSlot();
-+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
-+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-+ pwSpec->master_secret =
-+ PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
-+ PK11_OriginUnwrap, CKA_ENCRYPT,
-+ &wrappedMS, NULL);
-+ PK11_FreeSlot(slot);
-+ if (pwSpec->master_secret == NULL) {
-+ return SECFailure;
-+ }
-+ }
-+
-+ return SECSuccess;
-+}
-+
- /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ServerHello message.
- * Caller must hold Handshake and RecvBuf locks.
-@@ -4886,6 +4982,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
-+ if (ss->ssl3.hs.snapStartType == snap_start_full ||
-+ ss->ssl3.hs.snapStartType == snap_start_resume) {
-+ /* Snap Start handshake was rejected. */
-+ rv = ssl3_ResetForSnapStartRecovery(ss, b, length);
-+ if (rv != SECSuccess)
-+ return rv;
-+ }
-+
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
-@@ -4897,6 +5001,21 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- goto alert_loser;
- }
-
-+ if (!ss->ssl3.serverHelloPredictionData.data) {
-+ /* If this allocation fails it will only stop the application from
-+ * recording the ServerHello information and performing future Snap
-+ * Starts. */
-+ if (SECITEM_AllocItem(NULL, &ss->ssl3.serverHelloPredictionData,
-+ length))
-+ memcpy(ss->ssl3.serverHelloPredictionData.data, b, length);
-+ /* ss->ssl3.serverHelloPredictionDataValid is still false at this
-+ * point. We have to record the contents of the ServerHello here
-+ * because we don't have a pointer to the whole message when handling
-+ * the extensions. However, we wait until the Snap Start extenion
-+ * handler to recognise that the server supports Snap Start and to set
-+ * serverHelloPredictionDataValid. */
-+ }
-+
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
-@@ -5037,118 +5156,40 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-
- if (sid_match &&
- sid->version == ss->version &&
-- sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do {
-- ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
--
-- SECItem wrappedMS; /* wrapped master secret. */
-+ sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) {
-+ rv = ssl3_SetupMasterSecretFromSessionID(ss);
-+ /* Failure of ssl3_SetupMasterSecretFromSessionID not considered an
-+ * error. Continue with a full handshake. */
-+ if (rv == SECSuccess) {
-+ /* Got a Match */
-+ SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
-
-- ss->sec.authAlgorithm = sid->authAlgorithm;
-- ss->sec.authKeyBits = sid->authKeyBits;
-- ss->sec.keaType = sid->keaType;
-- ss->sec.keaKeyBits = sid->keaKeyBits;
-+ /* If we sent a session ticket, then this is a stateless resume. */
-+ if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
-+ sid->u.ssl3.sessionTicket.ticket.data != NULL)
-+ SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );
-
-- /* 3 cases here:
-- * a) key is wrapped (implies using PKCS11)
-- * b) key is unwrapped, but we're still using PKCS11
-- * c) key is unwrapped, and we're bypassing PKCS11.
-- */
-- if (sid->u.ssl3.keys.msIsWrapped) {
-- PK11SlotInfo *slot;
-- PK11SymKey * wrapKey; /* wrapping key */
-- CK_FLAGS keyFlags = 0;
-+ if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
-+ ss->ssl3.hs.ws = wait_new_session_ticket;
-+ else
-+ ss->ssl3.hs.ws = wait_change_cipher;
-
-- if (ss->opt.bypassPKCS11) {
-- /* we cannot restart a non-bypass session in a
-- ** bypass socket.
-- */
-- break;
-- }
-- /* unwrap master secret with PKCS11 */
-- slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
-- sid->u.ssl3.masterSlotID);
-- if (slot == NULL) {
-- break; /* not considered an error. */
-- }
-- if (!PK11_IsPresent(slot)) {
-- PK11_FreeSlot(slot);
-- break; /* not considered an error. */
-- }
-- wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
-- sid->u.ssl3.masterWrapMech,
-- sid->u.ssl3.masterWrapSeries,
-- ss->pkcs11PinArg);
-- PK11_FreeSlot(slot);
-- if (wrapKey == NULL) {
-- break; /* not considered an error. */
-- }
-+ ss->ssl3.hs.isResuming = PR_TRUE;
-
-- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
-- keyFlags = CKF_SIGN | CKF_VERIFY;
-+ /* copy the peer cert from the SID */
-+ if (sid->peerCert != NULL) {
-+ ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
-+ ssl3_CopyPeerCertsFromSID(ss, sid);
- }
-
-- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
-- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-- pwSpec->master_secret =
-- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
-- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
-- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
-- errCode = PORT_GetError();
-- PK11_FreeSymKey(wrapKey);
-- if (pwSpec->master_secret == NULL) {
-- break; /* errorCode set just after call to UnwrapSymKey. */
-- }
-- } else if (ss->opt.bypassPKCS11) {
-- /* MS is not wrapped */
-- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
-- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-- memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
-- pwSpec->msItem.data = pwSpec->raw_master_secret;
-- pwSpec->msItem.len = wrappedMS.len;
-- } else {
-- /* We CAN restart a bypass session in a non-bypass socket. */
-- /* need to import the raw master secret to session object */
-- PK11SlotInfo *slot = PK11_GetInternalSlot();
-- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
-- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-- pwSpec->master_secret =
-- PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
-- PK11_OriginUnwrap, CKA_ENCRYPT,
-- &wrappedMS, NULL);
-- PK11_FreeSlot(slot);
-- if (pwSpec->master_secret == NULL) {
-- break;
-+ /* NULL value for PMS signifies re-use of the old MS */
-+ rv = ssl3_InitPendingCipherSpec(ss, NULL);
-+ if (rv != SECSuccess) {
-+ goto alert_loser;
- }
-+ return SECSuccess;
- }
--
-- /* Got a Match */
-- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
--
-- /* If we sent a session ticket, then this is a stateless resume. */
-- if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
-- sid->u.ssl3.sessionTicket.ticket.data != NULL)
-- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );
--
-- if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
-- ss->ssl3.hs.ws = wait_new_session_ticket;
-- else
-- ss->ssl3.hs.ws = wait_change_cipher;
--
-- ss->ssl3.hs.isResuming = PR_TRUE;
--
-- /* copy the peer cert from the SID */
-- if (sid->peerCert != NULL) {
-- ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
-- ssl3_CopyPeerCertsFromSID(ss, sid);
-- }
--
--
-- /* NULL value for PMS signifies re-use of the old MS */
-- rv = ssl3_InitPendingCipherSpec(ss, NULL);
-- if (rv != SECSuccess) {
-- goto alert_loser; /* err code was set */
-- }
-- return SECSuccess;
-- } while (0);
-+ }
-
- if (sid_match)
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok );
-@@ -6116,7 +6157,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- * ticket extension, but sent an empty ticket.
- */
- if (!ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) ||
-- ss->xtnData.emptySessionTicket) {
-+ ss->xtnData.serverReceivedEmptySessionTicket) {
- if (sidBytes.len > 0 && !ss->opt.noCache) {
- SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
- SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
-@@ -7569,6 +7610,12 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- return SECFailure; /* malformed */
- }
-
-+ if (ss->sec.ci.sid->peerCert == NULL) {
-+ ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
-+ ssl3_CopyPeerCertsToSID((ssl3CertNode *)ss->ssl3.peerCertChain,
-+ ss->sec.ci.sid);
-+ }
-+
- rv = ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &session_ticket);
- if (rv != SECSuccess) {
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
-@@ -7760,7 +7807,7 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
- ss->ssl3.peerCertChain = NULL;
- }
-
--static void
-+void
- ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid)
- {
- PRArenaPool *arena;
-@@ -8163,7 +8210,7 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
- return rv;
- }
-
--static SECStatus
-+SECStatus
- ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
- PRBool isServer,
- const SSL3Finished * hashes,
-@@ -8211,7 +8258,7 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
-
- /* called from ssl3_HandleServerHelloDone
- */
--static SECStatus
-+SECStatus
- ssl3_SendNextProto(sslSocket *ss)
- {
- SECStatus rv;
-@@ -8247,7 +8294,7 @@ ssl3_SendNextProto(sslSocket *ss)
- * ssl3_HandleClientHello
- * ssl3_HandleFinished
- */
--static SECStatus
-+SECStatus
- ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
- {
- ssl3CipherSpec *cwSpec;
-@@ -8300,10 +8347,27 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- }
-- rv = ssl3_FlushHandshake(ss, flags);
-- if (rv != SECSuccess) {
-- goto fail; /* error code set by ssl3_FlushHandshake */
-+ if ((flags & ssl_SEND_FLAG_NO_FLUSH) == 0) {
-+ rv = ssl3_FlushHandshake(ss, flags);
-+ if (rv != SECSuccess) {
-+ goto fail; /* error code set by ssl3_FlushHandshake */
-+ }
- }
-+
-+ if ((ss->ssl3.hs.snapStartType == snap_start_recovery ||
-+ ss->ssl3.hs.snapStartType == snap_start_resume_recovery) &&
-+ ss->ssl3.snapStartApplicationData.data) {
-+ /* In the event that the server ignored the application data in our
-+ * snap start extension, we need to retransmit it now. */
-+ PRInt32 sent = ssl3_SendRecord(ss, content_application_data,
-+ ss->ssl3.snapStartApplicationData.data,
-+ ss->ssl3.snapStartApplicationData.len,
-+ flags);
-+ SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
-+ if (sent < 0)
-+ return (SECStatus)sent; /* error code set by ssl3_SendRecord */
-+ }
-+
- return SECSuccess;
-
- fail:
-@@ -8420,6 +8484,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- return SECFailure;
- }
-
-+ if (ss->ssl3.hs.snapStartType == snap_start_full ||
-+ ss->ssl3.hs.snapStartType == snap_start_resume) {
-+ /* Snap Start handshake was successful. Switch the cipher spec. */
-+ ssl_GetSpecWriteLock(ss);
-+ ssl3_DestroyCipherSpec(ss->ssl3.cwSpec, PR_TRUE/*freeSrvName*/);
-+ ss->ssl3.cwSpec = ss->ssl3.pwSpec;
-+ ss->ssl3.pwSpec = NULL;
-+ ssl_ReleaseSpecWriteLock(ss);
-+ }
-+
- isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0);
- if (isTLS) {
- TLSFinished tlsFinished;
-@@ -8429,12 +8503,21 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
- return SECFailure;
- }
-- rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
-- hashes, &tlsFinished);
-- if (!isServer)
-- ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
-- else
-- ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
-+
-+ if (ss->ssl3.hs.snapStartType == snap_start_resume) {
-+ /* In this case we have already advanced the Finished hash past the
-+ * server's verify_data because we needed to predict the server's
-+ * Finished message in order to compute our own (which includes
-+ * it). When we did this, we stored a copy in tFinished[1]. */
-+ tlsFinished = ss->ssl3.hs.finishedMsgs.tFinished[1];
-+ } else {
-+ rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
-+ hashes, &tlsFinished);
-+ if (!isServer)
-+ ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
-+ else
-+ ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
-+ }
- ss->ssl3.hs.finishedBytes = sizeof tlsFinished;
- if (rv != SECSuccess ||
- 0 != NSS_SecureMemcmp(&tlsFinished, b, length)) {
-@@ -8465,8 +8548,9 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
-
- ssl_GetXmitBufLock(ss); /*************************************/
-
-- if ((isServer && !ss->ssl3.hs.isResuming) ||
-- (!isServer && ss->ssl3.hs.isResuming)) {
-+ if (ss->ssl3.hs.snapStartType != snap_start_resume &&
-+ ((isServer && !ss->ssl3.hs.isResuming) ||
-+ (!isServer && ss->ssl3.hs.isResuming))) {
- PRInt32 flags = 0;
-
- /* Send a NewSessionTicket message if the client sent us
-@@ -8582,7 +8666,10 @@ xmit_loser:
- ss->ssl3.hs.ws = idle_handshake;
-
- /* Do the handshake callback for sslv3 here, if we cannot false start. */
-- if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
-+ if (ss->handshakeCallback != NULL &&
-+ (!ssl3_CanFalseStart(ss) ||
-+ ss->ssl3.hs.snapStartType == snap_start_full ||
-+ ss->ssl3.hs.snapStartType == snap_start_resume)) {
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
- }
-
-@@ -8643,8 +8730,13 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- return rv;
- }
- }
-- /* We should not include hello_request messages in the handshake hashes */
-- if (ss->ssl3.hs.msg_type != hello_request) {
-+ /* We should not include hello_request messages in the handshake hashes.
-+ * Likewise, for Finished messages from the server during a Snap Start
-+ * resume, we have already predicted and included the message in our
-+ * Finished hash. */
-+ if (ss->ssl3.hs.msg_type != hello_request &&
-+ !(ss->ssl3.hs.msg_type == finished &&
-+ ss->ssl3.hs.snapStartType == snap_start_resume)) {
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
- if (rv != SECSuccess) return rv; /* err code already set. */
- rv = ssl3_UpdateHandshakeHashes(ss, b, length);
-@@ -9545,6 +9637,15 @@ ssl3_DestroySSL3Info(sslSocket *ss)
- ss->ssl3.clientCertChain = NULL;
- }
-
-+ if (ss->ssl3.predictedCertChain != NULL)
-+ ssl3_CleanupPredictedPeerCertificates(ss);
-+
-+ if (ss->ssl3.serverHelloPredictionData.data)
-+ SECITEM_FreeItem(&ss->ssl3.serverHelloPredictionData, PR_FALSE);
-+
-+ if (ss->ssl3.snapStartApplicationData.data)
-+ SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
-+
- /* clean up handshake */
- if (ss->opt.bypassPKCS11) {
- SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
-@@ -9562,6 +9663,9 @@ ssl3_DestroySSL3Info(sslSocket *ss)
- ss->ssl3.hs.messages.len = 0;
- ss->ssl3.hs.messages.space = 0;
- }
-+ if (ss->ssl3.hs.origClientHello.data) {
-+ SECITEM_FreeItem(&ss->ssl3.hs.origClientHello, PR_FALSE);
-+ }
-
- /* 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..a7ae062 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[] = {
- { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
-+ { ssl_snap_start_xtn, &ssl3_ClientHandleSnapStartXtn },
- { -1, NULL }
- };
-
-@@ -270,7 +271,9 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
- { 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_snap_start_xtn, &ssl3_SendSnapStartXtn }
-+ /* NOTE: The Snap Start sender MUST be the last extension in the list. */
- /* any extra entries will appear as { 0, NULL } */
- };
-
-@@ -298,7 +301,7 @@ ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
- xtnData->numNegotiated, ex_type);
- }
-
--static PRBool
-+PRBool
- ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
- TLSExtensionData *xtnData = &ss->xtnData;
- return arrayContainsExtension(xtnData->advertised,
-@@ -515,6 +518,8 @@ ssl3_SendSessionTicketXtn(
- rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
- session_ticket->ticket.len, 2);
- ss->xtnData.ticketTimestampVerified = PR_FALSE;
-+ if (!ss->sec.isServer)
-+ ss->xtnData.clientSentNonEmptySessionTicket = PR_TRUE;
- } else {
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- }
-@@ -573,7 +578,7 @@ ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
-
- SECStatus
- ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
-- SECItem *data)
-+ SECItem *data)
- {
- unsigned int i, j;
- SECStatus rv;
-@@ -1021,7 +1026,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
- * instead of terminating the current connection.
- */
- if (data->len == 0) {
-- ss->xtnData.emptySessionTicket = PR_TRUE;
-+ ss->xtnData.serverReceivedEmptySessionTicket = PR_TRUE;
- } else {
- int i;
- SECItem extension_data;
-diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
-index fe7ac7a..f708696 100644
---- a/mozilla/security/nss/lib/ssl/sslimpl.h
-+++ b/mozilla/security/nss/lib/ssl/sslimpl.h
-@@ -278,6 +278,7 @@ struct sslSocketOpsStr {
- /* Flags interpreted by ssl send functions. */
- #define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000
- #define ssl_SEND_FLAG_NO_BUFFER 0x20000000
-+#define ssl_SEND_FLAG_NO_FLUSH 0x10000000
- #define ssl_SEND_FLAG_MASK 0x7f000000
-
- /*
-@@ -339,6 +340,7 @@ typedef struct sslOptionsStr {
- unsigned int enableRenegotiation : 2; /* 20-21 */
- unsigned int requireSafeNegotiation : 1; /* 22 */
- unsigned int enableFalseStart : 1; /* 23 */
-+ unsigned int enableSnapStart : 1; /* 24 */
- } sslOptions;
-
- typedef enum { sslHandshakingUndetermined = 0,
-@@ -743,7 +745,8 @@ struct TLSExtensionDataStr {
-
- /* SessionTicket Extension related data. */
- PRBool ticketTimestampVerified;
-- PRBool emptySessionTicket;
-+ PRBool serverReceivedEmptySessionTicket;
-+ PRBool clientSentNonEmptySessionTicket;
-
- /* SNI Extension related data
- * Names data is not coppied from the input buffer. It can not be
-@@ -753,6 +756,14 @@ struct TLSExtensionDataStr {
- PRUint32 sniNameArrSize;
- };
-
-+typedef enum {
-+ snap_start_none = 0,
-+ snap_start_full,
-+ snap_start_recovery,
-+ snap_start_resume,
-+ snap_start_resume_recovery
-+} TLSSnapStartType;
-+
- /*
- ** This is the "hs" member of the "ssl3" struct.
- ** This entire struct is protected by ssl3HandshakeLock
-@@ -791,6 +802,14 @@ const ssl3CipherSuiteDef *suite_def;
- SSL3Hashes sFinished[2];
- SSL3Opaque data[72];
- } finishedMsgs;
-+
-+ TLSSnapStartType snapStartType;
-+ /* When we perform a Snap Start handshake, we hash our ClientHello as if
-+ * the Snap Start extension wasn't included. However, if the server rejects
-+ * our Snap Start attempt, then it will hash the whole ClientHello. Thus we
-+ * store the original ClientHello that we sent in case we need to reset our
-+ * Finished hash to cover it. */
-+ SECItem origClientHello;
- #ifdef NSS_ENABLE_ECC
- PRUint32 negotiatedECCurves; /* bit mask */
- #endif /* NSS_ENABLE_ECC */
-@@ -823,6 +842,17 @@ struct ssl3StateStr {
- CERTCertificateList *clientCertChain; /* used by client */
- PRBool sendEmptyCert; /* used by client */
-
-+ /* TLS Snap Start: */
-+ CERTCertificate ** predictedCertChain;
-+ /* An array terminated with a NULL. */
-+ SECItem serverHelloPredictionData;
-+ PRBool serverHelloPredictionDataValid;
-+ /* data needed to predict the ServerHello from
-+ * this server. */
-+ SECItem snapStartApplicationData;
-+ /* the application data to include in the Snap
-+ * Start extension. */
-+
- int policy;
- /* This says what cipher suites we can do, and should
- * be either SSL_ALLOWED or SSL_RESTRICTED
-@@ -1258,10 +1288,13 @@ extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
- extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port,
- const char *peerID, const char *urlSvrName);
- extern void ssl_FreeSID(sslSessionID *sid);
-+extern void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
-
- extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
- int len, int flags);
-
-+extern SECStatus ssl3_RestartHandshakeHashes(sslSocket *ss);
-+
- extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
-
- extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
-@@ -1434,6 +1467,9 @@ ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits);
-
- #endif /* NSS_ENABLE_ECC */
-
-+extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket* ss, unsigned char *b,
-+ unsigned int l);
-+
- extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
- extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
- extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
-@@ -1454,6 +1490,7 @@ extern void ssl3_InitSocketPolicy(sslSocket *ss);
-
- extern SECStatus ssl3_ConstructV2CipherSpecsHack(sslSocket *ss,
- unsigned char *cs, int *size);
-+extern void ssl3_DestroyCipherSpec(ssl3CipherSpec* spec, PRBool freeSrvName);
-
- extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
-
-@@ -1503,6 +1540,31 @@ extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash,
- extern SECStatus ssl3_CacheWrappedMasterSecret(sslSocket *ss,
- sslSessionID *sid, ssl3CipherSpec *spec,
- SSL3KEAType effectiveExchKeyType);
-+extern void ssl3_CleanupPredictedPeerCertificates(sslSocket *ss);
-+extern const ssl3CipherSuiteDef* ssl_LookupCipherSuiteDef(ssl3CipherSuite suite);
-+extern SECStatus ssl3_SetupPendingCipherSpec(sslSocket *ss);
-+extern SECStatus ssl3_SendClientKeyExchange(sslSocket *ss);
-+extern SECStatus ssl3_SendNextProto(sslSocket *ss);
-+extern SECStatus ssl3_SendFinished(sslSocket *ss, PRInt32 flags);
-+extern SECStatus ssl3_CompressMACEncryptRecord
-+ (sslSocket * ss,
-+ SSL3ContentType type,
-+ const SSL3Opaque * pIn,
-+ PRUint32 contentLen);
-+extern PRBool ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type);
-+extern SECStatus ssl3_SetupMasterSecretFromSessionID(sslSocket* ss);
-+extern SECStatus ssl3_ComputeHandshakeHashes(
-+ sslSocket * ss,
-+ ssl3CipherSpec *spec, /* uses ->master_secret */
-+ SSL3Hashes * hashes, /* output goes here. */
-+ PRUint32 sender);
-+extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket* ss, unsigned char *b,
-+ unsigned int l);
-+extern SECStatus ssl3_ComputeTLSFinished(
-+ ssl3CipherSpec *spec,
-+ PRBool isServer,
-+ const SSL3Finished * hashes,
-+ TLSFinished * tlsFinished);
-
- /* Functions that handle ClientHello and ServerHello extensions. */
- extern SECStatus ssl3_HandleServerNameXtn(sslSocket * ss,
-@@ -1532,6 +1594,13 @@ extern PRInt32 ssl3_SendSessionTicketXtn(sslSocket *ss, PRBool append,
- */
- extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-+extern PRInt32 ssl3_SendSnapStartXtn(sslSocket *ss, PRBool append,
-+ PRUint32 maxBytes);
-+extern SECStatus ssl3_ClientHandleSnapStartXtn(sslSocket *ss, PRUint16 ex_type,
-+ SECItem *data);
-+
-+extern SECStatus ssl3_ResetForSnapStartRecovery(sslSocket *ss,
-+ SSL3Opaque *b, PRUint32 length);
-
- /* Assigns new cert, cert chain and keys to ss->serverCerts
- * struct. If certChain is NULL, tries to find one. Aborts if
-@@ -1635,6 +1704,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 ca0d714..2898b88 100644
---- a/mozilla/security/nss/lib/ssl/sslsock.c
-+++ b/mozilla/security/nss/lib/ssl/sslsock.c
-@@ -738,6 +738,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
- ss->opt.enableFalseStart = on;
- break;
-
-+ case SSL_ENABLE_SNAP_START:
-+ ss->opt.enableSnapStart = on;
-+ break;
-+
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
-@@ -802,6 +806,7 @@ 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_ENABLE_SNAP_START: on = ss->opt.enableSnapStart; break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
-@@ -853,6 +858,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
- on = ssl_defaults.requireSafeNegotiation;
- break;
- case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break;
-+ case SSL_ENABLE_SNAP_START: on = ssl_defaults.enableSnapStart; break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
-@@ -1000,6 +1006,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
- ssl_defaults.enableFalseStart = on;
- break;
-
-+ case SSL_ENABLE_SNAP_START:
-+ ssl_defaults.enableSnapStart = 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 f6e0b62..68cbf87 100644
---- a/mozilla/security/nss/lib/ssl/sslt.h
-+++ b/mozilla/security/nss/lib/ssl/sslt.h
-@@ -204,9 +204,23 @@ typedef enum {
- #endif
- ssl_session_ticket_xtn = 35,
- ssl_next_proto_neg_xtn = 13172,
-+ ssl_snap_start_xtn = 13174,
- ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
- } SSLExtensionType;
-
--#define SSL_MAX_EXTENSIONS 6
-+#define SSL_MAX_EXTENSIONS 7
-+
-+typedef enum {
-+ /* No Snap Start handshake was attempted. */
-+ SSL_SNAP_START_NONE = 0,
-+ /* A Snap Start full handshake was completed. */
-+ SSL_SNAP_START_FULL = 1,
-+ /* A Snap Start full handshake was attempted, but failed. */
-+ SSL_SNAP_START_RECOVERY = 2,
-+ /* A Snap Start resume handshake was completed. */
-+ SSL_SNAP_START_RESUME = 3,
-+ /* A Snap Start resume handshake was attempted, but failed. */
-+ SSL_SNAP_START_RESUME_RECOVERY = 4
-+} SSLSnapStartResult;
-
- #endif /* __sslt_h_ */
diff --git a/net/third_party/nss/patches/snapstart2.patch b/net/third_party/nss/patches/snapstart2.patch
deleted file mode 100644
index 34ec562..0000000
--- a/net/third_party/nss/patches/snapstart2.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-Index: net/third_party/nss/ssl/snapstart.c
-===================================================================
---- net/third_party/nss/ssl/snapstart.c (revision 64952)
-+++ net/third_party/nss/ssl/snapstart.c (revision 64953)
-@@ -48,10 +48,6 @@
-
- /* TODO(agl): Add support for snap starting with compression. */
-
--/* TODO(agl): Free snapStartApplicationData as soon as the handshake has
--** completed.
--*/
--
- #include "pk11pub.h"
- #include "ssl.h"
- #include "sslimpl.h"
-@@ -821,6 +817,7 @@
- rv = ssl3_AppendSnapStartApplicationData(
- ss, ss->ssl3.snapStartApplicationData.data,
- ss->ssl3.snapStartApplicationData.len);
-+ SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
- if (rv != SECSuccess)
- goto loser;
- }
-@@ -1053,6 +1053,8 @@
- ss->ssl3.hs.snapStartType = snap_start_resume_recovery;
- }
-
-+ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT;
-+
- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_TRUE/*freeSrvName*/);
-
- return SECSuccess;
-Index: net/third_party/nss/ssl/ssl3con.c
-===================================================================
---- net/third_party/nss/ssl/ssl3con.c (revision 65946)
-+++ net/third_party/nss/ssl/ssl3con.c (revision 65947)
-@@ -5023,21 +5023,21 @@
- goto alert_loser;
- }
-
-- if (!ss->ssl3.serverHelloPredictionData.data) {
-- /* If this allocation fails it will only stop the application from
-- * recording the ServerHello information and performing future Snap
-- * Starts. */
-- if (SECITEM_AllocItem(NULL, &ss->ssl3.serverHelloPredictionData,
-- length))
-- memcpy(ss->ssl3.serverHelloPredictionData.data, b, length);
-- /* ss->ssl3.serverHelloPredictionDataValid is still false at this
-- * point. We have to record the contents of the ServerHello here
-- * because we don't have a pointer to the whole message when handling
-- * the extensions. However, we wait until the Snap Start extenion
-- * handler to recognise that the server supports Snap Start and to set
-- * serverHelloPredictionDataValid. */
-- }
-+ if (ss->ssl3.serverHelloPredictionData.data)
-+ SECITEM_FreeItem(&ss->ssl3.serverHelloPredictionData, PR_FALSE);
-
-+ /* If this allocation fails it will only stop the application from
-+ * recording the ServerHello information and performing future Snap
-+ * Starts. */
-+ if (SECITEM_AllocItem(NULL, &ss->ssl3.serverHelloPredictionData, length))
-+ memcpy(ss->ssl3.serverHelloPredictionData.data, b, length);
-+ /* ss->ssl3.serverHelloPredictionDataValid is still false at this
-+ * point. We have to record the contents of the ServerHello here
-+ * because we don't have a pointer to the whole message when handling
-+ * the extensions. However, we wait until the Snap Start extension
-+ * handler to recognise that the server supports Snap Start and to set
-+ * serverHelloPredictionDataValid. */
-+
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
-@@ -8366,20 +8366,6 @@
- }
- }
-
-- if ((ss->ssl3.hs.snapStartType == snap_start_recovery ||
-- ss->ssl3.hs.snapStartType == snap_start_resume_recovery) &&
-- ss->ssl3.snapStartApplicationData.data) {
-- /* In the event that the server ignored the application data in our
-- * snap start extension, we need to retransmit it now. */
-- PRInt32 sent = ssl3_SendRecord(ss, content_application_data,
-- ss->ssl3.snapStartApplicationData.data,
-- ss->ssl3.snapStartApplicationData.len,
-- flags);
-- SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
-- if (sent < 0)
-- return (SECStatus)sent; /* error code set by ssl3_SendRecord */
-- }
--
- return SECSuccess;
-
- fail:
diff --git a/net/third_party/nss/ssl.gyp b/net/third_party/nss/ssl.gyp
index eb732a0..bb8eabe 100644
--- a/net/third_party/nss/ssl.gyp
+++ b/net/third_party/nss/ssl.gyp
@@ -28,13 +28,11 @@
'ssl/authcert.c',
'ssl/cmpcert.c',
'ssl/derive.c',
- 'ssl/fnv1a64.c',
'ssl/nsskea.c',
'ssl/os2_err.c',
'ssl/os2_err.h',
'ssl/preenc.h',
'ssl/prelib.c',
- 'ssl/snapstart.c',
'ssl/ssl.h',
'ssl/ssl3con.c',
'ssl/ssl3ecc.c',
diff --git a/net/third_party/nss/ssl/fnv1a64.c b/net/third_party/nss/ssl/fnv1a64.c
deleted file mode 100644
index c7c4b08..0000000
--- a/net/third_party/nss/ssl/fnv1a64.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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/net/third_party/nss/ssl/snapstart.c b/net/third_party/nss/ssl/snapstart.c
deleted file mode 100644
index 92406a7..0000000
--- a/net/third_party/nss/ssl/snapstart.c
+++ /dev/null
@@ -1,1061 +0,0 @@
-/*
- * TLS Snap Start
- *
- * ***** 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: ssl3snap.c,v 1.0 2010/08/09 13:00:00 agl%google.com Exp $ */
-
-
-/* TODO(agl): Refactor ssl3_CompressMACEncryptRecord so that it can write to
-** |sendBuf| directly and fix ssl3_AppendSnapStartHandshakeRecord and
-** ssl3_AppendSnapStartApplicationData.
-*/
-
-/* TODO(agl): Add support for snap starting with compression. */
-
-#include "pk11pub.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-
-static unsigned int GetBE16(const void *in)
-{
- const unsigned char *p = in;
- return ((unsigned) p[0]) << 8 |
- p[1];
-}
-
-static unsigned int GetBE24(const void *in)
-{
- const unsigned char *p = in;
- return ((unsigned) p[0]) << 16 |
- ((unsigned) p[1]) << 8 |
- p[2];
-}
-
-static void PutBE16(void *out, unsigned int value)
-{
- unsigned char *p = out;
- p[0] = value >> 8;
- p[1] = value;
-}
-
-static void PutBE24(void *out, unsigned int value)
-{
- unsigned char *p = out;
- p[0] = value >> 16;
- p[1] = value >> 8;
- p[2] = value;
-}
-
-/* ssl3_ForEachExtension calls a callback for each TLS extension in |extensions|
-** extensions: points to a block of extensions which includes the two prefix
-** length bytes
-** is_resuming: if true, certain extensions will be omitted
-** f: a function which is called with the data of each extension, which
-** includes the four type and length bytes at the beginning.
-*/
-static PRBool
-ssl3_ForEachExtension(const SECItem *extensions, PRBool is_resuming,
- void (*f) (const unsigned char *data, unsigned int length,
- void *ctx),
- void *ctx) {
- unsigned int extensions_len, offset;
-
- if (extensions->len == 0)
- return PR_TRUE;
-
- if (extensions->len < 2)
- goto loser;
-
- extensions_len = GetBE16(extensions->data);
- offset = 2;
-
- if (extensions->len != 2 + extensions_len)
- goto loser;
-
- while (extensions_len) {
- unsigned int extension_num, extension_len;
-
- if (extensions->len - offset < 4)
- goto loser;
-
- extension_num = GetBE16(extensions->data + offset);
- extension_len = GetBE16(extensions->data + offset + 2);
-
- if (extensions->len - offset < 4 + extension_len)
- goto loser;
-
- /* When resuming, the server will omit some extensions from the
- * previous non-resume ServerHello. */
- if (!is_resuming ||
- (extension_num != ssl_server_name_xtn &&
- extension_num != ssl_session_ticket_xtn)) {
- f(extensions->data + offset, 4 + extension_len, ctx);
- }
-
- offset += 4 + extension_len;
- extensions_len -= 4 + extension_len;
- }
-
- return PR_TRUE;
-
-loser:
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return PR_FALSE;
-}
-
-static void
-ssl3_AccumlateLengths(const unsigned char *data, unsigned int length, void *ptr)
-{
- unsigned int *sum = (unsigned int *) ptr;
- *sum += length;
-}
-
-/* ssl3_PredictServerResponse predicts the contents of the server's
-** ServerHello...ServerHelloDone (inclusive) and progressively calls a callback
-** with the contents of those messages.
-** previous_server_hello: the contents of a previous ServerHello from the
-** server where the 'random' field has been replaced with our suggested
-** server random.
-** is_resuming: if false, Certificate and ServerHelloDone messages will be
-** predicted
-** hashUpdate: a callback which is called repeated with the contents of the
-** predicted messages.
-*/
-static PRBool
-ssl3_PredictServerResponse(
- sslSocket *ss, SECItem *previous_server_hello, PRBool is_resuming,
- void (*hashUpdate) (const unsigned char *data, unsigned int length,
- void *ctx),
- void *ctx) {
- unsigned int old_session_id_length, old_extensions_len;
- unsigned int extensions_len, server_hello_len;
- unsigned char session_id_len, header[4];
- SECItem extensions;
-
- /* Keep the structure of a ServerHello in mind when reading the following:
- *
- * struct ServerHello {
- * uint16_t version;
- * uint8_t random[32];
- * uint8_t session_id_len;
- * uint8_t session_id[session_id_len];
- * uint16_t cipher
- * uint8_t compression
- *
- * // Optional:
- * uint16_t extensions_len;
- * struct Extension {
- * uint16_t num;
- * uint16_t len;
- * uint8_t payload[len];
- * }
- */
-
- /* 38 bytes is the shortest possible ServerHello with a zero-length
- * session_id and no extensions. */
- if (previous_server_hello->len < 38) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return PR_FALSE;
- }
-
- /* First we need to figure out the length of the predicted ServerHello. Any
- * session id in |previous_server_hello| needs to be removed
- * (or replaced). */
- old_session_id_length = previous_server_hello->data[34];
-
- extensions.len = 0;
-
- if (previous_server_hello->len >= 35 + old_session_id_length + 3 + 2) {
- /* Extensions present */
- unsigned int offset = 35 + old_session_id_length + 3;
- extensions.data = previous_server_hello->data + offset;
- extensions.len = previous_server_hello->len - offset;
- }
-
- /* Sum the lengths of all the extensions that we wish to include */
- extensions_len = 0;
- if (!ssl3_ForEachExtension(&extensions, is_resuming, ssl3_AccumlateLengths,
- &extensions_len)) {
- return PR_FALSE;
- }
-
- old_extensions_len =
- (previous_server_hello->len - 35 - old_session_id_length - 3 - 2);
-
- session_id_len = 0;
- if (ss->sec.ci.sid)
- session_id_len = ss->sec.ci.sid->u.ssl3.sessionIDLength;
- server_hello_len = previous_server_hello->len +
- session_id_len - old_session_id_length +
- extensions_len - old_extensions_len;
-
- header[0] = server_hello;
- PutBE24(header + 1, server_hello_len);
- hashUpdate(header, 4, ctx);
-
- hashUpdate(previous_server_hello->data, 34, ctx);
- hashUpdate(&session_id_len, sizeof(session_id_len), ctx);
- if (session_id_len)
- hashUpdate(ss->sec.ci.sid->u.ssl3.sessionID, session_id_len, ctx);
- hashUpdate(previous_server_hello->data + 35 + old_session_id_length, 3,
- ctx);
-
- if (extensions.len) {
- PutBE16(header, extensions_len);
- hashUpdate(header, 2, ctx);
-
- if (!ssl3_ForEachExtension(&extensions, is_resuming, hashUpdate, ctx))
- return PR_FALSE;
- }
-
- if (!is_resuming) {
- unsigned int certificate_message_len = 3, i;
- for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
- certificate_message_len += 3;
- certificate_message_len +=
- ss->ssl3.predictedCertChain[i]->derCert.len;
- }
-
- header[0] = certificate;
- PutBE24(header + 1, certificate_message_len);
- hashUpdate(header, 4, ctx);
-
- PutBE24(header, certificate_message_len - 3);
- hashUpdate(header, 3, ctx);
-
- for (i = 0; ss->ssl3.predictedCertChain[i]; i++) {
- unsigned int len = ss->ssl3.predictedCertChain[i]->derCert.len;
- PutBE24(header, len);
- hashUpdate(header, 3, ctx);
- hashUpdate(ss->ssl3.predictedCertChain[i]->derCert.data, len, ctx);
- }
-
- header[0] = server_hello_done;
- header[1] = header[2] = header[3] = 0;
- hashUpdate(header, 4, ctx);
- }
-
- return PR_TRUE;
-}
-
-/* ssl3_SnapStartHash is called with the contents of the server's predicted
- * response and updates both the Finished hash and an FNV641a hash. */
-static void
-ssl3_SnapStartHash(const unsigned char *data, unsigned int len, void *ctx)
-{
- SECStatus rv;
- void **ptrs = (void **) ctx;
- sslSocket *ss = ptrs[0];
- PRUint64 *fnv = ptrs[1];
-
- FNV1A64_Update(fnv, data, len);
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *) data, len);
- if (rv != SECSuccess)
- PR_Assert("rv == SECSuccess", __FILE__, __LINE__);
-}
-
-static PRInt32
-ssl3_SendEmptySnapStartXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
-{
- SECStatus rv;
-
- if (maxBytes < 4)
- return 0;
-
- if (append) {
- rv = ssl3_AppendHandshakeNumber(ss, ssl_snap_start_xtn, 2);
- if (rv != SECSuccess)
- return -1;
- rv = ssl3_AppendHandshakeNumber(ss, 0 /* empty extension */, 2);
- if (rv != SECSuccess)
- return -1;
- if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] = ssl_snap_start_xtn;
- }
- }
- return 4;
-}
-
-static SECStatus
-ssl3_BufferEnsure(sslBuffer *buf, unsigned int extra_bytes)
-{
- if (buf->space < buf->len + extra_bytes)
- return sslBuffer_Grow(buf, buf->len + extra_bytes);
- return SECSuccess;
-}
-
-/* ssl3_AppendSnapStartRecordHeader appends a 5 byte TLS record header to the
- * sendBuf of the given sslSocket. */
-static SECStatus
-ssl3_AppendSnapStartRecordHeader(sslSocket *ss, SSL3ContentType type,
- unsigned int len)
-{
- SECStatus rv;
-
- rv = ssl3_BufferEnsure(&ss->sec.ci.sendBuf, 5);
- if (rv != SECSuccess)
- return rv;
- ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len + 0] = type;
- PutBE16(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len + 1], ss->version);
- PutBE16(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len + 3], len);
- ss->sec.ci.sendBuf.len += 5;
- return SECSuccess;
-}
-
-/* ssl3_AppendSnapStartHandshakeRecord appends a (possibly encrypted) record to
-** the sendBuf of the given sslSocket.
-** f: a function which will append the bytes of the record (not including the
-** 5 byte header) to the sendBuf.
-*/
-static SECStatus
-ssl3_AppendSnapStartHandshakeRecord(sslSocket *ss, SECStatus (*f) (sslSocket*),
- PRBool encrypt)
-{
- SECStatus rv;
- unsigned int record_offset, record_len;
-
- /* ssl3_CompressMACEncryptRecord will deal with the record header if we are
- * encrypting. */
- if (!encrypt) {
- /* The zero length argument here is a dummy value. We write the real
- * length once we know it, below. */
- rv = ssl3_AppendSnapStartRecordHeader(ss, content_handshake, 0);
- if (rv != SECSuccess)
- return rv;
- }
-
- record_offset = ss->sec.ci.sendBuf.len;
- rv = f(ss);
- if (rv != SECSuccess)
- return rv;
- record_len = ss->sec.ci.sendBuf.len - record_offset;
- if (!encrypt) {
- PutBE16(&ss->sec.ci.sendBuf.buf[record_offset - 2], record_len);
- } else {
- /* ssl3_CompressMACEncryptRecord writes to |ss->sec.writeBuf|
- * so we copy it back to |ss->sec.ci.sendBuf| */
- /* TODO(agl): the buffer copy here is a bodge. See TODO at the top of
- * the file. */
- rv = ssl3_CompressMACEncryptRecord(
- ss, content_handshake,
- &ss->sec.ci.sendBuf.buf[record_offset], record_len);
- if (rv != SECSuccess)
- return rv;
- ss->sec.ci.sendBuf.len -= record_len;
- ssl3_BufferEnsure(&ss->sec.ci.sendBuf, ss->sec.writeBuf.len);
- memcpy(&ss->sec.ci.sendBuf.buf[record_offset], ss->sec.writeBuf.buf,
- ss->sec.writeBuf.len);
- ss->sec.ci.sendBuf.len += ss->sec.writeBuf.len;
- ss->sec.writeBuf.len = 0;
- }
-
- return SECSuccess;
-}
-
-/* ssl3_AppendSnapStartApplicationData appends an encrypted Application Data
-** record the sendBuf of the given sslSocket.
-*/
-static SECStatus ssl3_AppendSnapStartApplicationData(
- sslSocket *ss, const SSL3Opaque *data, unsigned int len)
-{
- SECStatus rv;
-
- /* TODO(agl): the buffer copy here is a bodge. See TODO at the top of the
- * file. */
- rv = ssl3_CompressMACEncryptRecord(ss, content_application_data, data, len);
- if (rv != SECSuccess)
- return rv;
- rv = ssl3_BufferEnsure(&ss->sec.ci.sendBuf, ss->sec.writeBuf.len);
- if (rv != SECSuccess)
- return rv;
- memcpy(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len],
- ss->sec.writeBuf.buf, ss->sec.writeBuf.len);
- ss->sec.ci.sendBuf.len += ss->sec.writeBuf.len;
- ss->sec.writeBuf.len = 0;
-
- return SECSuccess;
-}
-
-static SECStatus ssl3_SendSnapStartFinished(sslSocket *ss)
-{
- /* We use ssl_SEND_FLAG_NO_FLUSH here because this finished message is
- * going to end up in the middle of the Snap Start extension. So
- * transmitting |sendBuf| at this point would result in an incomplete
- * ClientHello. */
- return ssl3_SendFinished(ss, ssl_SEND_FLAG_NO_FLUSH);
-}
-
-/* ssl3_FindOrbit is called for each extension in a ServerHello message. It
-** tests for a Snap Start extension and records the server's orbit when found.
-** data: the extension data (including the four type and length bytes)
-** length: the length, in bytes, of |data|
-** ptr: a pointer to a uint8_t[9]. The orbit, if found, is copied into the
-** first 8 bytes and then the ninth byte is set to one.
-*/
-static void
-ssl3_FindOrbit(const unsigned char *data, unsigned int length, void *ptr)
-{
- unsigned char *orbit = (unsigned char *) ptr;
-
- unsigned int extension_num = GetBE16(data);
- if (extension_num == ssl_snap_start_xtn &&
- length == 4 + 8 /* orbit */ + 2 /* snap start cipher suite */) {
- memcpy(orbit, data + 4, 8);
- /* A last byte of 1 indicates that the previous eight are valid. */
- orbit[8] = 1;
- }
-}
-
-/* ssl3_CanSnapStart returns true if we are able to perform Snap Start on
-** the given socket.
-** extensions: on successful return, this is filled in with the contents of
-** the server's predicted extensions. This points within
-** |ss->ssl3.serverHelloPredictionData|.
-** resuming: PR_TRUE iff we wish to attempt a Snap Start resume
-** out_orbit: if this function returns PR_TRUE, then |out_orbit| is filled
-** with the server's predicted orbit value.
-** The |hs.cipher_suite|, |hs.cipher_def| and |hs.compression| fields of |ss|
-** are set to match the predicted ServerHello on successful exit (and may still
-** be modified on failure).
-*/
-static PRBool
-ssl3_CanSnapStart(sslSocket *ss, SECItem *extensions, PRBool resuming,
- unsigned char out_orbit[8]) {
- const unsigned char *server_hello;
- unsigned int server_hello_len, session_id_len, cipher_suite_offset;
- unsigned int extensions_offset, cipher_suite, compression_method;
- unsigned char orbit[9];
- SECStatus rv;
- SSL3ProtocolVersion version;
-
- /* If we don't have the information needed then we can't perform a Snap
- * Start. */
- if (!ss->ssl3.predictedCertChain || !ss->ssl3.serverHelloPredictionData.data)
- return PR_FALSE;
-
- /* When the sizes of the fields in the ClientHello are calculated, they'll
- * take the length of the Snap Start extension to be zero, so currently
- * it's as if this extension didn't exist, which is the state that we
- * need. */
-
- server_hello = ss->ssl3.serverHelloPredictionData.data;
- server_hello_len = ss->ssl3.serverHelloPredictionData.len;
-
- if (server_hello_len < 2 + 32 + 1)
- return PR_FALSE;
- session_id_len = server_hello[2 + 32];
- cipher_suite_offset = 2 + 32 + 1 + session_id_len;
- if (server_hello_len < cipher_suite_offset + 3)
- return PR_FALSE;
- extensions_offset = cipher_suite_offset + 3;
-
- version = (SSL3ProtocolVersion) GetBE16(server_hello);
- if (MSB(version) < MSB(SSL_LIBRARY_VERSION_3_0))
- return PR_FALSE;
- rv = ssl3_NegotiateVersion(ss, version);
- if (rv != SECSuccess)
- return PR_FALSE;
-
- cipher_suite = GetBE16(&server_hello[cipher_suite_offset]);
- ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)cipher_suite;
- ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
- if (!ss->ssl3.hs.suite_def)
- return PR_FALSE;
- compression_method = server_hello[cipher_suite_offset + 2];
- if (compression_method != ssl_compression_null) {
- /* TODO(agl): support compression. */
- return PR_FALSE;
- }
- ss->ssl3.hs.compression = ssl_compression_null;
-
- extensions->data = (unsigned char *) server_hello + extensions_offset;
- extensions->len = server_hello_len - extensions_offset;
-
- /* The last byte is used to indictate that the previous eight are valid. */
- orbit[8] = 0;
- if (!ssl3_ForEachExtension(extensions, resuming, ssl3_FindOrbit, orbit))
- return PR_FALSE;
-
- if (!orbit[8])
- return PR_FALSE;
-
- memcpy(out_orbit, orbit, 8);
-
- return PR_TRUE;
-}
-
-/* ssl3_UpdateClientHelloLengths rewrites the handshake header length and
-** extensions length in the ClientHello to reflect the addition of the Snap
-** Start extension.
-** snap_start_extension_len_offset: the number of bytes of the ClientHello to
-** skip in order to find the embedded length of the Snap Start extension.
-*/
-static void
-ssl3_UpdateClientHelloLengths(sslSocket *ss,
- unsigned int snap_start_extension_len_offset,
- sslSessionID *sid) {
- unsigned int extension_length, old_length, new_length, new_session_id_len;
- unsigned int offset, ciphers_length, compressions_len;
-
- extension_length =
- ss->sec.ci.sendBuf.len - snap_start_extension_len_offset - 2;
- PutBE16(&ss->sec.ci.sendBuf.buf[snap_start_extension_len_offset],
- extension_length);
-
- /* The length in the handshake header is short by extension_length + 4
- * bytes. */
- old_length = GetBE24(&ss->sec.ci.sendBuf.buf[1]);
- new_length = old_length + extension_length + 4;
- PutBE24(&ss->sec.ci.sendBuf.buf[1], new_length);
-
- /* The length of the extensions block is similarly wrong. */
- new_session_id_len = 0;
- if (sid)
- new_session_id_len = sid->u.ssl3.sessionIDLength;
- offset = 4 + 2 + 32 + 1 + new_session_id_len;
- ciphers_length = GetBE16(&ss->sec.ci.sendBuf.buf[offset]);
- offset += 2 + ciphers_length;
- compressions_len = ss->sec.ci.sendBuf.buf[offset];
- offset += 1 + compressions_len;
- old_length = GetBE16(&ss->sec.ci.sendBuf.buf[offset]);
- new_length = old_length + extension_length + 4;
- PutBE16(&ss->sec.ci.sendBuf.buf[offset], new_length);
-}
-
-/* ssl3_FindServerNPNExtension is a callback function for ssl3_ForEachExtension.
- * It looks for a Next Protocol Negotiation and saves the payload of the
- * extension in the given SECItem */
-static void
-ssl3_FindServerNPNExtension(const unsigned char* data, unsigned int length,
- void *ctx)
-{
- SECItem *server_npn_extension = (SECItem*) ctx;
-
- unsigned int extension_num = GetBE16(data);
- if (extension_num == ssl_next_proto_neg_xtn && length >= 4) {
- server_npn_extension->data = (unsigned char*)data + 4;
- server_npn_extension->len = length - 4;
- }
-}
-
-/* ssl3_MaybeWriteNextProtocol deals with the interaction of Next Protocol
- * Negotiation and Snap Start. It's called just before we serialise the embedded
- * Finished message in the extension. At this point, if NPN is enabled, we have
- * to include a NextProtocol message. */
-static SECStatus
-ssl3_MaybeWriteNextProtocol(sslSocket *ss, SECItem *server_hello_extensions)
-{
- PRUint16 i16;
- SECItem server_npn_extension;
-
- for (i16 = 0; i16 < ss->xtnData.numAdvertised; i16++) {
- if (ss->xtnData.advertised[i16] == ssl_next_proto_neg_xtn)
- break;
- }
-
- if (i16 == ss->xtnData.numAdvertised) {
- /* We didn't send an NPN extension, so no need to do anything here. */
- return SECSuccess;
- }
-
- memset(&server_npn_extension, 0, sizeof(server_npn_extension));
-
- ssl3_ForEachExtension(
- server_hello_extensions, PR_FALSE /* is_resuming: value doesn't matter
- in this case */, ssl3_FindServerNPNExtension, &server_npn_extension);
-
- if (server_npn_extension.data == NULL) {
- /* We predicted that the server doesn't support NPN, so nothing to do
- * here. */
- return SECSuccess;
- }
-
- ssl3_ClientHandleNextProtoNegoXtn(ss, ssl_next_proto_neg_xtn,
- &server_npn_extension);
-
- if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT) {
- /* The server's predicted NPN extension was malformed. We're didn't pick
- * a protocol so we won't send a NextProtocol message. However, this is
- * probably fatal to the connection. */
- return SECSuccess;
- }
-
- return ssl3_AppendSnapStartHandshakeRecord(ss, ssl3_SendNextProto,
- PR_TRUE /* encrypt */);
-}
-
-/* ssl3_SendSnapStartXtn appends a Snap Start extension. It assumes that the
- * inchoate ClientHello is in |ss->sec.ci.sendBuf|. */
-PRInt32
-ssl3_SendSnapStartXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
-{
- unsigned char orbit[8];
- PRBool resuming = PR_FALSE;
- unsigned char suggested_server_random[32];
- SECStatus rv;
- PRUint64 fnv;
- /* The context for |ssl3_SnapStartHash|. The first pointer points to |ss|
- * and the second to the running FNV1A64 hash of the predicted server
- * response. */
- void *ctx[2];
- unsigned int snap_start_extension_len_offset, original_sendbuf_len;
- ssl3CipherSpec *temp;
- sslSessionID *sid;
- SECItem server_extensions;
-
- if (!ss->opt.enableSnapStart)
- return 0;
-
- original_sendbuf_len = ss->sec.ci.sendBuf.len;
-
- /* This function is called twice for each ClientHello emitted. The first
- * time around is to calculate the sizes of the extension (|append| is
- * false). The second time around is to actually write out the bytes
- * (|append| is true).
- *
- * We always return 0 bytes in each case because we want to be able to hash
- * the inchoate ClientHello as if this extension was missing: that's why
- * it's important that this always be the last extension serialised. */
- sid = ss->sec.ci.sid;
-
- if (!ss->opt.enableSessionTickets || ss->sec.isServer)
- return 0;
-
- /* If we are sending a SessionTicket then the first time around
- * ticketTimestampVerified will be true but it's reset after serialising
- * the session ticket extension, so we have
- * |clientSentNonEmptySessionTicket|. */
- if (ss->xtnData.clientSentNonEmptySessionTicket) {
- resuming = PR_TRUE;
- } else if (sid->u.ssl3.sessionTicket.ticket.data &&
- ss->xtnData.ticketTimestampVerified) {
- resuming = PR_TRUE;
- }
-
- if (!ssl3_CanSnapStart(ss, &server_extensions, resuming, orbit))
- return ssl3_SendEmptySnapStartXtn(ss, append, maxBytes);
-
- /* At this point we are happy that we are going to send a non-empty Snap
- * Start extension. If we are still calculating length then we lie and
- * return 0 so that everything is set up as if the extension didn't exist
- * when this function is called again later. */
-
- if (!append)
- return 0;
-
- /* |ss->sec.ci.sendBuf.buf| contains the inchoate ClientHello. This copies
- * the ClientHello's gmt_unix_time into the suggested server random. */
- memcpy(suggested_server_random, ss->sec.ci.sendBuf.buf + 6, 4);
- memcpy(suggested_server_random + 4, orbit, 8);
- rv = PK11_GenerateRandom(suggested_server_random + 12, 20);
- if (rv != SECSuccess)
- goto loser;
- memcpy(ss->ssl3.serverHelloPredictionData.data + 2, suggested_server_random,
- 32);
-
- memcpy(&ss->ssl3.hs.server_random, suggested_server_random, 32);
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- rv = ssl3_SetupPendingCipherSpec(ss);
- if (rv != SECSuccess)
- goto loser;
- ss->ssl3.hs.isResuming = resuming;
-
- FNV1A64_Init(&fnv);
- ctx[0] = ss;
- ctx[1] = &fnv;
-
- if (!ssl3_PredictServerResponse(ss, &ss->ssl3.serverHelloPredictionData,
- resuming, ssl3_SnapStartHash, ctx)) {
- /* It's not a fatal error if the predicted ServerHello was invalid. */
- return 0;
- }
- FNV1A64_Final(&fnv);
-
- /* Now we grow the send buffer to accomodate the extension type and length,
- * orbit, suggested random and predicted server response hash without
- * calling ssl3_AppendHandshake (which would also update the Finished
- * hash). */
- if (ssl3_BufferEnsure(&ss->sec.ci.sendBuf, 4 + 8 + 20 + 8) != SECSuccess)
- goto loser;
-
- PutBE16(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len],
- ssl_snap_start_xtn);
- ss->sec.ci.sendBuf.len += 2;
- /* Skip over the length for now. */
- snap_start_extension_len_offset = ss->sec.ci.sendBuf.len;
- ss->sec.ci.sendBuf.len += 2;
- memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, orbit, 8);
- ss->sec.ci.sendBuf.len += 8;
- memcpy(&ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len],
- suggested_server_random + 12, 20);
- ss->sec.ci.sendBuf.len += 20;
- memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, &fnv, 8);
- ss->sec.ci.sendBuf.len += 8;
-
- if (!resuming) {
- /* Write ClientKeyExchange */
- ss->sec.peerCert =
- CERT_DupCertificate(ss->ssl3.predictedCertChain[0]);
- rv = ssl3_AppendSnapStartHandshakeRecord(
- ss, ssl3_SendClientKeyExchange, PR_FALSE /* do not encrypt */);
- if (rv != SECSuccess)
- goto loser;
- } else {
- SSL3Finished hashes;
- TLSFinished tlsFinished;
- unsigned char hdr[4];
-
- rv = ssl3_SetupMasterSecretFromSessionID(ss);
- if (rv == SECFailure)
- goto loser;
-
- if (sid->peerCert != NULL) {
- ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
- ssl3_CopyPeerCertsFromSID(ss, sid);
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, NULL /* re-use master secret */);
- if (rv != SECSuccess)
- goto loser;
-
- /* Need to add the server's predicted Finished message to our handshake
- * hash in order to be able to produce our own Finished message. */
- rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes,
- 0 /* only for SSL3 */);
- if (rv != SECSuccess)
- goto loser;
-
- rv = ssl3_ComputeTLSFinished(ss->ssl3.pwSpec, PR_TRUE /* isServer */,
- &hashes, &tlsFinished);
- if (rv != SECSuccess)
- goto loser;
-
- hdr[0] = (unsigned char) finished;
- hdr[1] = hdr[2] = 0;
- hdr[3] = sizeof(tlsFinished.verify_data);
- ssl3_UpdateHandshakeHashes(ss, hdr, sizeof(hdr));
- ssl3_UpdateHandshakeHashes(ss, tlsFinished.verify_data,
- sizeof(tlsFinished.verify_data));
-
- /* Store the Finished message so that we can verify it later */
- memcpy(&ss->ssl3.hs.finishedMsgs.tFinished[1], tlsFinished.verify_data,
- sizeof(tlsFinished.verify_data));
- }
-
- /* Write ChangeCipherSpec */
- rv = ssl3_AppendSnapStartRecordHeader(ss, content_change_cipher_spec, 1);
- if (rv != SECSuccess)
- goto loser;
- rv = ssl3_BufferEnsure(&ss->sec.ci.sendBuf, 1);
- if (rv != SECSuccess)
- goto loser;
- ss->sec.ci.sendBuf.buf[ss->sec.ci.sendBuf.len] = change_cipher_spec_choice;
- ss->sec.ci.sendBuf.len++;
-
- /* We swap |cwSpec| and |pwSpec| temporarily in order to encrypt some
- * records before switching them back so that the whole ClientHello doesn't
- * get encrypted. */
- ssl_GetSpecWriteLock(ss);
- temp = ss->ssl3.cwSpec;
- ss->ssl3.cwSpec = ss->ssl3.pwSpec;
- ss->ssl3.pwSpec = temp;
- ss->ssl3.cwSpec->write_seq_num.high = 0;
- ss->ssl3.cwSpec->write_seq_num.low = 0;
- ssl_ReleaseSpecWriteLock(ss);
-
- rv = ssl3_MaybeWriteNextProtocol(ss, &server_extensions);
- if (rv != SECSuccess)
- goto loser;
-
- /* Write Finished */
- rv = ssl3_AppendSnapStartHandshakeRecord(ss, ssl3_SendSnapStartFinished,
- PR_TRUE /* encrypt */);
- if (rv != SECSuccess)
- goto loser;
-
- /* Write application data */
- if (ss->ssl3.snapStartApplicationData.data) {
- rv = ssl3_AppendSnapStartApplicationData(
- ss, ss->ssl3.snapStartApplicationData.data,
- ss->ssl3.snapStartApplicationData.len);
- SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* Revert the write cipher spec because the ClientHello will get encrypted
- * with it otherwise. */
- ssl_GetSpecWriteLock(ss);
- temp = ss->ssl3.cwSpec;
- ss->ssl3.cwSpec = ss->ssl3.pwSpec;
- ss->ssl3.pwSpec = temp;
- ssl_ReleaseSpecWriteLock(ss);
-
- /* Update the lengths in the ClientHello to reflect this extension. */
- ssl3_UpdateClientHelloLengths(ss, snap_start_extension_len_offset, sid);
-
- /* Keep a copy of the ClientHello around so that we can hash it in the case
- * the the Snap Start handshake is rejected. */
-
- if (SECITEM_AllocItem(NULL, &ss->ssl3.hs.origClientHello,
- ss->sec.ci.sendBuf.len) == NULL) {
- goto loser;
- }
- memcpy(ss->ssl3.hs.origClientHello.data, ss->sec.ci.sendBuf.buf,
- ss->sec.ci.sendBuf.len);
- ss->ssl3.hs.origClientHello.len = ss->sec.ci.sendBuf.len;
-
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] = ssl_snap_start_xtn;
-
- if (resuming) {
- ss->ssl3.hs.snapStartType = snap_start_resume;
- } else {
- ss->ssl3.hs.snapStartType = snap_start_full;
- }
-
- return 0;
-
-loser:
- /* In the case of an error we revert the length of the sendBuf to remove
- * any partial data that we may have appended. */
- ss->sec.ci.sendBuf.len = original_sendbuf_len;
- return -1;
-}
-
-SECStatus ssl3_ClientHandleSnapStartXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data) {
- /* The work of saving the ServerHello is done in ssl3_HandleServerHello,
- * where its contents are available. Here we renognise that the saved
- * ServerHello message contains a Snap Start extension and mark it as
- * valid. */
- ss->ssl3.serverHelloPredictionDataValid = PR_TRUE;
- 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;
-}
-
-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;
-}
-
-SECStatus
-SSL_GetPredictedServerHelloData(PRFileDesc *fd, const unsigned char **data,
- unsigned int *data_len)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPredictedServerHelloData",
- SSL_GETPID(), fd));
- *data = NULL;
- *data_len = 0;
- return SECFailure;
- }
-
- if (!ss->ssl3.serverHelloPredictionDataValid) {
- *data = NULL;
- *data_len = 0;
- } else {
- *data = ss->ssl3.serverHelloPredictionData.data;
- *data_len = ss->ssl3.serverHelloPredictionData.len;
- }
- return SECSuccess;
-}
-
-SECStatus
-SSL_SetPredictedServerHelloData(PRFileDesc *fd, const unsigned char *data,
- unsigned int data_len)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPredictedServerHelloData",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ss->ssl3.serverHelloPredictionData.data)
- SECITEM_FreeItem(&ss->ssl3.serverHelloPredictionData, PR_FALSE);
- if (!SECITEM_AllocItem(NULL, &ss->ssl3.serverHelloPredictionData, data_len))
- return SECFailure;
- memcpy(ss->ssl3.serverHelloPredictionData.data, data, data_len);
- return SECSuccess;
-}
-
-SECStatus
-SSL_SetSnapStartApplicationData(PRFileDesc *fd, const unsigned char *data,
- unsigned int data_len)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSnapStartApplicationData",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ss->ssl3.snapStartApplicationData.data)
- SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
- if (!SECITEM_AllocItem(NULL, &ss->ssl3.snapStartApplicationData, data_len))
- return SECFailure;
- memcpy(ss->ssl3.snapStartApplicationData.data, data, data_len);
- return SECSuccess;
-}
-
-SECStatus
-SSL_GetSnapStartResult(PRFileDesc *fd, SSLSnapStartResult *result)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSnapStartResult",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- switch (ss->ssl3.hs.snapStartType) {
- case snap_start_full:
- *result = SSL_SNAP_START_FULL;
- break;
- case snap_start_recovery:
- *result = SSL_SNAP_START_RECOVERY;
- break;
- case snap_start_resume:
- *result = SSL_SNAP_START_RESUME;
- break;
- case snap_start_resume_recovery:
- *result = SSL_SNAP_START_RESUME_RECOVERY;
- break;
- default:
- PORT_Assert(ss->ssl3.hs.snapStartType == snap_start_none);
- *result = SSL_SNAP_START_NONE;
- break;
- }
-
- return SECSuccess;
-}
-
-/* Called form ssl3_HandleServerHello in the case that we sent a Snap Start
-** ClientHello but received a ServerHello in reply.
-*/
-SECStatus
-ssl3_ResetForSnapStartRecovery(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- SECStatus rv;
- PRUint8 hdr[4];
-
- ss->ssl3.hs.ws = wait_server_hello;
-
- /* Need to reset the Finished hashes to include the full ClientHello
- * message. */
-
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess)
- return rv;
- rv = ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.origClientHello.data,
- ss->ssl3.hs.origClientHello.len);
- SECITEM_FreeItem(&ss->ssl3.hs.origClientHello, PR_FALSE);
- if (rv != SECSuccess)
- return rv;
-
- hdr[0] = (PRUint8)server_hello;
- hdr[1] = (PRUint8)(length >> 16);
- hdr[2] = (PRUint8)(length >> 8);
- hdr[3] = (PRUint8)(length );
-
- rv = ssl3_UpdateHandshakeHashes(ss, hdr, sizeof(hdr));
- if (rv != SECSuccess)
- return rv;
- rv = ssl3_UpdateHandshakeHashes(ss, b, length);
- if (rv != SECSuccess)
- return rv;
-
- if (ss->ssl3.hs.snapStartType == snap_start_full) {
- ss->ssl3.hs.snapStartType = snap_start_recovery;
- } else {
- ss->ssl3.hs.snapStartType = snap_start_resume_recovery;
- }
-
- ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT;
-
- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_TRUE/*freeSrvName*/);
-
- return SECSuccess;
-}
diff --git a/net/third_party/nss/ssl/ssl.def b/net/third_party/nss/ssl/ssl.def
index 76417d0..35cc1e3 100644
--- a/net/third_party/nss/ssl/ssl.def
+++ b/net/third_party/nss/ssl/ssl.def
@@ -155,19 +155,9 @@ SSL_SNISocketConfigHook;
;+NSS_CHROMIUM {
;+ global:
SSL_GetNextProto;
-SSL_SetNextProtoNego;
-;+ local:
-;+*;
-;+};
-;+NSS_3.13 { # NSS 3.13 release
-;+ global:
-SSL_GetPredictedServerHelloData;
-SSL_GetSnapStartResult;
SSL_GetStapledOCSPResponse;
SSL_PeerCertificateChain;
-SSL_SetPredictedPeerCertificates;
-SSL_SetPredictedServerHelloData;
-SSL_SetSnapStartApplicationData;
+SSL_SetNextProtoNego;
;+ local:
;+*;
;+};
diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
index f2a0c11..563cfd5 100644
--- a/net/third_party/nss/ssl/ssl.h
+++ b/net/third_party/nss/ssl/ssl.h
@@ -139,16 +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_SNAP_START 23 /* Enable SSL snap start (off by */
- /* default, applies only to */
- /* clients). Snap start is a way */
-/* of performing TLS handshakes with no round trips. The client's entire */
-/* handshake is included in the first handshake message, along with */
-/* optional application data. In order to do this, information from a */
-/* previous connection to the same server is required. See */
-/* SSL_GetPredictedServerHelloData, SSL_SetPredictedPeerCertificates and */
-/* SSL_SetSnapStartApplicationData. */
-#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
+#define SSL_ENABLE_OCSP_STAPLING 23 /* Request OCSP stapling (client) */
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
@@ -447,49 +438,6 @@ 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 Snap Start extension. Note that the SSL_ENABLE_SNAP_START 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);
-
-/*
-** Get the data needed to predict the server's hello message in the future. On
-** return, |*data| will either be NULL (in which case no data is available and
-** |*data_len| will be zero) or it will point to a buffer within the internal
-** data of |fd| and |*data_len| will contain the number of bytes available. If
-** non-NULL, |*data| will persist at least until the next handshake on |fd|.
-*/
-SSL_IMPORT SECStatus SSL_GetPredictedServerHelloData(
- PRFileDesc *fd, const unsigned char **data,
- unsigned int *data_len);
-
-/*
-** Set the predicted server hello data. This is used for the TLS Snap Start
-** extension. Note that the SSL_ENABLE_SNAP_START option must be set for this
-** to occur.
-*/
-SSL_IMPORT SECStatus SSL_SetPredictedServerHelloData(
- PRFileDesc *fd, const unsigned char *data, unsigned int data_len);
-
-/* Set the application data which will be transmitted in a Snap Start
-** handshake. If the Snap Start handshake fails, this data will be
-* retransmitted automatically. */
-SSL_IMPORT SECStatus SSL_SetSnapStartApplicationData(
- PRFileDesc *fd, const unsigned char *data, unsigned int data_len);
-
-/* Get the result of a Snap Start handshake. It's valid to call then even if
-** SSL_ENABLE_SNAP_START hasn't been set, although the result will always be
-** SSL_SNAP_START_NONE.
-*/
-SSL_IMPORT SECStatus SSL_GetSnapStartResult(PRFileDesc* socket,
- SSLSnapStartResult* result);
-
-/*
** 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/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index ac23c4c..0997e18 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -72,8 +72,7 @@
#endif
static void ssl3_CleanupPeerCerts(sslSocket *ss);
-static void ssl3_CopyPeerCertsToSID(ssl3CertNode *certs,
- sslSessionID *sid);
+static void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo * serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
@@ -83,10 +82,14 @@ 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);
static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss);
+static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, unsigned char *b,
+ unsigned int l);
static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
int maxOutputLen, const unsigned char *input,
@@ -580,7 +583,7 @@ void SSL_AtomicIncrementLong(long * x)
/* return pointer to ssl3CipherSuiteDef for suite, or NULL */
/* XXX This does a linear search. A binary search would be better. */
-const ssl3CipherSuiteDef *
+static const ssl3CipherSuiteDef *
ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
{
int cipher_suite_def_len =
@@ -1166,7 +1169,7 @@ ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
** ssl3_DestroySSL3Info
** Caller must hold SpecWriteLock.
*/
-void
+static void
ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
{
PRBool freeit = (PRBool)(!spec->bypassCiphers);
@@ -1208,7 +1211,7 @@ ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
** Caller must hold the ssl3 handshake lock.
** Acquires & releases SpecWriteLock.
*/
-SECStatus
+static SECStatus
ssl3_SetupPendingCipherSpec(sslSocket *ss)
{
ssl3CipherSpec * pwSpec;
@@ -2040,7 +2043,7 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
#endif /* NSS_PLATFORM_CLIENT_AUTH */
}
-SECStatus
+static SECStatus
ssl3_CompressMACEncryptRecord(sslSocket * ss,
SSL3ContentType type,
const SSL3Opaque * pIn,
@@ -3102,7 +3105,7 @@ loser:
return SECFailure;
}
-SECStatus
+static SECStatus
ssl3_RestartHandshakeHashes(sslSocket *ss)
{
SECStatus rv = SECSuccess;
@@ -3180,7 +3183,7 @@ loser:
** ssl3_HandleHandshakeMessage()
** Caller must hold the ssl3Handshake lock.
*/
-SECStatus
+static SECStatus
ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l)
{
SECStatus rv = SECSuccess;
@@ -3439,7 +3442,7 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
* Caller must hold a read or write lock on the Spec R/W lock.
* (There is presently no way to assert on a Read lock.)
*/
-SECStatus
+static SECStatus
ssl3_ComputeHandshakeHashes(sslSocket * ss,
ssl3CipherSpec *spec, /* uses ->master_secret */
SSL3Hashes * hashes, /* output goes here. */
@@ -4037,18 +4040,7 @@ ssl3_SendClientHello(sslSocket *ss)
return rv; /* error code set by ssl3_FlushHandshake */
}
- switch (ss->ssl3.hs.snapStartType) {
- case snap_start_full:
- ss->ssl3.hs.ws = wait_new_session_ticket;
- break;
- case snap_start_resume:
- ss->ssl3.hs.ws = wait_change_cipher;
- break;
- default:
- ss->ssl3.hs.ws = wait_server_hello;
- break;
- }
-
+ ss->ssl3.hs.ws = wait_server_hello;
return rv;
}
@@ -4739,7 +4731,7 @@ loser:
/* Called from ssl3_HandleServerHelloDone(). */
-SECStatus
+static SECStatus
ssl3_SendClientKeyExchange(sslSocket *ss)
{
SECKEYPublicKey * serverKey = NULL;
@@ -4879,94 +4871,6 @@ done:
return rv;
}
-/* Called from ssl3_HandleServerHello to set up the master secret in
- * ss->ssl3.pwSpec and the auth algorithm and kea type in ss->sec in the case
- * of a successful session resumption. */
-SECStatus ssl3_SetupMasterSecretFromSessionID(sslSocket* ss) {
- sslSessionID *sid = ss->sec.ci.sid;
- ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
- SECItem wrappedMS; /* wrapped master secret. */
-
- ss->sec.authAlgorithm = sid->authAlgorithm;
- ss->sec.authKeyBits = sid->authKeyBits;
- ss->sec.keaType = sid->keaType;
- ss->sec.keaKeyBits = sid->keaKeyBits;
-
- /* 3 cases here:
- * a) key is wrapped (implies using PKCS11)
- * b) key is unwrapped, but we're still using PKCS11
- * c) key is unwrapped, and we're bypassing PKCS11.
- */
- if (sid->u.ssl3.keys.msIsWrapped) {
- PK11SlotInfo *slot;
- PK11SymKey * wrapKey; /* wrapping key */
- CK_FLAGS keyFlags = 0;
-
- if (ss->opt.bypassPKCS11) {
- /* we cannot restart a non-bypass session in a
- ** bypass socket.
- */
- return SECFailure;
- }
- /* unwrap master secret with PKCS11 */
- slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- if (slot == NULL) {
- return SECFailure;
- }
- if (!PK11_IsPresent(slot)) {
- PK11_FreeSlot(slot);
- return SECFailure;
- }
- wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (wrapKey == NULL) {
- return SECFailure;
- }
-
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
-
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- PK11_FreeSymKey(wrapKey);
- if (pwSpec->master_secret == NULL) {
- return SECFailure;
- }
- } else if (ss->opt.bypassPKCS11) {
- /* MS is not wrapped */
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
- pwSpec->msItem.data = pwSpec->raw_master_secret;
- pwSpec->msItem.len = wrappedMS.len;
- } else {
- /* We CAN restart a bypass session in a non-bypass socket. */
- /* need to import the raw master secret to session object */
- PK11SlotInfo *slot = PK11_GetInternalSlot();
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- pwSpec->master_secret =
- PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
- PK11_OriginUnwrap, CKA_ENCRYPT,
- &wrappedMS, NULL);
- PK11_FreeSlot(slot);
- if (pwSpec->master_secret == NULL) {
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 ServerHello message.
* Caller must hold Handshake and RecvBuf locks.
@@ -4991,14 +4895,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (ss->ssl3.hs.snapStartType == snap_start_full ||
- ss->ssl3.hs.snapStartType == snap_start_resume) {
- /* Snap Start handshake was rejected. */
- rv = ssl3_ResetForSnapStartRecovery(ss, b, length);
- if (rv != SECSuccess)
- return rv;
- }
-
rv = ssl3_InitState(ss);
if (rv != SECSuccess) {
errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
@@ -5030,21 +4926,6 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
#endif /* NSS_PLATFORM_CLIENT_AUTH */
- if (ss->ssl3.serverHelloPredictionData.data)
- SECITEM_FreeItem(&ss->ssl3.serverHelloPredictionData, PR_FALSE);
-
- /* If this allocation fails it will only stop the application from
- * recording the ServerHello information and performing future Snap
- * Starts. */
- if (SECITEM_AllocItem(NULL, &ss->ssl3.serverHelloPredictionData, length))
- memcpy(ss->ssl3.serverHelloPredictionData.data, b, length);
- /* ss->ssl3.serverHelloPredictionDataValid is still false at this
- * point. We have to record the contents of the ServerHello here
- * because we don't have a pointer to the whole message when handling
- * the extensions. However, we wait until the Snap Start extension
- * handler to recognise that the server supports Snap Start and to set
- * serverHelloPredictionDataValid. */
-
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (temp < 0) {
goto loser; /* alert has been sent */
@@ -5185,40 +5066,118 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (sid_match &&
sid->version == ss->version &&
- sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) {
- rv = ssl3_SetupMasterSecretFromSessionID(ss);
- /* Failure of ssl3_SetupMasterSecretFromSessionID not considered an
- * error. Continue with a full handshake. */
- if (rv == SECSuccess) {
- /* Got a Match */
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
+ sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do {
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
- /* If we sent a session ticket, then this is a stateless resume. */
- if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
- sid->u.ssl3.sessionTicket.ticket.data != NULL)
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );
+ SECItem wrappedMS; /* wrapped master secret. */
- if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
- ss->ssl3.hs.ws = wait_new_session_ticket;
- else
- ss->ssl3.hs.ws = wait_change_cipher;
+ ss->sec.authAlgorithm = sid->authAlgorithm;
+ ss->sec.authKeyBits = sid->authKeyBits;
+ ss->sec.keaType = sid->keaType;
+ ss->sec.keaKeyBits = sid->keaKeyBits;
- ss->ssl3.hs.isResuming = PR_TRUE;
+ /* 3 cases here:
+ * a) key is wrapped (implies using PKCS11)
+ * b) key is unwrapped, but we're still using PKCS11
+ * c) key is unwrapped, and we're bypassing PKCS11.
+ */
+ if (sid->u.ssl3.keys.msIsWrapped) {
+ PK11SlotInfo *slot;
+ PK11SymKey * wrapKey; /* wrapping key */
+ CK_FLAGS keyFlags = 0;
- /* copy the peer cert from the SID */
- if (sid->peerCert != NULL) {
- ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
- ssl3_CopyPeerCertsFromSID(ss, sid);
+ if (ss->opt.bypassPKCS11) {
+ /* we cannot restart a non-bypass session in a
+ ** bypass socket.
+ */
+ break;
+ }
+ /* unwrap master secret with PKCS11 */
+ slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
+ sid->u.ssl3.masterSlotID);
+ if (slot == NULL) {
+ break; /* not considered an error. */
+ }
+ if (!PK11_IsPresent(slot)) {
+ PK11_FreeSlot(slot);
+ break; /* not considered an error. */
+ }
+ wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
+ sid->u.ssl3.masterWrapMech,
+ sid->u.ssl3.masterWrapSeries,
+ ss->pkcs11PinArg);
+ PK11_FreeSlot(slot);
+ if (wrapKey == NULL) {
+ break; /* not considered an error. */
}
- /* NULL value for PMS signifies re-use of the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- if (rv != SECSuccess) {
- goto alert_loser;
+ if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
+ keyFlags = CKF_SIGN | CKF_VERIFY;
+ }
+
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ pwSpec->master_secret =
+ PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
+ NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
+ CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
+ errCode = PORT_GetError();
+ PK11_FreeSymKey(wrapKey);
+ if (pwSpec->master_secret == NULL) {
+ break; /* errorCode set just after call to UnwrapSymKey. */
+ }
+ } else if (ss->opt.bypassPKCS11) {
+ /* MS is not wrapped */
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
+ pwSpec->msItem.data = pwSpec->raw_master_secret;
+ pwSpec->msItem.len = wrappedMS.len;
+ } else {
+ /* We CAN restart a bypass session in a non-bypass socket. */
+ /* need to import the raw master secret to session object */
+ PK11SlotInfo *slot = PK11_GetInternalSlot();
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ pwSpec->master_secret =
+ PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
+ PK11_OriginUnwrap, CKA_ENCRYPT,
+ &wrappedMS, NULL);
+ PK11_FreeSlot(slot);
+ if (pwSpec->master_secret == NULL) {
+ break;
}
- return SECSuccess;
}
- }
+
+ /* Got a Match */
+ SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
+
+ /* If we sent a session ticket, then this is a stateless resume. */
+ if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
+ sid->u.ssl3.sessionTicket.ticket.data != NULL)
+ SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );
+
+ if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
+ ss->ssl3.hs.ws = wait_new_session_ticket;
+ else
+ ss->ssl3.hs.ws = wait_change_cipher;
+
+ ss->ssl3.hs.isResuming = PR_TRUE;
+
+ /* copy the peer cert from the SID */
+ if (sid->peerCert != NULL) {
+ ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
+ ssl3_CopyPeerCertsFromSID(ss, sid);
+ }
+
+
+ /* NULL value for PMS signifies re-use of the old MS */
+ rv = ssl3_InitPendingCipherSpec(ss, NULL);
+ if (rv != SECSuccess) {
+ goto alert_loser; /* err code was set */
+ }
+ return SECSuccess;
+ } while (0);
if (sid_match)
SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok );
@@ -6250,7 +6209,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* ticket extension, but sent an empty ticket.
*/
if (!ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) ||
- ss->xtnData.serverReceivedEmptySessionTicket) {
+ ss->xtnData.emptySessionTicket) {
if (sidBytes.len > 0 && !ss->opt.noCache) {
SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
@@ -7703,12 +7662,6 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
return SECFailure; /* malformed */
}
- if (ss->sec.ci.sid->peerCert == NULL) {
- ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
- ssl3_CopyPeerCertsToSID((ssl3CertNode *)ss->ssl3.peerCertChain,
- ss->sec.ci.sid);
- }
-
rv = ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &session_ticket);
if (rv != SECSuccess) {
(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
@@ -7900,7 +7853,7 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
ss->ssl3.peerCertChain = NULL;
}
-void
+static void
ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid)
{
PRArenaPool *arena;
@@ -8366,7 +8319,7 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
return rv;
}
-SECStatus
+static SECStatus
ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
PRBool isServer,
const SSL3Finished * hashes,
@@ -8414,7 +8367,7 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
/* called from ssl3_HandleServerHelloDone
*/
-SECStatus
+static SECStatus
ssl3_SendNextProto(sslSocket *ss)
{
SECStatus rv;
@@ -8450,7 +8403,7 @@ ssl3_SendNextProto(sslSocket *ss)
* ssl3_HandleClientHello
* ssl3_HandleFinished
*/
-SECStatus
+static SECStatus
ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
{
ssl3CipherSpec *cwSpec;
@@ -8503,13 +8456,10 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
if (rv != SECSuccess)
goto fail; /* err set by AppendHandshake. */
}
- if ((flags & ssl_SEND_FLAG_NO_FLUSH) == 0) {
- rv = ssl3_FlushHandshake(ss, flags);
- if (rv != SECSuccess) {
- goto fail; /* error code set by ssl3_FlushHandshake */
- }
+ rv = ssl3_FlushHandshake(ss, flags);
+ if (rv != SECSuccess) {
+ goto fail; /* error code set by ssl3_FlushHandshake */
}
-
return SECSuccess;
fail:
@@ -8626,16 +8576,6 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
return SECFailure;
}
- if (ss->ssl3.hs.snapStartType == snap_start_full ||
- ss->ssl3.hs.snapStartType == snap_start_resume) {
- /* Snap Start handshake was successful. Switch the cipher spec. */
- ssl_GetSpecWriteLock(ss);
- ssl3_DestroyCipherSpec(ss->ssl3.cwSpec, PR_TRUE/*freeSrvName*/);
- ss->ssl3.cwSpec = ss->ssl3.pwSpec;
- ss->ssl3.pwSpec = NULL;
- ssl_ReleaseSpecWriteLock(ss);
- }
-
isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0);
if (isTLS) {
TLSFinished tlsFinished;
@@ -8645,21 +8585,12 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
return SECFailure;
}
-
- if (ss->ssl3.hs.snapStartType == snap_start_resume) {
- /* In this case we have already advanced the Finished hash past the
- * server's verify_data because we needed to predict the server's
- * Finished message in order to compute our own (which includes
- * it). When we did this, we stored a copy in tFinished[1]. */
- tlsFinished = ss->ssl3.hs.finishedMsgs.tFinished[1];
- } else {
- rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
- hashes, &tlsFinished);
- if (!isServer)
- ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
- else
- ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
- }
+ rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
+ hashes, &tlsFinished);
+ if (!isServer)
+ ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
+ else
+ ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
ss->ssl3.hs.finishedBytes = sizeof tlsFinished;
if (rv != SECSuccess ||
0 != NSS_SecureMemcmp(&tlsFinished, b, length)) {
@@ -8690,9 +8621,8 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
ssl_GetXmitBufLock(ss); /*************************************/
- if (ss->ssl3.hs.snapStartType != snap_start_resume &&
- ((isServer && !ss->ssl3.hs.isResuming) ||
- (!isServer && ss->ssl3.hs.isResuming))) {
+ if ((isServer && !ss->ssl3.hs.isResuming) ||
+ (!isServer && ss->ssl3.hs.isResuming)) {
PRInt32 flags = 0;
/* Send a NewSessionTicket message if the client sent us
@@ -8808,10 +8738,7 @@ xmit_loser:
ss->ssl3.hs.ws = idle_handshake;
/* Do the handshake callback for sslv3 here, if we cannot false start. */
- if (ss->handshakeCallback != NULL &&
- (!ssl3_CanFalseStart(ss) ||
- ss->ssl3.hs.snapStartType == snap_start_full ||
- ss->ssl3.hs.snapStartType == snap_start_resume)) {
+ if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
}
@@ -8892,13 +8819,8 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
return rv;
}
}
- /* We should not include hello_request messages in the handshake hashes.
- * Likewise, for Finished messages from the server during a Snap Start
- * resume, we have already predicted and included the message in our
- * Finished hash. */
- if (ss->ssl3.hs.msg_type != hello_request &&
- !(ss->ssl3.hs.msg_type == finished &&
- ss->ssl3.hs.snapStartType == snap_start_resume)) {
+ /* We should not include hello_request messages in the handshake hashes */
+ if (ss->ssl3.hs.msg_type != hello_request) {
rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
if (rv != SECSuccess) return rv; /* err code already set. */
rv = ssl3_UpdateHandshakeHashes(ss, b, length);
@@ -9837,15 +9759,6 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ss->ssl3.clientCertChain = NULL;
}
- if (ss->ssl3.predictedCertChain != NULL)
- ssl3_CleanupPredictedPeerCertificates(ss);
-
- if (ss->ssl3.serverHelloPredictionData.data)
- SECITEM_FreeItem(&ss->ssl3.serverHelloPredictionData, PR_FALSE);
-
- if (ss->ssl3.snapStartApplicationData.data)
- SECITEM_FreeItem(&ss->ssl3.snapStartApplicationData, PR_FALSE);
-
/* clean up handshake */
if (ss->opt.bypassPKCS11) {
SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
@@ -9863,9 +9776,6 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ss->ssl3.hs.messages.len = 0;
ss->ssl3.hs.messages.space = 0;
}
- if (ss->ssl3.hs.origClientHello.data) {
- SECITEM_FreeItem(&ss->ssl3.hs.origClientHello, PR_FALSE);
- }
if (ss->ssl3.hs.pending_cert_msg.data) {
SECITEM_FreeItem(&ss->ssl3.hs.pending_cert_msg, PR_FALSE);
}
diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
index b93671e..94dab58 100644
--- a/net/third_party/nss/ssl/ssl3ext.c
+++ b/net/third_party/nss/ssl/ssl3ext.c
@@ -248,7 +248,6 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
- { ssl_snap_start_xtn, &ssl3_ClientHandleSnapStartXtn },
{ -1, NULL }
};
@@ -273,9 +272,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
#endif
{ ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
{ ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
- { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
- { ssl_snap_start_xtn, &ssl3_SendSnapStartXtn }
- /* NOTE: The Snap Start sender MUST be the last extension in the list. */
+ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
/* any extra entries will appear as { 0, NULL } */
};
@@ -303,7 +300,7 @@ ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
xtnData->numNegotiated, ex_type);
}
-PRBool
+static PRBool
ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
TLSExtensionData *xtnData = &ss->xtnData;
return arrayContainsExtension(xtnData->advertised,
@@ -520,8 +517,6 @@ ssl3_SendSessionTicketXtn(
rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
session_ticket->ticket.len, 2);
ss->xtnData.ticketTimestampVerified = PR_FALSE;
- if (!ss->sec.isServer)
- ss->xtnData.clientSentNonEmptySessionTicket = PR_TRUE;
} else {
rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
}
@@ -580,7 +575,7 @@ ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
SECStatus
ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
+ SECItem *data)
{
unsigned int i, j;
SECStatus rv;
@@ -1102,7 +1097,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
* instead of terminating the current connection.
*/
if (data->len == 0) {
- ss->xtnData.serverReceivedEmptySessionTicket = PR_TRUE;
+ ss->xtnData.emptySessionTicket = PR_TRUE;
} else {
int i;
SECItem extension_data;
diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
index 95beb57..2e1364e 100644
--- a/net/third_party/nss/ssl/sslimpl.h
+++ b/net/third_party/nss/ssl/sslimpl.h
@@ -287,7 +287,6 @@ struct sslSocketOpsStr {
/* Flags interpreted by ssl send functions. */
#define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000
#define ssl_SEND_FLAG_NO_BUFFER 0x20000000
-#define ssl_SEND_FLAG_NO_FLUSH 0x10000000
#define ssl_SEND_FLAG_MASK 0x7f000000
/*
@@ -349,8 +348,7 @@ typedef struct sslOptionsStr {
unsigned int enableRenegotiation : 2; /* 20-21 */
unsigned int requireSafeNegotiation : 1; /* 22 */
unsigned int enableFalseStart : 1; /* 23 */
- unsigned int enableSnapStart : 1; /* 24 */
- unsigned int enableOCSPStapling : 1; /* 25 */
+ unsigned int enableOCSPStapling : 1; /* 24 */
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
@@ -765,8 +763,7 @@ struct TLSExtensionDataStr {
/* SessionTicket Extension related data. */
PRBool ticketTimestampVerified;
- PRBool serverReceivedEmptySessionTicket;
- PRBool clientSentNonEmptySessionTicket;
+ PRBool emptySessionTicket;
/* SNI Extension related data
* Names data is not coppied from the input buffer. It can not be
@@ -776,14 +773,6 @@ struct TLSExtensionDataStr {
PRUint32 sniNameArrSize;
};
-typedef enum {
- snap_start_none = 0,
- snap_start_full,
- snap_start_recovery,
- snap_start_resume,
- snap_start_resume_recovery
-} TLSSnapStartType;
-
/*
** This is the "hs" member of the "ssl3" struct.
** This entire struct is protected by ssl3HandshakeLock
@@ -830,14 +819,6 @@ const ssl3CipherSuiteDef *suite_def;
SSL3Hashes sFinished[2];
SSL3Opaque data[72];
} finishedMsgs;
-
- TLSSnapStartType snapStartType;
- /* When we perform a Snap Start handshake, we hash our ClientHello as if
- * the Snap Start extension wasn't included. However, if the server rejects
- * our Snap Start attempt, then it will hash the whole ClientHello. Thus we
- * store the original ClientHello that we sent in case we need to reset our
- * Finished hash to cover it. */
- SECItem origClientHello;
#ifdef NSS_ENABLE_ECC
PRUint32 negotiatedECCurves; /* bit mask */
#endif /* NSS_ENABLE_ECC */
@@ -873,17 +854,6 @@ struct ssl3StateStr {
CERTCertificateList *clientCertChain; /* used by client */
PRBool sendEmptyCert; /* used by client */
- /* TLS Snap Start: */
- CERTCertificate ** predictedCertChain;
- /* An array terminated with a NULL. */
- SECItem serverHelloPredictionData;
- PRBool serverHelloPredictionDataValid;
- /* data needed to predict the ServerHello from
- * this server. */
- SECItem snapStartApplicationData;
- /* the application data to include in the Snap
- * Start extension. */
-
int policy;
/* This says what cipher suites we can do, and should
* be either SSL_ALLOWED or SSL_RESTRICTED
@@ -1323,13 +1293,10 @@ extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port,
const char *peerID, const char *urlSvrName);
extern void ssl_FreeSID(sslSessionID *sid);
-extern void ssl3_CopyPeerCertsFromSID(sslSocket *ss, sslSessionID *sid);
extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
int len, int flags);
-extern SECStatus ssl3_RestartHandshakeHashes(sslSocket *ss);
-
extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
@@ -1502,9 +1469,6 @@ ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits);
#endif /* NSS_ENABLE_ECC */
-extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket* ss, unsigned char *b,
- unsigned int l);
-
extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
@@ -1525,7 +1489,6 @@ extern void ssl3_InitSocketPolicy(sslSocket *ss);
extern SECStatus ssl3_ConstructV2CipherSpecsHack(sslSocket *ss,
unsigned char *cs, int *size);
-extern void ssl3_DestroyCipherSpec(ssl3CipherSpec* spec, PRBool freeSrvName);
extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
@@ -1575,31 +1538,6 @@ extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash,
extern SECStatus ssl3_CacheWrappedMasterSecret(sslSocket *ss,
sslSessionID *sid, ssl3CipherSpec *spec,
SSL3KEAType effectiveExchKeyType);
-extern void ssl3_CleanupPredictedPeerCertificates(sslSocket *ss);
-extern const ssl3CipherSuiteDef* ssl_LookupCipherSuiteDef(ssl3CipherSuite suite);
-extern SECStatus ssl3_SetupPendingCipherSpec(sslSocket *ss);
-extern SECStatus ssl3_SendClientKeyExchange(sslSocket *ss);
-extern SECStatus ssl3_SendNextProto(sslSocket *ss);
-extern SECStatus ssl3_SendFinished(sslSocket *ss, PRInt32 flags);
-extern SECStatus ssl3_CompressMACEncryptRecord
- (sslSocket * ss,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen);
-extern PRBool ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type);
-extern SECStatus ssl3_SetupMasterSecretFromSessionID(sslSocket* ss);
-extern SECStatus ssl3_ComputeHandshakeHashes(
- sslSocket * ss,
- ssl3CipherSpec *spec, /* uses ->master_secret */
- SSL3Hashes * hashes, /* output goes here. */
- PRUint32 sender);
-extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket* ss, unsigned char *b,
- unsigned int l);
-extern SECStatus ssl3_ComputeTLSFinished(
- ssl3CipherSpec *spec,
- PRBool isServer,
- const SSL3Finished * hashes,
- TLSFinished * tlsFinished);
/* Functions that handle ClientHello and ServerHello extensions. */
extern SECStatus ssl3_HandleServerNameXtn(sslSocket * ss,
@@ -1633,13 +1571,6 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append,
*/
extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
-extern PRInt32 ssl3_SendSnapStartXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-extern SECStatus ssl3_ClientHandleSnapStartXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data);
-
-extern SECStatus ssl3_ResetForSnapStartRecovery(sslSocket *ss,
- SSL3Opaque *b, PRUint32 length);
/* Assigns new cert, cert chain and keys to ss->serverCerts
* struct. If certChain is NULL, tries to find one. Aborts if
@@ -1763,12 +1694,6 @@ 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/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
index c5b63d1..1bb211e 100644
--- a/net/third_party/nss/ssl/sslsock.c
+++ b/net/third_party/nss/ssl/sslsock.c
@@ -743,10 +743,6 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
ss->opt.enableFalseStart = on;
break;
- case SSL_ENABLE_SNAP_START:
- ss->opt.enableSnapStart = on;
- break;
-
case SSL_ENABLE_OCSP_STAPLING:
ss->opt.enableOCSPStapling = on;
break;
@@ -815,7 +811,6 @@ 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_ENABLE_SNAP_START: on = ss->opt.enableSnapStart; break;
case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
default:
@@ -868,7 +863,6 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
on = ssl_defaults.requireSafeNegotiation;
break;
case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break;
- case SSL_ENABLE_SNAP_START: on = ssl_defaults.enableSnapStart; break;
case SSL_ENABLE_OCSP_STAPLING:
on = ssl_defaults.enableOCSPStapling;
break;
@@ -1019,10 +1013,6 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
ssl_defaults.enableFalseStart = on;
break;
- case SSL_ENABLE_SNAP_START:
- ssl_defaults.enableSnapStart = on;
- break;
-
case SSL_ENABLE_OCSP_STAPLING:
ssl_defaults.enableOCSPStapling = on;
break;
diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
index 3fa3f9b..917c093 100644
--- a/net/third_party/nss/ssl/sslt.h
+++ b/net/third_party/nss/ssl/sslt.h
@@ -205,23 +205,9 @@ typedef enum {
#endif
ssl_session_ticket_xtn = 35,
ssl_next_proto_neg_xtn = 13172,
- ssl_snap_start_xtn = 13174,
ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
} SSLExtensionType;
-#define SSL_MAX_EXTENSIONS 8
-
-typedef enum {
- /* No Snap Start handshake was attempted. */
- SSL_SNAP_START_NONE = 0,
- /* A Snap Start full handshake was completed. */
- SSL_SNAP_START_FULL = 1,
- /* A Snap Start full handshake was attempted, but failed. */
- SSL_SNAP_START_RECOVERY = 2,
- /* A Snap Start resume handshake was completed. */
- SSL_SNAP_START_RESUME = 3,
- /* A Snap Start resume handshake was attempted, but failed. */
- SSL_SNAP_START_RESUME_RECOVERY = 4
-} SSLSnapStartResult;
+#define SSL_MAX_EXTENSIONS 7
#endif /* __sslt_h_ */