summaryrefslogtreecommitdiffstats
path: root/net/third_party/nss/patches
diff options
context:
space:
mode:
Diffstat (limited to 'net/third_party/nss/patches')
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh36
-rw-r--r--net/third_party/nss/patches/cachecerts.patch50
-rw-r--r--net/third_party/nss/patches/channelid.patch263
-rw-r--r--net/third_party/nss/patches/checkuncache.patch164
-rw-r--r--net/third_party/nss/patches/clientauth.patch190
-rw-r--r--net/third_party/nss/patches/dhvalues.patch53
-rw-r--r--net/third_party/nss/patches/didhandshakeresume.patch20
-rw-r--r--net/third_party/nss/patches/dtls.patch3322
-rw-r--r--net/third_party/nss/patches/dtlssrtp.patch468
-rw-r--r--net/third_party/nss/patches/ecpointform.patch19
-rw-r--r--net/third_party/nss/patches/falsestartnpn.patch20
-rw-r--r--net/third_party/nss/patches/getchannelinfo.patch27
-rw-r--r--net/third_party/nss/patches/getrequestedclientcerttypes.patch68
-rw-r--r--net/third_party/nss/patches/keylog.patch189
-rw-r--r--net/third_party/nss/patches/negotiatedextension.patch20
-rw-r--r--net/third_party/nss/patches/ocspstapling.patch190
-rw-r--r--net/third_party/nss/patches/peercertchain.patch78
-rw-r--r--net/third_party/nss/patches/recordlayerversion.patch196
-rw-r--r--net/third_party/nss/patches/renegoclientversion.patch114
-rw-r--r--net/third_party/nss/patches/renegoscsv.patch8
-rw-r--r--net/third_party/nss/patches/restartclientauth.patch55
-rw-r--r--net/third_party/nss/patches/secretexporterlocks.patch44
-rw-r--r--net/third_party/nss/patches/sslkeylogerror.patch15
-rw-r--r--net/third_party/nss/patches/sslprotocolvariant.patch52
-rw-r--r--net/third_party/nss/patches/tlsunique.patch90
-rw-r--r--net/third_party/nss/patches/versionskew.patch36
26 files changed, 584 insertions, 5203 deletions
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index 9d49844..1992ad0 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -10,48 +10,34 @@
# chromium source tree.
patches_dir=/Users/wtc/chrome1/src/net/third_party/nss/patches
-patch -p6 < $patches_dir/versionskew.patch
+patch -p5 < $patches_dir/versionskew.patch
-patch -p6 < $patches_dir/renegoscsv.patch
+patch -p5 < $patches_dir/renegoscsv.patch
-patch -p6 < $patches_dir/cachecerts.patch
+patch -p5 < $patches_dir/cachecerts.patch
patch -p5 < $patches_dir/peercertchain.patch
-patch -p6 < $patches_dir/ocspstapling.patch
+patch -p5 < $patches_dir/ocspstapling.patch
-patch -p6 < $patches_dir/clientauth.patch
+patch -p5 < $patches_dir/clientauth.patch
-patch -p6 < $patches_dir/didhandshakeresume.patch
+patch -p5 < $patches_dir/didhandshakeresume.patch
-patch -p6 < $patches_dir/negotiatedextension.patch
+patch -p5 < $patches_dir/negotiatedextension.patch
-patch -p6 < $patches_dir/getrequestedclientcerttypes.patch
+patch -p5 < $patches_dir/getrequestedclientcerttypes.patch
-patch -p6 < $patches_dir/restartclientauth.patch
-
-patch -p4 < $patches_dir/dtls.patch
+patch -p5 < $patches_dir/restartclientauth.patch
patch -p5 < $patches_dir/falsestartnpn.patch
-patch -p5 < $patches_dir/dhvalues.patch
-
patch -p5 < $patches_dir/channelid.patch
-patch -p4 < $patches_dir/dtlssrtp.patch
-
-patch -p5 < $patches_dir/keylog.patch
-
-patch -p4 < $patches_dir/getchannelinfo.patch
-
patch -p5 < $patches_dir/tlsunique.patch
patch -p5 < $patches_dir/sslkeylogerror.patch
-patch -p5 < $patches_dir/recordlayerversion.patch
-
-patch -p5 < $patches_dir/sslprotocolvariant.patch
-
-patch -p5 < $patches_dir/renegoclientversion.patch
+patch -p5 < $patches_dir/ecpointform.patch
-patch -p4 < $patches_dir/checkuncache.patch
+patch -p5 < $patches_dir/secretexporterlocks.patch
diff --git a/net/third_party/nss/patches/cachecerts.patch b/net/third_party/nss/patches/cachecerts.patch
index f7ce5fb..8c3e60b 100644
--- a/net/third_party/nss/patches/cachecerts.patch
+++ b/net/third_party/nss/patches/cachecerts.patch
@@ -1,19 +1,7 @@
-From 4c2b4b3992f81f062248f03296f7eb59b5fc0868 Mon Sep 17 00:00:00 2001
-From: Adam Langley <agl@chromium.org>
-Date: Mon, 3 Oct 2011 12:20:29 -0400
-Subject: [PATCH] cachecerts.patch
-
----
- mozilla/security/nss/lib/ssl/ssl3con.c | 54 +++++++++++++++++++++++++++++-
- mozilla/security/nss/lib/ssl/sslimpl.h | 3 ++
- mozilla/security/nss/lib/ssl/sslnonce.c | 4 ++
- 3 files changed, 59 insertions(+), 2 deletions(-)
-
-diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
-index 455a532..9830e65 100644
---- a/mozilla/security/nss/lib/ssl/ssl3con.c
-+++ b/mozilla/security/nss/lib/ssl/ssl3con.c
-@@ -72,6 +72,7 @@
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:19:29.665155332 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:20:08.835732728 -0800
+@@ -42,6 +42,7 @@
#endif
static void ssl3_CleanupPeerCerts(sslSocket *ss);
@@ -21,7 +9,7 @@ index 455a532..9830e65 100644
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo * serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
-@@ -5141,6 +5142,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -5575,6 +5576,7 @@ ssl3_HandleServerHello(sslSocket *ss, SS
/* copy the peer cert from the SID */
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
@@ -29,7 +17,7 @@ index 455a532..9830e65 100644
}
-@@ -6393,6 +6395,7 @@ compression_found:
+@@ -6916,6 +6918,7 @@ compression_found:
ss->sec.ci.sid = sid;
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
@@ -37,7 +25,7 @@ index 455a532..9830e65 100644
}
/*
-@@ -7761,6 +7764,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
+@@ -8323,6 +8326,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
ss->ssl3.peerCertChain = NULL;
}
@@ -82,19 +70,18 @@ index 455a532..9830e65 100644
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 Certificate message.
* Caller must hold Handshake and RecvBuf locks.
-@@ -7947,6 +7994,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -8510,6 +8551,7 @@ ssl3_HandleCertificate(sslSocket *ss, SS
}
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
+ ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);
if (!ss->sec.isServer) {
- /* set the server authentication and key exchange types and sizes
-diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
-index d1c1181..48d6d83 100644
---- a/mozilla/security/nss/lib/ssl/sslimpl.h
-+++ b/mozilla/security/nss/lib/ssl/sslimpl.h
-@@ -569,10 +569,13 @@ typedef enum { never_cached,
+ CERTCertificate *cert = ss->sec.peerCert;
+diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-09-27 18:46:45.000000000 -0700
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:20:08.835732728 -0800
+@@ -571,10 +571,13 @@ typedef enum { never_cached,
invalid_cache /* no longer in any cache. */
} Cached;
@@ -108,11 +95,10 @@ index d1c1181..48d6d83 100644
const char * peerID; /* client only */
const char * urlSvrName; /* client only */
CERTCertificate * localCert;
-diff --git a/mozilla/security/nss/lib/ssl/sslnonce.c b/mozilla/security/nss/lib/ssl/sslnonce.c
-index 63dc5a2..64adc1f 100644
---- a/mozilla/security/nss/lib/ssl/sslnonce.c
-+++ b/mozilla/security/nss/lib/ssl/sslnonce.c
-@@ -197,6 +197,7 @@ lock_cache(void)
+diff -pu -r a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c
+--- a/net/third_party/nss/ssl/sslnonce.c 2012-04-25 07:50:12.000000000 -0700
++++ b/net/third_party/nss/ssl/sslnonce.c 2012-11-09 15:20:08.835732728 -0800
+@@ -165,6 +165,7 @@ lock_cache(void)
static void
ssl_DestroySID(sslSessionID *sid)
{
@@ -120,7 +106,7 @@ index 63dc5a2..64adc1f 100644
SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
PORT_Assert((sid->references == 0));
-@@ -216,6 +217,9 @@ ssl_DestroySID(sslSessionID *sid)
+@@ -184,6 +185,9 @@ ssl_DestroySID(sslSessionID *sid)
if ( sid->peerCert ) {
CERT_DestroyCertificate(sid->peerCert);
}
diff --git a/net/third_party/nss/patches/channelid.patch b/net/third_party/nss/patches/channelid.patch
index bdac018..ea7fd29 100644
--- a/net/third_party/nss/patches/channelid.patch
+++ b/net/third_party/nss/patches/channelid.patch
@@ -1,64 +1,7 @@
-diff --git a/net/third_party/nss/ssl/SSLerrs.h b/net/third_party/nss/ssl/SSLerrs.h
-index e3f9a1c..2d92514 100644
---- a/net/third_party/nss/ssl/SSLerrs.h
-+++ b/net/third_party/nss/ssl/SSLerrs.h
-@@ -429,3 +429,12 @@ ER3(SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 122),
-
- ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 123),
- "SSL received an unexpected Hello Verify Request handshake message.")
-+
-+ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 124),
-+"SSL received a malformed TLS Channel ID extension.")
-+
-+ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 125),
-+"The application provided an invalid TLS Channel ID key.")
-+
-+ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 126),
-+"The application could not get a TLS Channel ID.")
-diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
-index 1368e2f..9b3a199 100644
---- a/net/third_party/nss/ssl/ssl.h
-+++ b/net/third_party/nss/ssl/ssl.h
-@@ -945,6 +945,34 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
- SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd,
- PRBool *last_handshake_resumed);
-
-+/* See SSL_SetClientChannelIDCallback for usage. If the callback returns
-+ * SECWouldBlock then SSL_RestartHandshakeAfterChannelIDReq should be called in
-+ * the future to restart the handshake. On SECSuccess, the callback must have
-+ * written a P-256, EC key pair to |*out_public_key| and |*out_private_key|. */
-+typedef SECStatus (PR_CALLBACK *SSLClientChannelIDCallback)(
-+ void *arg,
-+ PRFileDesc *fd,
-+ SECKEYPublicKey **out_public_key,
-+ SECKEYPrivateKey **out_private_key);
-+
-+/* SSL_RestartHandshakeAfterChannelIDReq attempts to restart the handshake
-+ * after a ChannelID callback returned SECWouldBlock.
-+ *
-+ * This function takes ownership of |channelIDPub| and |channelID|. */
-+SSL_IMPORT SECStatus SSL_RestartHandshakeAfterChannelIDReq(
-+ PRFileDesc *fd,
-+ SECKEYPublicKey *channelIDPub,
-+ SECKEYPrivateKey *channelID);
-+
-+/* SSL_SetClientChannelIDCallback sets a callback function that will be called
-+ * once the server's ServerHello has been processed. This is only applicable to
-+ * a client socket and setting this callback causes the TLS Channel ID
-+ * extension to be advertised. */
-+SSL_IMPORT SECStatus SSL_SetClientChannelIDCallback(
-+ PRFileDesc *fd,
-+ SSLClientChannelIDCallback callback,
-+ void *arg);
-+
- /*
- ** How long should we wait before retransmitting the next flight of
- ** the DTLS handshake? Returns SECFailure if not DTLS or not in a
-diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
-index db9fad3..cb2906f 100644
---- a/net/third_party/nss/ssl/ssl3con.c
-+++ b/net/third_party/nss/ssl/ssl3con.c
-@@ -86,6 +86,7 @@ static SECStatus ssl3_SendCertificate( sslSocket *ss);
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:57:12.838336618 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 16:11:46.721027895 -0800
+@@ -53,6 +53,7 @@ static SECStatus ssl3_SendCertificate(
static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
static SECStatus ssl3_SendNextProto( sslSocket *ss);
@@ -66,7 +9,7 @@ index db9fad3..cb2906f 100644
static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
static SECStatus ssl3_SendServerHello( sslSocket *ss);
static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
-@@ -5200,6 +5201,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -5330,6 +5331,15 @@ ssl3_HandleServerHello(sslSocket *ss, SS
}
#endif /* NSS_PLATFORM_CLIENT_AUTH */
@@ -82,13 +25,7 @@ index db9fad3..cb2906f 100644
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (temp < 0) {
goto loser; /* alert has been sent */
-@@ -5452,13 +5462,12 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- ssl3_CopyPeerCertsFromSID(ss, sid);
- }
-
--
- /* NULL value for PMS signifies re-use of the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
+@@ -5603,7 +5613,7 @@ ssl3_HandleServerHello(sslSocket *ss, SS
if (rv != SECSuccess) {
goto alert_loser; /* err code was set */
}
@@ -97,7 +34,7 @@ index db9fad3..cb2906f 100644
} while (0);
if (sid_match)
-@@ -5483,6 +5492,27 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -5629,6 +5639,27 @@ ssl3_HandleServerHello(sslSocket *ss, SS
ss->ssl3.hs.isResuming = PR_FALSE;
ss->ssl3.hs.ws = wait_server_cert;
@@ -125,7 +62,7 @@ index db9fad3..cb2906f 100644
return SECSuccess;
alert_loser:
-@@ -6239,6 +6269,10 @@ ssl3_SendClientSecondRound(sslSocket *ss)
+@@ -6385,6 +6416,10 @@ ssl3_SendClientSecondRound(sslSocket *ss
goto loser; /* err code was set. */
}
}
@@ -136,8 +73,8 @@ index db9fad3..cb2906f 100644
rv = ssl3_SendFinished(ss, 0);
if (rv != SECSuccess) {
-@@ -8855,6 +8889,164 @@ ssl3_SendNextProto(sslSocket *ss)
- return rv;
+@@ -9102,6 +9137,164 @@ ssl3_RecordKeyLog(sslSocket *ss)
+ return;
}
+/* called from ssl3_SendClientSecondRound
@@ -301,7 +238,7 @@ index db9fad3..cb2906f 100644
/* called from ssl3_HandleServerHelloDone
* ssl3_HandleClientHello
* ssl3_HandleFinished
-@@ -9105,11 +9297,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+@@ -9355,11 +9548,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3O
flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
}
@@ -322,7 +259,7 @@ index db9fad3..cb2906f 100644
}
if (IS_DTLS(ss)) {
-@@ -10376,6 +10573,11 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -10623,6 +10821,11 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ssl_FreePlatformKey(ss->ssl3.platformClientKey);
#endif /* NSS_PLATFORM_CLIENT_AUTH */
@@ -334,42 +271,37 @@ index db9fad3..cb2906f 100644
if (ss->ssl3.peerCertArena != NULL)
ssl3_CleanupPeerCerts(ss);
-diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
-index b9fd6e7..029487e 100644
---- a/net/third_party/nss/ssl/ssl3ext.c
-+++ b/net/third_party/nss/ssl/ssl3ext.c
-@@ -80,10 +80,14 @@ static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
- static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
+diff -pu -r a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
+--- a/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 15:57:12.838336618 -0800
++++ b/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 16:04:14.414475097 -0800
+@@ -61,6 +61,10 @@ static PRInt32 ssl3_SendUseSRTPXtn(sslSo
+ PRUint32 maxBytes);
+ static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
+ SECItem *data);
+static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss,
-+ PRUint16 ex_type, SECItem *data);
- static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
- static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
++ PRUint16 ex_type, SECItem *data);
+static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
-+ PRUint32 maxBytes);
++ PRUint32 maxBytes);
/*
* Write bytes. Using this function means the SECItem structure
-@@ -253,6 +257,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
- { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
+@@ -234,6 +238,7 @@ static const ssl3HelloExtensionHandler s
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
-+ { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
+ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
++ { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
{ -1, NULL }
};
-@@ -278,6 +283,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
- #endif
+@@ -260,6 +265,7 @@ ssl3HelloExtensionSender clientHelloSend
{ ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
{ ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
+ { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
+ { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
/* any extra entries will appear as { 0, NULL } */
};
-@@ -668,6 +674,52 @@ loser:
+@@ -650,6 +656,52 @@ loser:
return -1;
}
@@ -422,11 +354,10 @@ index b9fd6e7..029487e 100644
SECStatus
ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data)
-diff --git a/net/third_party/nss/ssl/ssl3prot.h b/net/third_party/nss/ssl/ssl3prot.h
-index 550c341..11f9624 100644
---- a/net/third_party/nss/ssl/ssl3prot.h
-+++ b/net/third_party/nss/ssl/ssl3prot.h
-@@ -163,7 +163,8 @@ typedef enum {
+diff -pu -r a/net/third_party/nss/ssl/ssl3prot.h b/net/third_party/nss/ssl/ssl3prot.h
+--- a/net/third_party/nss/ssl/ssl3prot.h 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/ssl3prot.h 2012-11-09 15:58:06.979126989 -0800
+@@ -130,7 +130,8 @@ typedef enum {
client_key_exchange = 16,
finished = 20,
certificate_status = 22,
@@ -436,11 +367,10 @@ index 550c341..11f9624 100644
} SSL3HandshakeType;
typedef struct {
-diff --git a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth.c
-index 8ccd1a4..e8b4acb 100644
---- a/net/third_party/nss/ssl/sslauth.c
-+++ b/net/third_party/nss/ssl/sslauth.c
-@@ -251,6 +251,24 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
+diff -pu -r a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth.c
+--- a/net/third_party/nss/ssl/sslauth.c 2012-11-09 15:39:36.892892416 -0800
++++ b/net/third_party/nss/ssl/sslauth.c 2012-11-09 15:58:06.979126989 -0800
+@@ -219,6 +219,24 @@ SSL_GetClientAuthDataHook(PRFileDesc *s,
return SECSuccess;
}
@@ -465,26 +395,78 @@ index 8ccd1a4..e8b4acb 100644
#ifdef NSS_PLATFORM_CLIENT_AUTH
/* NEED LOCKS IN HERE. */
SECStatus
-diff --git a/net/third_party/nss/ssl/sslerr.h b/net/third_party/nss/ssl/sslerr.h
-index 9d3bebc..53c897c 100644
---- a/net/third_party/nss/ssl/sslerr.h
-+++ b/net/third_party/nss/ssl/sslerr.h
-@@ -218,6 +218,10 @@ SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 121),
- SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
- SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
+diff -pu -r a/net/third_party/nss/ssl/sslerr.h b/net/third_party/nss/ssl/sslerr.h
+--- a/net/third_party/nss/ssl/sslerr.h 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/sslerr.h 2012-11-09 16:00:57.921621448 -0800
+@@ -190,6 +190,10 @@ SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERS
-+SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 124),
-+SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 125),
-+SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 126),
+ SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 125),
+
++SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 126),
++SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 127),
++SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 128),
+
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */
-diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
-index 8ab865a..d7335ae 100644
---- a/net/third_party/nss/ssl/sslimpl.h
-+++ b/net/third_party/nss/ssl/sslimpl.h
-@@ -930,6 +930,9 @@ struct ssl3StateStr {
+diff -pu -r a/net/third_party/nss/ssl/SSLerrs.h b/net/third_party/nss/ssl/SSLerrs.h
+--- a/net/third_party/nss/ssl/SSLerrs.h 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/SSLerrs.h 2012-11-09 16:00:11.540944794 -0800
+@@ -403,3 +403,12 @@ ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_
+
+ ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 125),
+ "SSL received an unexpected Certificate Status handshake message.")
++
++ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 126),
++"SSL received a malformed TLS Channel ID extension.")
++
++ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 127),
++"The application provided an invalid TLS Channel ID key.")
++
++ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 128),
++"The application could not get a TLS Channel ID.")
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 15:53:13.884846338 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:58:06.969126842 -0800
+@@ -935,6 +935,34 @@ SSL_IMPORT SECStatus SSL_HandshakeNegoti
+ SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd,
+ PRBool *last_handshake_resumed);
+
++/* See SSL_SetClientChannelIDCallback for usage. If the callback returns
++ * SECWouldBlock then SSL_RestartHandshakeAfterChannelIDReq should be called in
++ * the future to restart the handshake. On SECSuccess, the callback must have
++ * written a P-256, EC key pair to |*out_public_key| and |*out_private_key|. */
++typedef SECStatus (PR_CALLBACK *SSLClientChannelIDCallback)(
++ void *arg,
++ PRFileDesc *fd,
++ SECKEYPublicKey **out_public_key,
++ SECKEYPrivateKey **out_private_key);
++
++/* SSL_RestartHandshakeAfterChannelIDReq attempts to restart the handshake
++ * after a ChannelID callback returned SECWouldBlock.
++ *
++ * This function takes ownership of |channelIDPub| and |channelID|. */
++SSL_IMPORT SECStatus SSL_RestartHandshakeAfterChannelIDReq(
++ PRFileDesc *fd,
++ SECKEYPublicKey *channelIDPub,
++ SECKEYPrivateKey *channelID);
++
++/* SSL_SetClientChannelIDCallback sets a callback function that will be called
++ * once the server's ServerHello has been processed. This is only applicable to
++ * a client socket and setting this callback causes the TLS Channel ID
++ * extension to be advertised. */
++SSL_IMPORT SECStatus SSL_SetClientChannelIDCallback(
++ PRFileDesc *fd,
++ SSLClientChannelIDCallback callback,
++ void *arg);
++
+ /*
+ ** How long should we wait before retransmitting the next flight of
+ ** the DTLS handshake? Returns SECFailure if not DTLS or not in a
+diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:53:13.884846338 -0800
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:58:06.979126989 -0800
+@@ -894,6 +894,9 @@ struct ssl3StateStr {
CERTCertificateList *clientCertChain; /* used by client */
PRBool sendEmptyCert; /* used by client */
@@ -494,7 +476,7 @@ index 8ab865a..d7335ae 100644
int policy;
/* This says what cipher suites we can do, and should
* be either SSL_ALLOWED or SSL_RESTRICTED
-@@ -1198,6 +1201,8 @@ const unsigned char * preferredCipher;
+@@ -1165,6 +1168,8 @@ const unsigned char * preferredCipher;
void *pkcs11PinArg;
SSLNextProtoCallback nextProtoCallback;
void *nextProtoArg;
@@ -503,7 +485,7 @@ index 8ab865a..d7335ae 100644
PRIntervalTime rTimeout; /* timeout for NSPR I/O */
PRIntervalTime wTimeout; /* timeout for NSPR I/O */
-@@ -1529,6 +1534,11 @@ extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
+@@ -1495,6 +1500,11 @@ extern SECStatus ssl3_RestartHandshakeAf
SECKEYPrivateKey * key,
CERTCertificateList *certChain);
@@ -515,11 +497,10 @@ index 8ab865a..d7335ae 100644
extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
/*
-diff --git a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c
-index e4804d0..526d654 100644
---- a/net/third_party/nss/ssl/sslsecur.c
-+++ b/net/third_party/nss/ssl/sslsecur.c
-@@ -1535,6 +1535,42 @@ SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd,
+diff -pu -r a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c
+--- a/net/third_party/nss/ssl/sslsecur.c 2012-11-09 15:53:13.884846338 -0800
++++ b/net/third_party/nss/ssl/sslsecur.c 2012-11-09 15:58:06.979126989 -0800
+@@ -1503,6 +1503,42 @@ SSL_RestartHandshakeAfterCertReq(PRFileD
return ret;
}
@@ -562,11 +543,10 @@ index e4804d0..526d654 100644
/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
* this implementation exists to maintain link-time compatibility.
*/
-diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
-index ebc245a..9498828 100644
---- a/net/third_party/nss/ssl/sslsock.c
-+++ b/net/third_party/nss/ssl/sslsock.c
-@@ -374,6 +374,8 @@ ssl_DupSocket(sslSocket *os)
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:48:41.260860199 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:58:06.979126989 -0800
+@@ -346,6 +346,8 @@ ssl_DupSocket(sslSocket *os)
ss->handshakeCallback = os->handshakeCallback;
ss->handshakeCallbackData = os->handshakeCallbackData;
ss->pkcs11PinArg = os->pkcs11PinArg;
@@ -575,7 +555,7 @@ index ebc245a..9498828 100644
/* Create security data */
rv = ssl_CopySecurityInfo(ss, os);
-@@ -1688,6 +1690,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
+@@ -1736,6 +1738,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile
ss->handshakeCallbackData = sm->handshakeCallbackData;
if (sm->pkcs11PinArg)
ss->pkcs11PinArg = sm->pkcs11PinArg;
@@ -586,7 +566,7 @@ index ebc245a..9498828 100644
return fd;
loser:
return NULL;
-@@ -2938,6 +2944,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
+@@ -2988,6 +2994,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
ss->handleBadCert = NULL;
ss->badCertArg = NULL;
ss->pkcs11PinArg = NULL;
@@ -595,19 +575,18 @@ index ebc245a..9498828 100644
ssl_ChooseOps(ss);
ssl2_InitSocketPolicy(ss);
-diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
-index 0636570..978b1cb 100644
---- a/net/third_party/nss/ssl/sslt.h
-+++ b/net/third_party/nss/ssl/sslt.h
-@@ -215,9 +215,10 @@ typedef enum {
- #endif
+diff -pu -r a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
+--- a/net/third_party/nss/ssl/sslt.h 2012-11-09 15:34:12.268133912 -0800
++++ b/net/third_party/nss/ssl/sslt.h 2012-11-09 15:58:55.569836197 -0800
+@@ -183,9 +183,10 @@ typedef enum {
+ ssl_use_srtp_xtn = 14,
ssl_session_ticket_xtn = 35,
ssl_next_proto_nego_xtn = 13172,
+ ssl_channel_id_xtn = 30031,
ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
} SSLExtensionType;
--#define SSL_MAX_EXTENSIONS 7
-+#define SSL_MAX_EXTENSIONS 8
+-#define SSL_MAX_EXTENSIONS 8
++#define SSL_MAX_EXTENSIONS 9
#endif /* __sslt_h_ */
diff --git a/net/third_party/nss/patches/checkuncache.patch b/net/third_party/nss/patches/checkuncache.patch
deleted file mode 100644
index eb928bb..0000000
--- a/net/third_party/nss/patches/checkuncache.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-Index: net/third_party/nss/ssl/sslcon.c
-===================================================================
---- net/third_party/nss/ssl/sslcon.c (revision 166543)
-+++ net/third_party/nss/ssl/sslcon.c (working copy)
-@@ -658,7 +658,8 @@
-
- if (sent < 0) {
- /* If send failed, it is now a bogus session-id */
-- (*ss->sec.uncache)(sid);
-+ if (ss->sec.uncache)
-+ (*ss->sec.uncache)(sid);
- rv = (SECStatus)sent;
- } else if (!ss->opt.noCache) {
- /* Put the sid in session-id cache, (may already be there) */
-@@ -2891,7 +2892,8 @@
- /* Forget our session-id - server didn't like it */
- SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
- SSL_GETPID(), ss->fd));
-- (*ss->sec.uncache)(sid);
-+ if (ss->sec.uncache)
-+ (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
- ss->sec.ci.sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
- if (!sid) {
-@@ -3065,7 +3067,8 @@
-
- /* if we're not doing this SID's protocol any more, drop it. */
- if (!sidVersionEnabled) {
-- ss->sec.uncache(sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- break;
-@@ -3077,7 +3080,8 @@
- break;
- }
- if (i >= ss->sizeCipherSpecs) {
-- ss->sec.uncache(sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- break;
-Index: net/third_party/nss/ssl/ssl3ext.c
-===================================================================
---- net/third_party/nss/ssl/ssl3ext.c (revision 166543)
-+++ net/third_party/nss/ssl/ssl3ext.c (working copy)
-@@ -1204,7 +1204,8 @@
- * renegotiation.)
- */
- if (ss->sec.ci.sid != NULL) {
-- ss->sec.uncache(ss->sec.ci.sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(ss->sec.ci.sid);
- ssl_FreeSID(ss->sec.ci.sid);
- ss->sec.ci.sid = NULL;
- }
-Index: net/third_party/nss/ssl/ssl3con.c
-===================================================================
---- net/third_party/nss/ssl/ssl3con.c (revision 166543)
-+++ net/third_party/nss/ssl/ssl3con.c (working copy)
-@@ -2666,7 +2666,8 @@
- (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
- PRFileDesc * lower;
-
-- ss->sec.uncache(ss->sec.ci.sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(ss->sec.ci.sid);
- SSL3_SendAlert(ss, alert_fatal, bad_certificate);
-
- lower = ss->fd->lower;
-@@ -2721,7 +2722,7 @@
-
- ssl_GetSSL3HandshakeLock(ss);
- if (level == alert_fatal) {
-- if (ss->sec.ci.sid) {
-+ if (!ss->opt.noCache && ss->sec.ci.sid && ss->sec.uncache) {
- ss->sec.uncache(ss->sec.ci.sid);
- }
- }
-@@ -2891,8 +2892,10 @@
- default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
- }
- if (level == alert_fatal) {
-- if (!ss->opt.noCache)
-- ss->sec.uncache(ss->sec.ci.sid);
-+ if (!ss->opt.noCache) {
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(ss->sec.ci.sid);
-+ }
- if ((ss->ssl3.hs.ws == wait_server_hello) &&
- (desc == handshake_failure)) {
- /* XXX This is a hack. We're assuming that any handshake failure
-@@ -4152,7 +4155,8 @@
-
- if (!sidOK) {
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
-- (*ss->sec.uncache)(sid);
-+ if (ss->sec.uncache)
-+ (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
-@@ -4457,7 +4461,8 @@
- }
-
- if (sid) {
-- ss->sec.uncache(sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- ss->sec.ci.sid = NULL;
- }
-@@ -5588,7 +5593,8 @@
-
- /* throw the old one away */
- sid->u.ssl3.keys.resumable = PR_FALSE;
-- (*ss->sec.uncache)(sid);
-+ if (ss->sec.uncache)
-+ (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
-
- /* get a new sid */
-@@ -6851,7 +6857,8 @@
- && !ss->firstHsDone))) {
-
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
-- ss->sec.uncache(sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
-@@ -6998,7 +7005,8 @@
- }
-
- if (ss->sec.ci.sid) {
-- ss->sec.uncache(ss->sec.ci.sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(ss->sec.ci.sid);
- PORT_Assert(ss->sec.ci.sid != sid); /* should be impossible, but ... */
- if (ss->sec.ci.sid != sid) {
- ssl_FreeSID(ss->sec.ci.sid);
-@@ -7167,7 +7175,8 @@
-
- if (sid) { /* we had a sid, but it's no longer valid, free it */
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
-- ss->sec.uncache(sid);
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
-@@ -10782,7 +10791,8 @@
- return SECFailure;
- }
- if (sid && flushCache) {
-- ss->sec.uncache(sid); /* remove it from whichever cache it's in. */
-+ if (ss->sec.uncache)
-+ ss->sec.uncache(sid); /* remove it from whichever cache it's in. */
- ssl_FreeSID(sid); /* dec ref count and free if zero. */
- ss->sec.ci.sid = NULL;
- }
diff --git a/net/third_party/nss/patches/clientauth.patch b/net/third_party/nss/patches/clientauth.patch
index 7bf8369..39687d6 100644
--- a/net/third_party/nss/patches/clientauth.patch
+++ b/net/third_party/nss/patches/clientauth.patch
@@ -1,56 +1,7 @@
-diff -upN a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h
---- a/src/net/third_party/nss/ssl/ssl.h 2012-02-28 19:26:04.047351199 -0800
-+++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-28 20:04:24.039351965 -0800
-@@ -421,6 +421,45 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl
- SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
- SSLGetClientAuthData f, void *a);
-
-+/*
-+ * Prototype for SSL callback to get client auth data from the application,
-+ * optionally using the underlying platform's cryptographic primitives.
-+ * To use the platform cryptographic primitives, caNames and pRetCerts
-+ * should be set. To use NSS, pRetNSSCert and pRetNSSKey should be set.
-+ * Returning SECFailure will cause the socket to send no client certificate.
-+ * arg - application passed argument
-+ * caNames - pointer to distinguished names of CAs that the server likes
-+ * pRetCerts - pointer to pointer to list of certs, with the first being
-+ * the client cert, and any following being used for chain
-+ * building
-+ * pRetKey - pointer to native key pointer, for return of key
-+ * - Windows: A pointer to a PCERT_KEY_CONTEXT that was allocated
-+ * via PORT_Alloc(). Ownership of the PCERT_KEY_CONTEXT
-+ * is transferred to NSS, which will free via
-+ * PORT_Free().
-+ * - Mac OS X: A pointer to a SecKeyRef. Ownership is
-+ * transferred to NSS, which will free via CFRelease().
-+ * pRetNSSCert - pointer to pointer to NSS cert, for return of cert.
-+ * pRetNSSKey - pointer to NSS key pointer, for return of key.
-+ */
-+typedef SECStatus (PR_CALLBACK *SSLGetPlatformClientAuthData)(void *arg,
-+ PRFileDesc *fd,
-+ CERTDistNames *caNames,
-+ CERTCertList **pRetCerts,/*return */
-+ void **pRetKey,/* return */
-+ CERTCertificate **pRetNSSCert,/*return */
-+ SECKEYPrivateKey **pRetNSSKey);/* return */
-+
-+/*
-+ * Set the client side callback for SSL to retrieve user's private key
-+ * and certificate.
-+ * fd - the file descriptor for the connection in question
-+ * f - the application's callback that delivers the key and cert
-+ * a - application specific data
-+ */
-+SSL_IMPORT SECStatus
-+SSL_GetPlatformClientAuthDataHook(PRFileDesc *fd,
-+ SSLGetPlatformClientAuthData f, void *a);
-
- /*
- ** SNI extension processing callback function.
-diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c
---- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 19:26:04.047351199 -0800
-+++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-28 20:07:04.101579541 -0800
-@@ -2015,6 +2015,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID
+diff -puN -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:35:08.488958561 -0800
+@@ -2033,6 +2033,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID
PRBool isPresent = PR_TRUE;
/* we only care if we are doing client auth */
@@ -60,7 +11,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
if (!sid || !sid->u.ssl3.clAuthValid) {
return PR_TRUE;
}
-@@ -4893,24 +4896,33 @@ ssl3_SendCertificateVerify(sslSocket *ss
+@@ -5226,24 +5229,33 @@ ssl3_SendCertificateVerify(sslSocket *ss
}
isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
@@ -110,7 +61,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
if (rv != SECSuccess) {
goto done; /* err code was set by ssl3_SignHashes */
}
-@@ -4978,6 +4990,12 @@ ssl3_HandleServerHello(sslSocket *ss, SS
+@@ -5311,6 +5323,12 @@ ssl3_HandleServerHello(sslSocket *ss, SS
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
ss->ssl3.clientPrivateKey = NULL;
}
@@ -123,7 +74,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (temp < 0) {
-@@ -5522,6 +5540,10 @@ ssl3_HandleCertificateRequest(sslSocket
+@@ -5901,6 +5919,10 @@ ssl3_HandleCertificateRequest(sslSocket
SSL3AlertDescription desc = illegal_parameter;
SECItem cert_types = {siBuffer, NULL, 0};
CERTDistNames ca_list;
@@ -134,7 +85,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
SSL_GETPID(), ss->fd));
-@@ -5538,6 +5560,7 @@ ssl3_HandleCertificateRequest(sslSocket
+@@ -5917,6 +5939,7 @@ ssl3_HandleCertificateRequest(sslSocket
PORT_Assert(ss->ssl3.clientCertChain == NULL);
PORT_Assert(ss->ssl3.clientCertificate == NULL);
PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
@@ -142,7 +93,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
-@@ -5604,6 +5627,20 @@ ssl3_HandleCertificateRequest(sslSocket
+@@ -5983,6 +6006,20 @@ ssl3_HandleCertificateRequest(sslSocket
desc = no_certificate;
ss->ssl3.hs.ws = wait_hello_done;
@@ -163,7 +114,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
if (ss->getClientAuthData == NULL) {
rv = SECFailure; /* force it to send a no_certificate alert */
} else {
-@@ -5613,12 +5650,52 @@ ssl3_HandleCertificateRequest(sslSocket
+@@ -5992,12 +6029,52 @@ ssl3_HandleCertificateRequest(sslSocket
&ss->ssl3.clientCertificate,
&ss->ssl3.clientPrivateKey);
}
@@ -216,7 +167,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
/* check what the callback function returned */
if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
/* we are missing either the key or cert */
-@@ -5681,6 +5758,10 @@ loser:
+@@ -6060,6 +6137,10 @@ loser:
done:
if (arena != NULL)
PORT_FreeArena(arena, PR_FALSE);
@@ -227,7 +178,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
return rv;
}
-@@ -5755,7 +5836,8 @@ ssl3_SendClientSecondRound(sslSocket *ss
+@@ -6134,7 +6215,8 @@ ssl3_SendClientSecondRound(sslSocket *ss
sendClientCert = !ss->ssl3.sendEmptyCert &&
ss->ssl3.clientCertChain != NULL &&
@@ -237,7 +188,7 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
/* We must wait for the server's certificate to be authenticated before
* sending the client certificate in order to disclosing the client
-@@ -9725,6 +9807,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -10446,6 +10528,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
if (ss->ssl3.clientPrivateKey != NULL)
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
@@ -248,10 +199,10 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/
if (ss->ssl3.peerCertArena != NULL)
ssl3_CleanupPeerCerts(ss);
-diff -upN a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c
---- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 19:26:04.047351199 -0800
-+++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 20:20:35.392842118 -0800
-@@ -46,8 +46,8 @@
+diff -puN -r a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
+--- a/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 15:35:08.488958561 -0800
+@@ -11,8 +11,8 @@
#include "nssrenam.h"
#include "nss.h"
#include "ssl.h"
@@ -259,12 +210,12 @@ diff -upN a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/
#include "sslimpl.h"
+#include "sslproto.h"
#include "pk11pub.h"
- #include "blapi.h"
- #include "prinit.h"
-diff -upN a/src/net/third_party/nss/ssl/sslauth.c b/src/net/third_party/nss/ssl/sslauth.c
---- a/src/net/third_party/nss/ssl/sslauth.c 2012-02-28 18:34:23.263186340 -0800
-+++ b/src/net/third_party/nss/ssl/sslauth.c 2012-02-28 20:04:24.039351965 -0800
-@@ -251,6 +251,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s,
+ #ifdef NO_PKCS11_BYPASS
+ #include "blapit.h"
+diff -puN -r a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth.c
+--- a/net/third_party/nss/ssl/sslauth.c 2012-11-09 15:27:15.952019947 -0800
++++ b/net/third_party/nss/ssl/sslauth.c 2012-11-09 15:35:08.488958561 -0800
+@@ -219,6 +219,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s,
return SECSuccess;
}
@@ -293,10 +244,59 @@ diff -upN a/src/net/third_party/nss/ssl/sslauth.c b/src/net/third_party/nss/ssl/
/* NEED LOCKS IN HERE. */
SECStatus
SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
-diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h
---- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 19:26:04.047351199 -0800
-+++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 20:04:24.039351965 -0800
-@@ -65,6 +65,15 @@
+diff -puN -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:35:08.488958561 -0800
+@@ -483,6 +483,45 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl
+ SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
+ SSLGetClientAuthData f, void *a);
+
++/*
++ * Prototype for SSL callback to get client auth data from the application,
++ * optionally using the underlying platform's cryptographic primitives.
++ * To use the platform cryptographic primitives, caNames and pRetCerts
++ * should be set. To use NSS, pRetNSSCert and pRetNSSKey should be set.
++ * Returning SECFailure will cause the socket to send no client certificate.
++ * arg - application passed argument
++ * caNames - pointer to distinguished names of CAs that the server likes
++ * pRetCerts - pointer to pointer to list of certs, with the first being
++ * the client cert, and any following being used for chain
++ * building
++ * pRetKey - pointer to native key pointer, for return of key
++ * - Windows: A pointer to a PCERT_KEY_CONTEXT that was allocated
++ * via PORT_Alloc(). Ownership of the PCERT_KEY_CONTEXT
++ * is transferred to NSS, which will free via
++ * PORT_Free().
++ * - Mac OS X: A pointer to a SecKeyRef. Ownership is
++ * transferred to NSS, which will free via CFRelease().
++ * pRetNSSCert - pointer to pointer to NSS cert, for return of cert.
++ * pRetNSSKey - pointer to NSS key pointer, for return of key.
++ */
++typedef SECStatus (PR_CALLBACK *SSLGetPlatformClientAuthData)(void *arg,
++ PRFileDesc *fd,
++ CERTDistNames *caNames,
++ CERTCertList **pRetCerts,/*return */
++ void **pRetKey,/* return */
++ CERTCertificate **pRetNSSCert,/*return */
++ SECKEYPrivateKey **pRetNSSKey);/* return */
++
++/*
++ * Set the client side callback for SSL to retrieve user's private key
++ * and certificate.
++ * fd - the file descriptor for the connection in question
++ * f - the application's callback that delivers the key and cert
++ * a - application specific data
++ */
++SSL_IMPORT SECStatus
++SSL_GetPlatformClientAuthDataHook(PRFileDesc *fd,
++ SSLGetPlatformClientAuthData f, void *a);
+
+ /*
+ ** SNI extension processing callback function.
+diff -puN -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:34:12.258133766 -0800
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:36:42.600338478 -0800
+@@ -32,6 +32,15 @@
#include "sslt.h" /* for some formerly private types, now public */
@@ -312,7 +312,7 @@ diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/
/* to make some of these old enums public without namespace pollution,
** it was necessary to prepend ssl_ to the names.
** These #defines preserve compatibility with the old code here in libssl.
-@@ -462,6 +471,14 @@ typedef SECStatus (*SSLCompressor)(void
+@@ -446,6 +455,14 @@ typedef SECStatus (*SSLCompressor)(void
int inlen);
typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit);
@@ -327,7 +327,7 @@ diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/
/*
-@@ -836,6 +853,10 @@ struct ssl3StateStr {
+@@ -870,6 +887,10 @@ struct ssl3StateStr {
CERTCertificate * clientCertificate; /* used by client */
SECKEYPrivateKey * clientPrivateKey; /* used by client */
@@ -338,7 +338,7 @@ diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/
CERTCertificateList *clientCertChain; /* used by client */
PRBool sendEmptyCert; /* used by client */
-@@ -1082,6 +1103,10 @@ const unsigned char * preferredCipher;
+@@ -1127,6 +1148,10 @@ const unsigned char * preferredCipher;
void *authCertificateArg;
SSLGetClientAuthData getClientAuthData;
void *getClientAuthDataArg;
@@ -349,7 +349,15 @@ diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/
SSLSNISocketConfig sniSocketConfig;
void *sniSocketConfigArg;
SSLBadCertHandler handleBadCert;
-@@ -1644,6 +1669,26 @@ extern SECStatus ssl_InitSessionCacheLoc
+@@ -1700,7 +1725,6 @@ extern void ssl_FreePRSocket(PRFileDesc
+ * various ciphers */
+ extern int ssl3_config_match_init(sslSocket *);
+
+-
+ /* Create a new ref counted key pair object from two keys. */
+ extern ssl3KeyPair * ssl3_NewKeyPair( SECKEYPrivateKey * privKey,
+ SECKEYPublicKey * pubKey);
+@@ -1740,6 +1764,26 @@ extern SECStatus ssl_InitSessionCacheLoc
extern SECStatus ssl_FreeSessionCacheLocks(void);
@@ -374,11 +382,11 @@ diff -upN a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/
+ CERTCertList* list);
+#endif /* NSS_PLATFORM_CLIENT_AUTH */
- /********************** misc calls *********************/
-
-diff -upN a/src/net/third_party/nss/ssl/sslplatf.c b/src/net/third_party/nss/ssl/sslplatf.c
---- a/src/net/third_party/nss/ssl/sslplatf.c 1969-12-31 16:00:00.000000000 -0800
-+++ b/src/net/third_party/nss/ssl/sslplatf.c 2012-02-28 20:04:24.039351965 -0800
+ /**************** DTLS-specific functions **************/
+ extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
+diff -puN -r a/net/third_party/nss/ssl/sslplatf.c b/net/third_party/nss/ssl/sslplatf.c
+--- a/net/third_party/nss/ssl/sslplatf.c 1969-12-31 16:00:00.000000000 -0800
++++ b/net/third_party/nss/ssl/sslplatf.c 2012-11-09 15:35:08.498958708 -0800
@@ -0,0 +1,399 @@
+/*
+ * Platform specific crypto wrappers
@@ -779,10 +787,10 @@ diff -upN a/src/net/third_party/nss/ssl/sslplatf.c b/src/net/third_party/nss/ssl
+#endif
+
+#endif /* NSS_PLATFORM_CLIENT_AUTH */
-diff -upN a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c
---- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 19:26:04.057351342 -0800
-+++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 20:04:24.049352104 -0800
-@@ -339,6 +339,10 @@ ssl_DupSocket(sslSocket *os)
+diff -puN -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:34:12.268133912 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:35:08.498958708 -0800
+@@ -335,6 +335,10 @@ ssl_DupSocket(sslSocket *os)
ss->authCertificateArg = os->authCertificateArg;
ss->getClientAuthData = os->getClientAuthData;
ss->getClientAuthDataArg = os->getClientAuthDataArg;
@@ -793,7 +801,7 @@ diff -upN a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/
ss->sniSocketConfig = os->sniSocketConfig;
ss->sniSocketConfigArg = os->sniSocketConfigArg;
ss->handleBadCert = os->handleBadCert;
-@@ -1530,6 +1534,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile
+@@ -1712,6 +1716,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile
ss->getClientAuthData = sm->getClientAuthData;
if (sm->getClientAuthDataArg)
ss->getClientAuthDataArg = sm->getClientAuthDataArg;
@@ -806,7 +814,7 @@ diff -upN a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/
if (sm->sniSocketConfig)
ss->sniSocketConfig = sm->sniSocketConfig;
if (sm->sniSocketConfigArg)
-@@ -2617,6 +2627,10 @@ ssl_NewSocket(PRBool makeLocks)
+@@ -2942,6 +2952,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
ss->sniSocketConfig = NULL;
ss->sniSocketConfigArg = NULL;
ss->getClientAuthData = NULL;
diff --git a/net/third_party/nss/patches/dhvalues.patch b/net/third_party/nss/patches/dhvalues.patch
deleted file mode 100644
index 5d8ef28..0000000
--- a/net/third_party/nss/patches/dhvalues.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
-index b6f4313..5476fa5 100644
---- a/net/third_party/nss/ssl/ssl3con.c
-+++ b/net/third_party/nss/ssl/ssl3con.c
-@@ -5505,6 +5505,30 @@ loser:
- return SECFailure;
- }
-
-+/* ssl3_BigIntGreaterThan1 returns true iff |mpint|, taken as an unsigned,
-+ * big-endian integer is > 1 */
-+static PRBool
-+ssl3_BigIntGreaterThan1(const SECItem* mpint) {
-+ unsigned char firstNonZeroByte = 0;
-+ unsigned int i;
-+
-+ for (i = 0; i < mpint->len; i++) {
-+ if (mpint->data[i]) {
-+ firstNonZeroByte = mpint->data[i];
-+ break;
-+ }
-+ }
-+
-+ if (firstNonZeroByte == 0)
-+ return PR_FALSE;
-+ if (firstNonZeroByte > 1)
-+ return PR_TRUE;
-+
-+ // firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte
-+ // is followed by another byte.
-+ return (i < mpint->len - 1);
-+}
-+
- /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ServerKeyExchange message.
- * Caller must hold Handshake and RecvBuf locks.
-@@ -5636,15 +5660,13 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-- if (dh_g.len == 0 || dh_g.len > dh_p.len + 1 ||
-- (dh_g.len == 1 && dh_g.data[0] == 0))
-+ if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThan1(&dh_g))
- goto alert_loser;
- rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-- if (dh_Ys.len == 0 || dh_Ys.len > dh_p.len + 1 ||
-- (dh_Ys.len == 1 && dh_Ys.data[0] == 0))
-+ if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThan1(&dh_Ys))
- goto alert_loser;
- rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
- if (rv != SECSuccess) {
diff --git a/net/third_party/nss/patches/didhandshakeresume.patch b/net/third_party/nss/patches/didhandshakeresume.patch
index ed74c79..3523cb7 100644
--- a/net/third_party/nss/patches/didhandshakeresume.patch
+++ b/net/third_party/nss/patches/didhandshakeresume.patch
@@ -1,7 +1,7 @@
-diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h
---- a/src/net/third_party/nss/ssl/ssl.h 2012-02-28 20:34:50.114663722 -0800
-+++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 14:37:56.872332622 -0800
-@@ -818,6 +818,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegoti
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 15:44:22.247069358 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:43:25.766243027 -0800
+@@ -917,6 +917,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegoti
SSLExtensionType extId,
PRBool *yes);
@@ -9,12 +9,12 @@ diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h
+ PRBool *last_handshake_resumed);
+
/*
- * Return a boolean that indicates whether the underlying library
- * will perform as the caller expects.
-diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c
---- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-28 20:34:50.124663860 -0800
-+++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 14:39:13.203415737 -0800
-@@ -1590,6 +1590,20 @@ SSL_GetStapledOCSPResponse(PRFileDesc *f
+ ** How long should we wait before retransmitting the next flight of
+ ** the DTLS handshake? Returns SECFailure if not DTLS or not in a
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:44:22.247069358 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:40:33.053714908 -0800
+@@ -1912,6 +1912,20 @@ SSL_GetStapledOCSPResponse(PRFileDesc *f
return SECSuccess;
}
diff --git a/net/third_party/nss/patches/dtls.patch b/net/third_party/nss/patches/dtls.patch
deleted file mode 100644
index f8239d2..0000000
--- a/net/third_party/nss/patches/dtls.patch
+++ /dev/null
@@ -1,3322 +0,0 @@
-Index: net/third_party/nss/ssl/SSLerrs.h
-===================================================================
---- net/third_party/nss/ssl/SSLerrs.h (revision 127709)
-+++ net/third_party/nss/ssl/SSLerrs.h (working copy)
-@@ -423,3 +423,9 @@
-
- ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 121),
- "SSL received an unexpected Certificate Status handshake message.")
-+
-+ER3(SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 122),
-+"SSL received a malformed Hello Verify Request handshake message.")
-+
-+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 123),
-+"SSL received an unexpected Hello Verify Request handshake message.")
-Index: net/third_party/nss/ssl/ssl.h
-===================================================================
---- net/third_party/nss/ssl/ssl.h (revision 127709)
-+++ net/third_party/nss/ssl/ssl.h (working copy)
-@@ -80,6 +80,12 @@
- SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
-
- /*
-+** Imports fd into DTLS, returning a new socket. Copies DTLS configuration
-+** from model.
-+*/
-+SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
-+
-+/*
- ** Enable/disable an ssl mode
- **
- ** SSL_SECURITY:
-@@ -942,6 +948,14 @@
- PRBool *last_handshake_resumed);
-
- /*
-+** How long should we wait before retransmitting the next flight of
-+** the DTLS handshake? Returns SECFailure if not DTLS or not in a
-+** handshake.
-+*/
-+SSL_IMPORT SECStatus DTLS_GetHandshakeTimeout(PRFileDesc *socket,
-+ PRIntervalTime *timeout);
-+
-+/*
- * Return a boolean that indicates whether the underlying library
- * will perform as the caller expects.
- *
-Index: net/third_party/nss/ssl/ssl3gthr.c
-===================================================================
---- net/third_party/nss/ssl/ssl3gthr.c (revision 127709)
-+++ net/third_party/nss/ssl/ssl3gthr.c (working copy)
-@@ -50,7 +50,7 @@
- *
- * returns 1 if received a complete SSL3 record.
- * returns 0 if recv returns EOF
-- * returns -1 if recv returns <0
-+ * returns -1 if recv returns < 0
- * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
- *
- * Caller must hold the recv buf lock.
-@@ -59,7 +59,8 @@
- * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
- * GS_DATA: waiting for the body of the SSL3 record to come in.
- *
-- * This loop returns when either (a) an error or EOF occurs,
-+ * This loop returns when either
-+ * (a) an error or EOF occurs,
- * (b) PR_WOULD_BLOCK_ERROR,
- * (c) data (entire SSL3 record) has been received.
- */
-@@ -167,6 +168,125 @@
- return rv;
- }
-
-+/*
-+ * Read in an entire DTLS record.
-+ *
-+ * Blocks here for blocking sockets, otherwise returns -1 with
-+ * PR_WOULD_BLOCK_ERROR when socket would block.
-+ *
-+ * This is simpler than SSL because we are reading on a datagram socket
-+ * and datagrams must contain >=1 complete records.
-+ *
-+ * returns 1 if received a complete DTLS record.
-+ * returns 0 if recv returns EOF
-+ * returns -1 if recv returns < 0
-+ * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
-+ *
-+ * Caller must hold the recv buf lock.
-+ *
-+ * This loop returns when either
-+ * (a) an error or EOF occurs,
-+ * (b) PR_WOULD_BLOCK_ERROR,
-+ * (c) data (entire DTLS record) has been received.
-+ */
-+static int
-+dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
-+{
-+ int nb;
-+ int err;
-+ int rv = 1;
-+
-+ SSL_TRC(30, ("dtls_GatherData"));
-+
-+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-+
-+ gs->state = GS_HEADER;
-+ gs->offset = 0;
-+
-+ if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
-+ gs->dtlsPacketOffset = 0;
-+ gs->dtlsPacket.len = 0;
-+
-+ /* Resize to the maximum possible size so we can fit a full datagram */
-+ /* This is the max fragment length for an encrypted fragment
-+ ** plus the size of the record header.
-+ ** This magic constant is copied from ssl3_GatherData, with 5 changed
-+ ** to 13 (the size of the record header).
-+ */
-+ if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
-+ err = sslBuffer_Grow(&gs->dtlsPacket,
-+ MAX_FRAGMENT_LENGTH + 2048 + 13);
-+ if (err) { /* realloc has set error code to no mem. */
-+ return err;
-+ }
-+ }
-+
-+ /* recv() needs to read a full datagram at a time */
-+ nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
-+
-+ if (nb > 0) {
-+ PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
-+ } else if (nb == 0) {
-+ /* EOF */
-+ SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
-+ rv = 0;
-+ return rv;
-+ } else /* if (nb < 0) */ {
-+ SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
-+ PR_GetError()));
-+ rv = SECFailure;
-+ return rv;
-+ }
-+
-+ gs->dtlsPacket.len = nb;
-+ }
-+
-+ /* At this point we should have >=1 complete records lined up in
-+ * dtlsPacket. Read off the header.
-+ */
-+ if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) {
-+ SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
-+ "too short to contain header", SSL_GETPID(), ss->fd));
-+ PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
-+ gs->dtlsPacketOffset = 0;
-+ gs->dtlsPacket.len = 0;
-+ rv = SECFailure;
-+ return rv;
-+ }
-+ memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13);
-+ gs->dtlsPacketOffset += 13;
-+
-+ /* Have received SSL3 record header in gs->hdr. */
-+ gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
-+
-+ if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
-+ SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
-+ "to contain rest of body", SSL_GETPID(), ss->fd));
-+ PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
-+ gs->dtlsPacketOffset = 0;
-+ gs->dtlsPacket.len = 0;
-+ rv = SECFailure;
-+ return rv;
-+ }
-+
-+ /* OK, we have at least one complete packet, copy into inbuf */
-+ if (gs->remainder > gs->inbuf.space) {
-+ err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
-+ if (err) { /* realloc has set error code to no mem. */
-+ return err;
-+ }
-+ }
-+
-+ memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
-+ gs->remainder);
-+ gs->inbuf.len = gs->remainder;
-+ gs->offset = gs->remainder;
-+ gs->dtlsPacketOffset += gs->remainder;
-+ gs->state = GS_INIT;
-+
-+ return 1;
-+}
-+
- /* Gather in a record and when complete, Handle that record.
- * Repeat this until the handshake is complete,
- * or until application data is available.
-@@ -190,6 +310,8 @@
- int rv;
- PRBool canFalseStart = PR_FALSE;
-
-+ SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
-+
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- do {
- /* Without this, we may end up wrongly reporting
-@@ -224,7 +346,24 @@
- rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
- } else {
- /* bring in the next sslv3 record. */
-- rv = ssl3_GatherData(ss, &ss->gs, flags);
-+ if (!IS_DTLS(ss)) {
-+ rv = ssl3_GatherData(ss, &ss->gs, flags);
-+ } else {
-+ rv = dtls_GatherData(ss, &ss->gs, flags);
-+
-+ /* If we got a would block error, that means that no data was
-+ * available, so we check the timer to see if it's time to
-+ * retransmit */
-+ if (rv == SECFailure &&
-+ (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
-+ ssl_GetSSL3HandshakeLock(ss);
-+ dtls_CheckTimer(ss);
-+ ssl_ReleaseSSL3HandshakeLock(ss);
-+ /* Restore the error in case something succeeded */
-+ PORT_SetError(PR_WOULD_BLOCK_ERROR);
-+ }
-+ }
-+
- if (rv <= 0) {
- return rv;
- }
-@@ -236,6 +375,20 @@
- */
- cText.type = (SSL3ContentType)ss->gs.hdr[0];
- cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
-+
-+ if (IS_DTLS(ss)) {
-+ int i;
-+
-+ cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
-+ /* DTLS sequence number */
-+ cText.seq_num.high = 0; cText.seq_num.low = 0;
-+ for (i = 0; i < 4; i++) {
-+ cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
-+ cText.seq_num.high |= ss->gs.hdr[3 + i];
-+ cText.seq_num.low |= ss->gs.hdr[7 + i];
-+ }
-+ }
-+
- cText.buf = &ss->gs.inbuf;
- rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
- }
-Index: net/third_party/nss/ssl/derive.c
-===================================================================
---- net/third_party/nss/ssl/derive.c (revision 127709)
-+++ net/third_party/nss/ssl/derive.c (working copy)
-@@ -583,6 +583,8 @@
- * arguments were all valid but the slot cannot be bypassed.
- */
-
-+/* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */
-+
- SECStatus
- SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey,
- PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites,
-Index: net/third_party/nss/ssl/sslerr.h
-===================================================================
---- net/third_party/nss/ssl/sslerr.h (revision 127709)
-+++ net/third_party/nss/ssl/sslerr.h (working copy)
-@@ -215,6 +215,9 @@
-
- SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 121),
-
-+SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
-+SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
-+
- SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
- } SSLErrorCodes;
- #endif /* NO_SECURITY_ERROR_ENUM */
-Index: net/third_party/nss/ssl/ssldef.c
-===================================================================
---- net/third_party/nss/ssl/ssldef.c (revision 127709)
-+++ net/third_party/nss/ssl/ssldef.c (working copy)
-@@ -138,6 +138,11 @@
- return rv;
- }
- sent += rv;
-+
-+ if (IS_DTLS(ss) && (len > sent)) {
-+ /* We got a partial write so just return it */
-+ return sent;
-+ }
- } while (len > sent);
- ss->lastWriteBlocked = 0;
- return sent;
-Index: net/third_party/nss/ssl/sslimpl.h
-===================================================================
---- net/third_party/nss/ssl/sslimpl.h (revision 127709)
-+++ net/third_party/nss/ssl/sslimpl.h (working copy)
-@@ -62,6 +62,7 @@
- #endif
- #include "nssrwlk.h"
- #include "prthread.h"
-+#include "prclist.h"
-
- #include "sslt.h" /* for some formerly private types, now public */
-
-@@ -195,6 +196,10 @@
-
- #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
-
-+#define INITIAL_DTLS_TIMEOUT_MS 1000 /* Default value from RFC 4347 = 1s*/
-+#define MAX_DTLS_TIMEOUT_MS 60000 /* 1 minute */
-+#define DTLS_FINISHED_TIMER_MS 120000 /* Time to wait in FINISHED state */
-+
- typedef struct sslBufferStr sslBuffer;
- typedef struct sslConnectInfoStr sslConnectInfo;
- typedef struct sslGatherStr sslGather;
-@@ -287,6 +292,8 @@
- /* 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_USE_EPOCH 0x10000000 /* DTLS only */
-+#define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
- #define ssl_SEND_FLAG_MASK 0x7f000000
-
- /*
-@@ -448,8 +455,15 @@
- ** The portion of the SSL record header put here always comes off the wire
- ** as plaintext, never ciphertext.
- ** For SSL2, the plaintext portion is two bytes long. For SSl3 it is 5.
-+ ** For DTLS it is 13.
- */
-- unsigned char hdr[5]; /* ssl 2 & 3 */
-+ unsigned char hdr[13]; /* ssl 2 & 3 or dtls */
-+
-+ /* Buffer for DTLS data read off the wire as a single datagram */
-+ sslBuffer dtlsPacket;
-+
-+ /* the start of the buffered DTLS record in dtlsPacket */
-+ unsigned int dtlsPacketOffset;
- };
-
- /* sslGather.state */
-@@ -521,6 +535,10 @@
- PRUint32 low;
- } SSL3SequenceNumber;
-
-+typedef PRUint16 DTLSEpoch;
-+
-+typedef void (*DTLSTimerCb)(sslSocket *);
-+
- #define MAX_MAC_CONTEXT_BYTES 400
- #define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8)
-
-@@ -547,6 +565,20 @@
- PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS];
- } ssl3KeyMaterial;
-
-+/* The DTLS anti-replay window. Defined here because we need it in
-+ * the cipher spec. Note that this is a ring buffer but left and
-+ * right represent the true window, with modular arithmetic used to
-+ * map them onto the buffer.
-+ */
-+#define DTLS_RECVD_RECORDS_WINDOW 1024 /* Packets; approximate
-+ * Must be divisible by 8
-+ */
-+typedef struct DTLSRecvdRecordsStr {
-+ unsigned char data[DTLS_RECVD_RECORDS_WINDOW/8];
-+ PRUint64 left;
-+ PRUint64 right;
-+} DTLSRecvdRecords;
-+
- /*
- ** These are the "specs" in the "ssl3" struct.
- ** Access to the pointers to these specs, and all the specs' contents
-@@ -582,6 +614,8 @@
- SECItem srvVirtName; /* for server: name that was negotiated
- * with a client. For client - is
- * always set to NULL.*/
-+ DTLSEpoch epoch;
-+ DTLSRecvdRecords recvdRecords;
- } ssl3CipherSpec;
-
- typedef enum { never_cached,
-@@ -777,6 +811,17 @@
- typedef SECStatus (*sslRestartTarget)(sslSocket *);
-
- /*
-+** A DTLS queued message (potentially to be retransmitted)
-+*/
-+typedef struct DTLSQueuedMessageStr {
-+ PRCList link; /* The linked list link */
-+ DTLSEpoch epoch; /* The epoch to use */
-+ SSL3ContentType type; /* The message type */
-+ unsigned char *data; /* The data */
-+ PRUint16 len; /* The data length */
-+} DTLSQueuedMessage;
-+
-+/*
- ** This is the "hs" member of the "ssl3" struct.
- ** This entire struct is protected by ssl3HandshakeLock
- */
-@@ -831,6 +876,30 @@
- sslRestartTarget restartTarget;
- /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
- PRBool cacheSID;
-+
-+ /* This group of values is used for DTLS */
-+ PRUint16 sendMessageSeq; /* The sending message sequence
-+ * number */
-+ PRCList * lastMessageFlight; /* The last message flight we sent.
-+ * This is a pointer because
-+ * ssl_FreeSocket relocates the
-+ * structure in DEBUG mode, which
-+ * messes up the list macros */
-+ PRUint16 maxMessageSent; /* The largest message we sent */
-+ PRUint16 recvMessageSeq; /* The receiving message sequence
-+ * number */
-+ sslBuffer recvdFragments; /* The fragments we have received in
-+ * a bitmask */
-+ PRInt32 recvdHighWater; /* The high water mark for fragments
-+ * received. -1 means no reassembly
-+ * in progress. */
-+ unsigned char cookie[32]; /* The cookie */
-+ unsigned char cookieLen; /* The length of the cookie */
-+ PRIntervalTime rtTimerStarted; /* When the timer was started */
-+ DTLSTimerCb rtTimerCb; /* The function to call on expiry */
-+ PRUint32 rtTimeoutMs; /* The length of the current timeout
-+ * used for backoff (in ms) */
-+ PRUint32 rtRetries; /* The retry counter */
- } SSL3HandshakeState;
-
-
-@@ -882,11 +951,18 @@
- */
- SECItem nextProto;
- SSLNextProtoState nextProtoState;
-+
-+ PRUint16 mtu; /* Our estimate of the MTU */
- };
-
-+#define DTLS_MAX_MTU 1500 /* Ethernet MTU but without subtracting the
-+ * headers, so slightly larger than expected */
-+#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
-+
- typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
-+ SSL3SequenceNumber seq_num; /* DTLS only */
- sslBuffer * buf;
- } SSL3Ciphertext;
-
-@@ -1188,6 +1264,9 @@
- /* True when the current session is a stateless resume. */
- PRBool statelessResume;
- TLSExtensionData xtnData;
-+
-+ /* Whether we are doing stream or datagram mode */
-+ SSLProtocolVariant protocolVariant;
- };
-
-
-@@ -1321,7 +1400,35 @@
- extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
-
- extern PRBool ssl3_CanFalseStart(sslSocket *ss);
-+extern SECStatus
-+ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
-+ PRBool isServer,
-+ PRBool isDTLS,
-+ SSL3ContentType type,
-+ const SSL3Opaque * pIn,
-+ PRUint32 contentLen,
-+ sslBuffer * wrBuf);
-+extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch,
-+ SSL3ContentType type,
-+ const SSL3Opaque* pIn, PRInt32 nIn,
-+ PRInt32 flags);
-
-+#ifdef NSS_ENABLE_ZLIB
-+/*
-+ * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a
-+ * maximum TLS record payload of 2**14 bytes, that's 29 bytes.
-+ */
-+#define SSL3_COMPRESSION_MAX_EXPANSION 29
-+#else /* !NSS_ENABLE_ZLIB */
-+#define SSL3_COMPRESSION_MAX_EXPANSION 0
-+#endif
-+
-+/*
-+ * make sure there is room in the write buffer for padding and
-+ * other compression and cryptographic expansions.
-+ */
-+#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION
-+
- #define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock)
- #define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock)
- #define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock)
-@@ -1417,6 +1524,7 @@
- extern void ssl_FreeSocket(struct sslSocketStr *ssl);
- extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
- SSL3AlertDescription desc);
-+extern SECStatus ssl3_DecodeError(sslSocket *ss);
-
- extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
-@@ -1436,7 +1544,7 @@
- /*
- * SSL3 specific routines
- */
--SECStatus ssl3_SendClientHello(sslSocket *ss);
-+SECStatus ssl3_SendClientHello(sslSocket *ss, PRBool resending);
-
- /*
- * input into the SSL3 machinery from the actualy network reading code
-@@ -1531,6 +1639,8 @@
- unsigned char *cs, int *size);
-
- extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
-+extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
-+ PRUint32 length);
-
- extern void ssl3_DestroySSL3Info(sslSocket *ss);
-
-@@ -1556,6 +1666,7 @@
- extern SECStatus ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf,
- unsigned int bufLen, SSL3Hashes *hashes,
- PRBool bypassPKCS11);
-+extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName);
- extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms);
- extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src,
- PRInt32 bytes);
-@@ -1724,6 +1835,42 @@
- CERTCertList* list);
- #endif /* NSS_PLATFORM_CLIENT_AUTH */
-
-+/**************** DTLS-specific functions **************/
-+extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
-+extern void dtls_FreeQueuedMessages(PRCList *lst);
-+extern void dtls_FreeHandshakeMessages(PRCList *lst);
-+
-+extern SECStatus dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf);
-+extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss,
-+ SSL3Opaque *b, PRUint32 length);
-+extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss);
-+extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
-+ const SSL3Opaque *pIn, PRInt32 nIn);
-+extern SECStatus dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
-+extern SECStatus dtls_CompressMACEncryptRecord(sslSocket *ss,
-+ DTLSEpoch epoch,
-+ PRBool use_epoch,
-+ SSL3ContentType type,
-+ const SSL3Opaque *pIn,
-+ PRUint32 contentLen,
-+ sslBuffer *wrBuf);
-+SECStatus ssl3_DisableNonDTLSSuites(sslSocket * ss);
-+extern SECStatus dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb);
-+extern SECStatus dtls_RestartTimer(sslSocket *ss, PRBool backoff,
-+ DTLSTimerCb cb);
-+extern void dtls_CheckTimer(sslSocket *ss);
-+extern void dtls_CancelTimer(sslSocket *ss);
-+extern void dtls_FinishedTimerCb(sslSocket *ss);
-+extern void dtls_SetMTU(sslSocket *ss, PRUint16 advertised);
-+extern void dtls_InitRecvdRecords(DTLSRecvdRecords *records);
-+extern int dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq);
-+extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq);
-+extern void dtls_RehandshakeCleanup(sslSocket *ss);
-+extern SSL3ProtocolVersion
-+dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv);
-+extern SSL3ProtocolVersion
-+dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv);
-+
- /********************** misc calls *********************/
-
- extern int ssl_MapLowLevelError(int hiLevelError);
-Index: net/third_party/nss/ssl/manifest.mn
-===================================================================
---- net/third_party/nss/ssl/manifest.mn (revision 127709)
-+++ net/third_party/nss/ssl/manifest.mn (working copy)
-@@ -51,6 +51,7 @@
-
- CSRCS = \
- derive.c \
-+ dtls1con.c \
- prelib.c \
- ssl3con.c \
- ssl3gthr.c \
-Index: net/third_party/nss/ssl/ssl3prot.h
-===================================================================
---- net/third_party/nss/ssl/ssl3prot.h (revision 127709)
-+++ net/third_party/nss/ssl/ssl3prot.h (working copy)
-@@ -61,6 +61,9 @@
-
- #define SSL3_RECORD_HEADER_LENGTH 5
-
-+/* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
-+#define DTLS_RECORD_HEADER_LENGTH 13
-+
- #define MAX_FRAGMENT_LENGTH 16384
-
- typedef enum {
-@@ -150,6 +153,7 @@
- hello_request = 0,
- client_hello = 1,
- server_hello = 2,
-+ hello_verify_request = 3,
- new_session_ticket = 4,
- certificate = 11,
- server_key_exchange = 12,
-Index: net/third_party/nss/ssl/sslcon.c
-===================================================================
---- net/third_party/nss/ssl/sslcon.c (revision 127709)
-+++ net/third_party/nss/ssl/sslcon.c (working copy)
-@@ -1249,7 +1249,12 @@
-
- ssl_GetRecvBufLock(ss);
-
-- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
-+ /* The special case DTLS logic is needed here because the SSL/TLS
-+ * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake
-+ * (ss->version == 0) but with DTLS it gets confused, so we force the
-+ * SSL3 version.
-+ */
-+ if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) {
- /* Wait for handshake to complete, or application data to arrive. */
- rv = ssl3_GatherCompleteHandshake(ss, 0);
- } else {
-@@ -3120,7 +3125,7 @@
-
- ssl_GetSSL3HandshakeLock(ss);
- ssl_GetXmitBufLock(ss);
-- rv = ssl3_SendClientHello(ss);
-+ rv = ssl3_SendClientHello(ss, PR_FALSE);
- ssl_ReleaseXmitBufLock(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
-
-Index: net/third_party/nss/ssl/sslsecur.c
-===================================================================
---- net/third_party/nss/ssl/sslsecur.c (revision 127709)
-+++ net/third_party/nss/ssl/sslsecur.c (working copy)
-@@ -615,6 +615,7 @@
- if (!(flags & PR_MSG_PEEK)) {
- ss->gs.readOffset += amount;
- }
-+ PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset);
- rv = amount;
-
- SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
-Index: net/third_party/nss/ssl/sslsock.c
-===================================================================
---- net/third_party/nss/ssl/sslsock.c (revision 127709)
-+++ net/third_party/nss/ssl/sslsock.c (working copy)
-@@ -194,11 +194,20 @@
- /*
- * default range of enabled SSL/TLS protocols
- */
--static SSLVersionRange versions_defaults = {
-+static SSLVersionRange versions_defaults_stream = {
- SSL_LIBRARY_VERSION_3_0,
- SSL_LIBRARY_VERSION_TLS_1_0
- };
-
-+static SSLVersionRange versions_defaults_datagram = {
-+ SSL_LIBRARY_VERSION_TLS_1_1,
-+ SSL_LIBRARY_VERSION_TLS_1_1
-+};
-+
-+#define VERSIONS_DEFAULTS(variant) \
-+ (variant == ssl_variant_stream ? &versions_defaults_stream : \
-+ &versions_defaults_datagram)
-+
- sslSessionIDLookupFunc ssl_sid_lookup;
- sslSessionIDCacheFunc ssl_sid_cache;
- sslSessionIDUncacheFunc ssl_sid_uncache;
-@@ -217,7 +226,7 @@
- #define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
-
- /* forward declarations. */
--static sslSocket *ssl_NewSocket(PRBool makeLocks);
-+static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
- static SECStatus ssl_MakeLocks(sslSocket *ss);
- static void ssl_SetDefaultsFromEnvironment(void);
- static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
-@@ -281,7 +290,13 @@
- sslSocket *ss;
- SECStatus rv;
-
-- ss = ssl_NewSocket((PRBool)(!os->opt.noLocks));
-+ /* Not implemented for datagram */
-+ if (IS_DTLS(os)) {
-+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
-+ return NULL;
-+ }
-+
-+ ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
- if (ss) {
- ss->opt = os->opt;
- ss->opt.useSocks = PR_FALSE;
-@@ -698,6 +713,13 @@
- break;
-
- case SSL_ENABLE_TLS:
-+ if (IS_DTLS(ss)) {
-+ if (on) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ rv = SECFailure; /* not allowed */
-+ }
-+ break;
-+ }
- ssl_EnableTLS(&ss->vrange, on);
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
-@@ -708,6 +730,13 @@
- break;
-
- case SSL_ENABLE_SSL3:
-+ if (IS_DTLS(ss)) {
-+ if (on) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ rv = SECFailure; /* not allowed */
-+ }
-+ break;
-+ }
- ssl_EnableSSL3(&ss->vrange, on);
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
-@@ -718,6 +747,13 @@
- break;
-
- case SSL_ENABLE_SSL2:
-+ if (IS_DTLS(ss)) {
-+ if (on) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ rv = SECFailure; /* not allowed */
-+ }
-+ break;
-+ }
- ss->opt.enableSSL2 = on;
- if (on) {
- ss->opt.v2CompatibleHello = on;
-@@ -743,6 +779,13 @@
- break;
-
- case SSL_V2_COMPATIBLE_HELLO:
-+ if (IS_DTLS(ss)) {
-+ if (on) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ rv = SECFailure; /* not allowed */
-+ }
-+ break;
-+ }
- ss->opt.v2CompatibleHello = on;
- if (!on) {
- ss->opt.enableSSL2 = on;
-@@ -938,10 +981,10 @@
- case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient; break;
- case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer; break;
- case SSL_ENABLE_TLS:
-- on = versions_defaults.max >= SSL_LIBRARY_VERSION_TLS_1_0;
-+ on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
- break;
- case SSL_ENABLE_SSL3:
-- on = versions_defaults.min == SSL_LIBRARY_VERSION_3_0;
-+ on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
- break;
- case SSL_ENABLE_SSL2: on = ssl_defaults.enableSSL2; break;
- case SSL_NO_CACHE: on = ssl_defaults.noCache; break;
-@@ -1034,11 +1077,11 @@
- break;
-
- case SSL_ENABLE_TLS:
-- ssl_EnableTLS(&versions_defaults, on);
-+ ssl_EnableTLS(&versions_defaults_stream, on);
- break;
-
- case SSL_ENABLE_SSL3:
-- ssl_EnableSSL3(&versions_defaults, on);
-+ ssl_EnableSSL3(&versions_defaults_stream, on);
- break;
-
- case SSL_ENABLE_SSL2:
-@@ -1360,8 +1403,8 @@
-
-
- /* LOCKS ??? XXX */
--PRFileDesc *
--SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
-+static PRFileDesc *
-+ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
- {
- sslSocket * ns = NULL;
- PRStatus rv;
-@@ -1374,10 +1417,10 @@
-
- if (model == NULL) {
- /* Just create a default socket if we're given NULL for the model */
-- ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks));
-+ ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
- } else {
- sslSocket * ss = ssl_FindSocket(model);
-- if (ss == NULL) {
-+ if (ss == NULL || ss->protocolVariant != variant) {
- SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
- SSL_GETPID(), model));
- return NULL;
-@@ -1403,6 +1446,18 @@
- return fd;
- }
-
-+PRFileDesc *
-+SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
-+{
-+ return ssl_ImportFD(model, fd, ssl_variant_stream);
-+}
-+
-+PRFileDesc *
-+DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
-+{
-+ return ssl_ImportFD(model, fd, ssl_variant_datagram);
-+}
-+
- SECStatus
- SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
- void *arg)
-@@ -1667,9 +1722,18 @@
- ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
- SSL3ProtocolVersion version)
- {
-- return protocolVariant == ssl_variant_stream &&
-- version >= SSL_LIBRARY_VERSION_3_0 &&
-- version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED;
-+ switch (protocolVariant) {
-+ case ssl_variant_stream:
-+ return (version >= SSL_LIBRARY_VERSION_3_0 &&
-+ version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
-+ case ssl_variant_datagram:
-+ return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
-+ version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
-+ default:
-+ /* Can't get here */
-+ PORT_Assert(PR_FALSE);
-+ return PR_FALSE;
-+ }
- }
-
- /* Returns PR_TRUE if the given version range is valid and
-@@ -1689,13 +1753,24 @@
- SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
- SSLVersionRange *vrange)
- {
-- if (protocolVariant != ssl_variant_stream || !vrange) {
-+ if (!vrange) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
-- vrange->min = SSL_LIBRARY_VERSION_3_0;
-- vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
-+ switch (protocolVariant) {
-+ case ssl_variant_stream:
-+ vrange->min = SSL_LIBRARY_VERSION_3_0;
-+ vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
-+ break;
-+ case ssl_variant_datagram:
-+ vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
-+ vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
-+ break;
-+ default:
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ return SECFailure;
-+ }
-
- return SECSuccess;
- }
-@@ -1704,12 +1779,13 @@
- SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
- SSLVersionRange *vrange)
- {
-- if (protocolVariant != ssl_variant_stream || !vrange) {
-+ if ((protocolVariant != ssl_variant_stream &&
-+ protocolVariant != ssl_variant_datagram) || !vrange) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
-- *vrange = versions_defaults;
-+ *vrange = *VERSIONS_DEFAULTS(protocolVariant);
-
- return SECSuccess;
- }
-@@ -1723,7 +1799,7 @@
- return SECFailure;
- }
-
-- versions_defaults = *vrange;
-+ *VERSIONS_DEFAULTS(protocolVariant) = *vrange;
-
- return SECSuccess;
- }
-@@ -2830,7 +2906,7 @@
- ** Create a newsocket structure for a file descriptor.
- */
- static sslSocket *
--ssl_NewSocket(PRBool makeLocks)
-+ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
- {
- sslSocket *ss;
-
-@@ -2851,7 +2927,7 @@
- ss->opt = ssl_defaults;
- ss->opt.useSocks = PR_FALSE;
- ss->opt.noLocks = !makeLocks;
-- ss->vrange = versions_defaults;
-+ ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
-
- ss->peerID = NULL;
- ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
-@@ -2907,6 +2983,7 @@
- PORT_Free(ss);
- ss = NULL;
- }
-+ ss->protocolVariant = protocolVariant;
- }
- return ss;
- }
-Index: net/third_party/nss/ssl/ssl3con.c
-===================================================================
---- net/third_party/nss/ssl/ssl3con.c (revision 127709)
-+++ net/third_party/nss/ssl/ssl3con.c (working copy)
-@@ -42,6 +42,8 @@
- * ***** END LICENSE BLOCK ***** */
- /* $Id: ssl3con.c,v 1.173 2012/03/18 00:31:19 wtc%google.com Exp $ */
-
-+/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
-+
- #include "cert.h"
- #include "ssl.h"
- #include "cryptohi.h" /* for DSAU_ stuff */
-@@ -92,6 +94,7 @@
- static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
- const unsigned char *b,
- unsigned int l);
-+static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
-
- static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
- int maxOutputLen, const unsigned char *input,
-@@ -221,22 +224,6 @@
- #endif /* NSS_ENABLE_ECC */
- };
-
--#ifdef NSS_ENABLE_ZLIB
--/*
-- * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a
-- * maximum TLS record payload of 2**14 bytes, that's 29 bytes.
-- */
--#define SSL3_COMPRESSION_MAX_EXPANSION 29
--#else /* !NSS_ENABLE_ZLIB */
--#define SSL3_COMPRESSION_MAX_EXPANSION 0
--#endif
--
--/*
-- * make sure there is room in the write buffer for padding and
-- * other compression and cryptographic expansions.
-- */
--#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION
--
- #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
-
-
-@@ -517,6 +504,7 @@
- case hello_request: rv = "hello_request (0)"; break;
- case client_hello: rv = "client_hello (1)"; break;
- case server_hello: rv = "server_hello (2)"; break;
-+ case hello_verify_request: rv = "hello_verify_request (3)"; break;
- case certificate: rv = "certificate (11)"; break;
- case server_key_exchange: rv = "server_key_exchange (12)"; break;
- case certificate_request: rv = "certificate_request (13)"; break;
-@@ -656,7 +644,7 @@
- suite->isPresent = PR_FALSE;
- continue;
- }
-- cipher_alg=bulk_cipher_defs[cipher_def->bulk_cipher_alg ].calg;
-+ cipher_alg = bulk_cipher_defs[cipher_def->bulk_cipher_alg].calg;
- PORT_Assert( alg2Mech[cipher_alg].calg == cipher_alg);
- cipher_mech = alg2Mech[cipher_alg].cmech;
- exchKeyType =
-@@ -1148,7 +1136,7 @@
- ** ssl3_DestroySSL3Info
- ** Caller must hold SpecWriteLock.
- */
--static void
-+void
- ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
- {
- PRBool freeit = (PRBool)(!spec->bypassCiphers);
-@@ -1228,6 +1216,12 @@
- return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */
- }
-
-+ if (IS_DTLS(ss)) {
-+ /* Double-check that we did not pick an RC4 suite */
-+ PORT_Assert((suite_def->bulk_cipher_alg != cipher_rc4) &&
-+ (suite_def->bulk_cipher_alg != cipher_rc4_40) &&
-+ (suite_def->bulk_cipher_alg != cipher_rc4_56));
-+ }
-
- cipher = suite_def->bulk_cipher_alg;
- kea = suite_def->key_exchange_alg;
-@@ -1754,6 +1748,7 @@
- ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
- {
- ssl3CipherSpec * pwSpec;
-+ ssl3CipherSpec * cwSpec;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-@@ -1763,6 +1758,7 @@
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
-
- pwSpec = ss->ssl3.pwSpec;
-+ cwSpec = ss->ssl3.cwSpec;
-
- if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) {
- rv = ssl3_DeriveMasterSecret(ss, pms);
-@@ -1794,7 +1790,32 @@
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- }
-+ if (rv != SECSuccess) {
-+ goto done;
-+ }
-
-+ /* Generic behaviors -- common to all crypto methods */
-+ if (!IS_DTLS(ss)) {
-+ pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = 0;
-+ } else {
-+ if (cwSpec->epoch == PR_UINT16_MAX) {
-+ /* The problem here is that we have rehandshaked too many
-+ * times (you are not allowed to wrap the epoch). The
-+ * spec says you should be discarding the connection
-+ * and start over, so not much we can do here. */
-+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
-+ rv = SECFailure;
-+ goto done;
-+ }
-+ /* The sequence number has the high 16 bits as the epoch. */
-+ pwSpec->epoch = cwSpec->epoch + 1;
-+ pwSpec->read_seq_num.high = pwSpec->write_seq_num.high =
-+ pwSpec->epoch << 16;
-+
-+ dtls_InitRecvdRecords(&pwSpec->recvdRecords);
-+ }
-+ pwSpec->read_seq_num.low = pwSpec->write_seq_num.low = 0;
-+
- done:
- ssl_ReleaseSpecWriteLock(ss); /******************************/
- if (rv != SECSuccess)
-@@ -1834,6 +1855,7 @@
- ssl3_ComputeRecordMAC(
- ssl3CipherSpec * spec,
- PRBool useServerMacKey,
-+ PRBool isDTLS,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num,
-@@ -1871,8 +1893,16 @@
- isTLS = PR_FALSE;
- } else {
- /* New TLS hash includes version. */
-- temp[9] = MSB(version);
-- temp[10] = LSB(version);
-+ if (isDTLS) {
-+ SSL3ProtocolVersion dtls_version;
-+
-+ dtls_version = dtls_TLSVersionToDTLSVersion(version);
-+ temp[9] = MSB(dtls_version);
-+ temp[10] = LSB(dtls_version);
-+ } else {
-+ temp[9] = MSB(version);
-+ temp[10] = LSB(version);
-+ }
- temp[11] = MSB(inputLength);
- temp[12] = LSB(inputLength);
- tempLen = 13;
-@@ -2022,9 +2052,10 @@
- }
-
- /* Caller must hold the spec read lock. */
--static SECStatus
-+SECStatus
- ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
- PRBool isServer,
-+ PRBool isDTLS,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen,
-@@ -2035,10 +2066,12 @@
- PRUint32 macLen = 0;
- PRUint32 fragLen;
- PRUint32 p1Len, p2Len, oddLen = 0;
-+ PRUint16 headerLen;
- int ivLen = 0;
- int cipherBytes = 0;
-
- cipher_def = cwSpec->cipher_def;
-+ headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
-
- if (cipher_def->type == type_block &&
- cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
-@@ -2048,20 +2081,20 @@
- * record.
- */
- ivLen = cipher_def->iv_size;
-- if (ivLen > wrBuf->space - SSL3_RECORD_HEADER_LENGTH) {
-+ if (ivLen > wrBuf->space - headerLen) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-- rv = PK11_GenerateRandom(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, ivLen);
-+ rv = PK11_GenerateRandom(wrBuf->buf + headerLen, ivLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- return rv;
- }
- rv = cwSpec->encode( cwSpec->encodeContext,
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH,
-+ wrBuf->buf + headerLen,
- &cipherBytes, /* output and actual outLen */
- ivLen, /* max outlen */
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH,
-+ wrBuf->buf + headerLen,
- ivLen); /* input and inputLen*/
- if (rv != SECSuccess || cipherBytes != ivLen) {
- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
-@@ -2073,20 +2106,20 @@
- int outlen;
- rv = cwSpec->compressor(
- cwSpec->compressContext,
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen, &outlen,
-- wrBuf->space - SSL3_RECORD_HEADER_LENGTH - ivLen, pIn, contentLen);
-+ wrBuf->buf + headerLen + ivLen, &outlen,
-+ wrBuf->space - headerLen - ivLen, pIn, contentLen);
- if (rv != SECSuccess)
- return rv;
-- pIn = wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen;
-+ pIn = wrBuf->buf + headerLen + ivLen;
- contentLen = outlen;
- }
-
- /*
- * Add the MAC
- */
-- rv = ssl3_ComputeRecordMAC( cwSpec, isServer,
-+ rv = ssl3_ComputeRecordMAC( cwSpec, isServer, isDTLS,
- type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + contentLen, &macLen);
-+ wrBuf->buf + headerLen + ivLen + contentLen, &macLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- return SECFailure;
-@@ -2113,7 +2146,7 @@
- PORT_Assert((fragLen % cipher_def->block_size) == 0);
-
- /* Pad according to TLS rules (also acceptable to SSL3). */
-- pBuf = &wrBuf->buf[SSL3_RECORD_HEADER_LENGTH + ivLen + fragLen - 1];
-+ pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1];
- for (i = padding_length + 1; i > 0; --i) {
- *pBuf-- = padding_length;
- }
-@@ -2130,13 +2163,12 @@
- p2Len += oddLen;
- PORT_Assert( (cipher_def->block_size < 2) || \
- (p2Len % cipher_def->block_size) == 0);
-- memmove(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + p1Len,
-- pIn + p1Len, oddLen);
-+ memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len, oddLen);
- }
- if (p1Len > 0) {
- int cipherBytesPart1 = -1;
- rv = cwSpec->encode( cwSpec->encodeContext,
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen, /* output */
-+ wrBuf->buf + headerLen + ivLen, /* output */
- &cipherBytesPart1, /* actual outlen */
- p1Len, /* max outlen */
- pIn, p1Len); /* input, and inputlen */
-@@ -2150,10 +2182,10 @@
- if (p2Len > 0) {
- int cipherBytesPart2 = -1;
- rv = cwSpec->encode( cwSpec->encodeContext,
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + p1Len,
-+ wrBuf->buf + headerLen + ivLen + p1Len,
- &cipherBytesPart2, /* output and actual outLen */
- p2Len, /* max outlen */
-- wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + p1Len,
-+ wrBuf->buf + headerLen + ivLen + p1Len,
- p2Len); /* input and inputLen*/
- PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len);
- if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) {
-@@ -2164,15 +2196,33 @@
- }
- PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
-
-+ wrBuf->len = cipherBytes + headerLen;
-+ wrBuf->buf[0] = type;
-+ if (isDTLS) {
-+ SSL3ProtocolVersion version;
-+
-+ version = dtls_TLSVersionToDTLSVersion(cwSpec->version);
-+ wrBuf->buf[1] = MSB(version);
-+ wrBuf->buf[2] = LSB(version);
-+ wrBuf->buf[3] = (unsigned char)(cwSpec->write_seq_num.high >> 24);
-+ wrBuf->buf[4] = (unsigned char)(cwSpec->write_seq_num.high >> 16);
-+ wrBuf->buf[5] = (unsigned char)(cwSpec->write_seq_num.high >> 8);
-+ wrBuf->buf[6] = (unsigned char)(cwSpec->write_seq_num.high >> 0);
-+ wrBuf->buf[7] = (unsigned char)(cwSpec->write_seq_num.low >> 24);
-+ wrBuf->buf[8] = (unsigned char)(cwSpec->write_seq_num.low >> 16);
-+ wrBuf->buf[9] = (unsigned char)(cwSpec->write_seq_num.low >> 8);
-+ wrBuf->buf[10] = (unsigned char)(cwSpec->write_seq_num.low >> 0);
-+ wrBuf->buf[11] = MSB(cipherBytes);
-+ wrBuf->buf[12] = LSB(cipherBytes);
-+ } else {
-+ wrBuf->buf[1] = MSB(cwSpec->version);
-+ wrBuf->buf[2] = LSB(cwSpec->version);
-+ wrBuf->buf[3] = MSB(cipherBytes);
-+ wrBuf->buf[4] = LSB(cipherBytes);
-+ }
-+
- ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
-
-- wrBuf->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
-- wrBuf->buf[0] = type;
-- wrBuf->buf[1] = MSB(cwSpec->version);
-- wrBuf->buf[2] = LSB(cwSpec->version);
-- wrBuf->buf[3] = MSB(cipherBytes);
-- wrBuf->buf[4] = LSB(cipherBytes);
--
- return SECSuccess;
- }
-
-@@ -2194,10 +2244,13 @@
- * ssl_SEND_FLAG_FORCE_INTO_BUFFER
- * As above, except this suppresses all write attempts, and forces
- * all ciphertext into the pending ciphertext buffer.
-+ * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
-+ * Forces the use of the provided epoch
- *
- */
--static PRInt32
-+PRInt32
- ssl3_SendRecord( sslSocket * ss,
-+ DTLSEpoch epoch, /* DTLS only */
- SSL3ContentType type,
- const SSL3Opaque * pIn, /* input buffer */
- PRInt32 nIn, /* bytes of input */
-@@ -2269,8 +2322,8 @@
- sslBuffer secondRecord;
-
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
-- ss->sec.isServer, type, pIn, 1,
-- wrBuf);
-+ ss->sec.isServer, IS_DTLS(ss),
-+ type, pIn, 1, wrBuf);
- if (rv != SECSuccess)
- goto spec_locked_loser;
-
-@@ -2282,17 +2335,28 @@
- secondRecord.space = wrBuf->space - wrBuf->len;
-
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
-- ss->sec.isServer, type, pIn + 1,
-- contentLen - 1, &secondRecord);
-+ ss->sec.isServer, IS_DTLS(ss),
-+ type, pIn + 1, contentLen - 1,
-+ &secondRecord);
- if (rv == SECSuccess) {
- PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
- secondRecord.buf, secondRecord.len));
- wrBuf->len += secondRecord.len;
- }
- } else {
-- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
-- ss->sec.isServer, type, pIn,
-- contentLen, wrBuf);
-+ if (!IS_DTLS(ss)) {
-+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
-+ ss->sec.isServer,
-+ IS_DTLS(ss),
-+ type, pIn,
-+ contentLen, wrBuf);
-+ } else {
-+ rv = dtls_CompressMACEncryptRecord(ss, epoch,
-+ !!(flags & ssl_SEND_FLAG_USE_EPOCH),
-+ type, pIn,
-+ contentLen, wrBuf);
-+ }
-+
- if (rv == SECSuccess) {
- PRINT_BUF(50, (ss, "send (encrypted) record data:",
- wrBuf->buf, wrBuf->len));
-@@ -2350,6 +2414,11 @@
- }
- wrBuf->len -= sent;
- if (wrBuf->len) {
-+ if (IS_DTLS(ss)) {
-+ /* DTLS just says no in this case. No buffering */
-+ PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
-+ return SECFailure;
-+ }
- /* now take all the remaining unsent new ciphertext and
- * append it to the buffer of previously unsent ciphertext.
- */
-@@ -2378,6 +2447,9 @@
- PRInt32 discarded = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-+ /* These flags for internal use only */
-+ PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH |
-+ ssl_SEND_FLAG_NO_RETRANSMIT)));
- if (len < 0 || !in) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
-@@ -2415,7 +2487,11 @@
- ssl_GetXmitBufLock(ss);
- }
- toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
-- sent = ssl3_SendRecord(ss, content_application_data,
-+ /*
-+ * Note that the 0 epoch is OK because flags will never require
-+ * its use, as guaranteed by the PORT_Assert above.
-+ */
-+ sent = ssl3_SendRecord(ss, 0, content_application_data,
- in + totalSent, toSend, flags);
- if (sent < 0) {
- if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) {
-@@ -2450,10 +2526,15 @@
- return totalSent + discarded;
- }
-
--/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
-+/* Attempt to send buffered handshake messages.
- * This function returns SECSuccess or SECFailure, never SECWouldBlock.
- * Always set sendBuf.len to 0, even when returning SECFailure.
- *
-+ * Depending on whether we are doing DTLS or not, this either calls
-+ *
-+ * - ssl3_FlushHandshakeMessages if non-DTLS
-+ * - dtls_FlushHandshakeMessages if DTLS
-+ *
- * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(),
- * ssl3_AppendHandshake(), ssl3_SendClientHello(),
- * ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
-@@ -2462,6 +2543,22 @@
- static SECStatus
- ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
- {
-+ if (IS_DTLS(ss)) {
-+ return dtls_FlushHandshakeMessages(ss, flags);
-+ } else {
-+ return ssl3_FlushHandshakeMessages(ss, flags);
-+ }
-+}
-+
-+/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
-+ * This function returns SECSuccess or SECFailure, never SECWouldBlock.
-+ * Always set sendBuf.len to 0, even when returning SECFailure.
-+ *
-+ * Called from ssl3_FlushHandshake
-+ */
-+static SECStatus
-+ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
-+{
- PRInt32 rv = SECSuccess;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-@@ -2476,7 +2573,7 @@
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
-- rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf,
-+ rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
- ss->sec.ci.sendBuf.len, flags);
- }
- if (rv < 0) {
-@@ -2593,7 +2690,7 @@
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv == SECSuccess) {
- PRInt32 sent;
-- sent = ssl3_SendRecord(ss, content_alert, bytes, 2,
-+ sent = ssl3_SendRecord(ss, 0, content_alert, bytes, 2,
- desc == no_certificate
- ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-@@ -2667,7 +2764,7 @@
- /*
- * Send handshake_Failure alert. Set generic error number.
- */
--static SECStatus
-+SECStatus
- ssl3_DecodeError(sslSocket *ss)
- {
- (void)SSL3_SendAlert(ss, alert_fatal,
-@@ -2755,7 +2852,8 @@
- default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
- }
- if (level == alert_fatal) {
-- ss->sec.uncache(ss->sec.ci.sid);
-+ if (!ss->opt.noCache)
-+ ss->sec.uncache(ss->sec.ci.sid);
- if ((ss->ssl3.hs.ws == wait_server_hello) &&
- (desc == handshake_failure)) {
- /* XXX This is a hack. We're assuming that any handshake failure
-@@ -2806,17 +2904,22 @@
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
-- sent = ssl3_SendRecord(ss, content_change_cipher_spec, &change, 1,
-- ssl_SEND_FLAG_FORCE_INTO_BUFFER);
-- if (sent < 0) {
-- return (SECStatus)sent; /* error code set by ssl3_SendRecord */
-+ if (!IS_DTLS(ss)) {
-+ sent = ssl3_SendRecord(ss, 0, content_change_cipher_spec, &change, 1,
-+ ssl_SEND_FLAG_FORCE_INTO_BUFFER);
-+ if (sent < 0) {
-+ return (SECStatus)sent; /* error code set by ssl3_SendRecord */
-+ }
-+ } else {
-+ rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1);
-+ if (rv != SECSuccess) {
-+ return rv;
-+ }
- }
-
- /* swap the pending and current write specs. */
- ssl_GetSpecWriteLock(ss); /**************************************/
- pwSpec = ss->ssl3.pwSpec;
-- pwSpec->write_seq_num.high = 0;
-- pwSpec->write_seq_num.low = 0;
-
- ss->ssl3.pwSpec = ss->ssl3.cwSpec;
- ss->ssl3.cwSpec = pwSpec;
-@@ -2829,7 +2932,14 @@
- * (Both the read and write sides have changed) destroy it.
- */
- if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
-- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE/*freeSrvName*/);
-+ if (!IS_DTLS(ss)) {
-+ ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE/*freeSrvName*/);
-+ } else {
-+ /* With DTLS, we need to set a holddown timer in case the final
-+ * message got lost */
-+ ss->ssl3.hs.rtTimeoutMs = DTLS_FINISHED_TIMER_MS;
-+ dtls_StartTimer(ss, dtls_FinishedTimerCb);
-+ }
- }
- ssl_ReleaseSpecWriteLock(ss); /**************************************/
-
-@@ -2878,7 +2988,6 @@
- /* Swap the pending and current read specs. */
- ssl_GetSpecWriteLock(ss); /*************************************/
- prSpec = ss->ssl3.prSpec;
-- prSpec->read_seq_num.high = prSpec->read_seq_num.low = 0;
-
- ss->ssl3.prSpec = ss->ssl3.crSpec;
- ss->ssl3.crSpec = prSpec;
-@@ -2981,6 +3090,11 @@
- if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
- SSL3ProtocolVersion client_version;
- client_version = pms_version.major << 8 | pms_version.minor;
-+
-+ if (IS_DTLS(ss)) {
-+ client_version = dtls_DTLSVersionToTLSVersion(client_version);
-+ }
-+
- if (client_version != ss->clientHelloVersion) {
- /* Destroy it. Version roll-back detected. */
- PK11_FreeSymKey(pwSpec->master_secret);
-@@ -3405,6 +3519,17 @@
- {
- SECStatus rv;
-
-+ /* If we already have a message in place, we need to enqueue it.
-+ * This empties the buffer. This is a convenient place to call
-+ * dtls_StageHandshakeMessage to mark the message boundary.
-+ */
-+ if (IS_DTLS(ss)) {
-+ rv = dtls_StageHandshakeMessage(ss);
-+ if (rv != SECSuccess) {
-+ return rv;
-+ }
-+ }
-+
- SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
- SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
- PRINT_BUF(60, (ss, "MD5 handshake hash:",
-@@ -3417,6 +3542,32 @@
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, length, 3);
-+ if (rv != SECSuccess) {
-+ return rv; /* error code set by AppendHandshake, if applicable. */
-+ }
-+
-+ if (IS_DTLS(ss)) {
-+ /* Note that we make an unfragmented message here. We fragment in the
-+ * transmission code, if necessary */
-+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.sendMessageSeq, 2);
-+ if (rv != SECSuccess) {
-+ return rv; /* error code set by AppendHandshake, if applicable. */
-+ }
-+ ss->ssl3.hs.sendMessageSeq++;
-+
-+ /* 0 is the fragment offset, because it's not fragmented yet */
-+ rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
-+ if (rv != SECSuccess) {
-+ return rv; /* error code set by AppendHandshake, if applicable. */
-+ }
-+
-+ /* Fragment length -- set to the packet length because not fragmented */
-+ rv = ssl3_AppendHandshakeNumber(ss, length, 3);
-+ if (rv != SECSuccess) {
-+ return rv; /* error code set by AppendHandshake, if applicable. */
-+ }
-+ }
-+
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
-
-@@ -3823,9 +3974,10 @@
- /* Called from ssl3_HandleHelloRequest(),
- * ssl3_RedoHandshake()
- * ssl2_BeginClientHandshake (when resuming ssl3 session)
-+ * dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
- */
- SECStatus
--ssl3_SendClientHello(sslSocket *ss)
-+ssl3_SendClientHello(sslSocket *ss, PRBool resending)
- {
- sslSessionID * sid;
- ssl3CipherSpec * cwSpec;
-@@ -3849,6 +4001,7 @@
- return rv; /* ssl3_InitState has set the error code. */
- }
- ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
-+ PORT_Assert(IS_DTLS(ss) || !resending);
-
- /* We might be starting a session renegotiation in which case we should
- * clear previous state.
-@@ -4008,6 +4161,10 @@
- }
- #endif
-
-+ if (IS_DTLS(ss)) {
-+ ssl3_DisableNonDTLSSuites(ss);
-+ }
-+
- /* how many suites are permitted by policy and user preference? */
- num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
- if (!num_suites)
-@@ -4027,6 +4184,9 @@
- 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
- 2 + num_suites*sizeof(ssl3CipherSuite) +
- 1 + numCompressionMethods + total_exten_len;
-+ if (IS_DTLS(ss)) {
-+ length += 1 + ss->ssl3.hs.cookieLen;
-+ }
-
- rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
- if (rv != SECSuccess) {
-@@ -4034,13 +4194,23 @@
- }
-
- ss->clientHelloVersion = ss->version;
-- rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
-+ if (IS_DTLS(ss)) {
-+ PRUint16 version;
-+
-+ version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
-+ rv = ssl3_AppendHandshakeNumber(ss, version, 2);
-+ } else {
-+ rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
-+ }
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-- rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
-- if (rv != SECSuccess) {
-- return rv; /* err set by GetNewRandom. */
-+
-+ if (!resending) { /* Don't re-generate if we are in DTLS re-sending mode */
-+ rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by GetNewRandom. */
-+ }
- }
- rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
- SSL3_RANDOM_LENGTH);
-@@ -4057,6 +4227,14 @@
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
-+ if (IS_DTLS(ss)) {
-+ rv = ssl3_AppendHandshakeVariable(
-+ ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1);
-+ if (rv != SECSuccess) {
-+ return rv; /* err set by ssl3_AppendHandshake* */
-+ }
-+ }
-+
- rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
-@@ -4180,8 +4358,12 @@
- ss->sec.ci.sid = NULL;
- }
-
-+ if (IS_DTLS(ss)) {
-+ dtls_RehandshakeCleanup(ss);
-+ }
-+
- ssl_GetXmitBufLock(ss);
-- rv = ssl3_SendClientHello(ss);
-+ rv = ssl3_SendClientHello(ss, PR_FALSE);
- ssl_ReleaseXmitBufLock(ss);
-
- return rv;
-@@ -5036,6 +5218,23 @@
- }
- version = (SSL3ProtocolVersion)temp;
-
-+ if (IS_DTLS(ss)) {
-+ /* RFC 4347 required that you verify that the server versions
-+ * match (Section 4.2.1) in the HelloVerifyRequest and the
-+ * ServerHello.
-+ *
-+ * RFC 6347 suggests (SHOULD) that servers always use 1.0
-+ * in HelloVerifyRequest and allows the versions not to match,
-+ * especially when 1.2 is being negotiated.
-+ *
-+ * Therefore we do not check for matching here.
-+ */
-+ version = dtls_DTLSVersionToTLSVersion(version);
-+ if (version == 0) { /* Insane version number */
-+ goto alert_loser;
-+ }
-+ }
-+
- rv = ssl3_NegotiateVersion(ss, version, PR_FALSE);
- if (rv != SECSuccess) {
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
-@@ -6264,6 +6463,7 @@
- SSL3AlertLevel level = alert_fatal;
- SSL3ProtocolVersion version;
- SECItem sidBytes = {siBuffer, NULL, 0};
-+ SECItem cookieBytes = {siBuffer, NULL, 0};
- SECItem suites = {siBuffer, NULL, 0};
- SECItem comps = {siBuffer, NULL, 0};
- PRBool haveSpecWriteLock = PR_FALSE;
-@@ -6281,6 +6481,20 @@
- return rv; /* error code is set. */
- }
-
-+ /* Clearing the handshake pointers so that ssl_Do1stHandshake won't
-+ * call ssl2_HandleMessage.
-+ *
-+ * The issue here is that TLS ordinarily starts out in
-+ * ssl2_HandleV3HandshakeRecord() because of the backward-compatibility
-+ * code paths. That function zeroes these next pointers. But with DTLS,
-+ * we don't even try to do the v2 ClientHello so we skip that function
-+ * and need to reset these values here.
-+ */
-+ if (IS_DTLS(ss)) {
-+ ss->nextHandshake = 0;
-+ ss->securityHandshake = 0;
-+ }
-+
- /* We might be starting session renegotiation in which case we should
- * clear previous state.
- */
-@@ -6306,10 +6520,22 @@
- goto alert_loser;
- }
-
-+ if (IS_DTLS(ss)) {
-+ dtls_RehandshakeCleanup(ss);
-+ }
-+
- tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (tmp < 0)
- goto loser; /* malformed, alert already sent */
-- ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
-+
-+ /* Translate the version */
-+ if (IS_DTLS(ss)) {
-+ ss->clientHelloVersion = version =
-+ dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
-+ } else {
-+ ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
-+ }
-+
- rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
- if (rv != SECSuccess) {
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
-@@ -6331,6 +6557,14 @@
- goto loser; /* malformed */
- }
-
-+ /* grab the client's cookie, if present. */
-+ if (IS_DTLS(ss)) {
-+ rv = ssl3_ConsumeHandshakeVariable(ss, &cookieBytes, 1, &b, &length);
-+ if (rv != SECSuccess) {
-+ goto loser; /* malformed */
-+ }
-+ }
-+
- /* grab the list of cipher suites. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
- if (rv != SECSuccess) {
-@@ -6479,6 +6713,10 @@
- ssl3_FilterECCipherSuitesByServerCerts(ss);
- #endif
-
-+ if (IS_DTLS(ss)) {
-+ ssl3_DisableNonDTLSSuites(ss);
-+ }
-+
- #ifdef PARANOID
- /* Look for a matching cipher suite. */
- j = ssl3_config_match_init(ss);
-@@ -7166,17 +7404,28 @@
- PRUint32 maxBytes = 65535;
- PRUint32 length;
- PRInt32 extensions_len = 0;
-+ SSL3ProtocolVersion version;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-- PORT_Assert( MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
-
-- if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
-- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-- return SECFailure;
-+ if (!IS_DTLS(ss)) {
-+ PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
-+
-+ if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
-+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-+ return SECFailure;
-+ }
-+ } else {
-+ PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_DTLS_1_0));
-+
-+ if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_DTLS_1_0)) {
-+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-+ return SECFailure;
-+ }
- }
-
- sid = ss->sec.ci.sid;
-@@ -7194,7 +7443,13 @@
- return rv; /* err set by AppendHandshake. */
- }
-
-- rv = ssl3_AppendHandshakeNumber(ss, ss->version, 2);
-+ if (IS_DTLS(ss)) {
-+ version = dtls_TLSVersionToDTLSVersion(ss->version);
-+ } else {
-+ version = ss->version;
-+ }
-+
-+ rv = ssl3_AppendHandshakeNumber(ss, version, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-@@ -7379,11 +7634,8 @@
- nnames = ca_list->nnames;
- }
-
-- if (!nnames) {
-- PORT_SetError(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA);
-- return SECFailure;
-- }
--
-+ /* There used to be a test here to require a CA, but there
-+ * are cases where you want to have no CAs offered. */
- for (i = 0, name = names; i < nnames; i++, name++) {
- calen += 2 + name->len;
- }
-@@ -7551,9 +7803,17 @@
- }
-
- /* Generate the pre-master secret ... */
-- version.major = MSB(ss->clientHelloVersion);
-- version.minor = LSB(ss->clientHelloVersion);
-+ if (IS_DTLS(ss)) {
-+ SSL3ProtocolVersion temp;
-
-+ temp = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
-+ version.major = MSB(temp);
-+ version.minor = LSB(temp);
-+ } else {
-+ version.major = MSB(ss->clientHelloVersion);
-+ version.minor = LSB(ss->clientHelloVersion);
-+ }
-+
- param.data = (unsigned char *)&version;
- param.len = sizeof version;
-
-@@ -7635,6 +7895,11 @@
- } else if (ss->opt.detectRollBack) {
- SSL3ProtocolVersion client_version =
- (rsaPmsBuf[0] << 8) | rsaPmsBuf[1];
-+
-+ if (IS_DTLS(ss)) {
-+ client_version = dtls_DTLSVersionToTLSVersion(client_version);
-+ }
-+
- if (client_version != ss->clientHelloVersion) {
- /* Version roll-back detected. ensure failure. */
- rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
-@@ -8851,6 +9116,10 @@
- }
- }
-
-+ if (IS_DTLS(ss)) {
-+ flags |= ssl_SEND_FLAG_NO_RETRANSMIT;
-+ }
-+
- rv = ssl3_SendFinished(ss, flags);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err is set. */
-@@ -8980,13 +9249,14 @@
- * hanshake message.
- * Caller must hold Handshake and RecvBuf locks.
- */
--static SECStatus
-+SECStatus
- ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- {
- SECStatus rv = SECSuccess;
- SSL3HandshakeType type = ss->ssl3.hs.msg_type;
- SSL3Hashes hashes; /* computed hashes are put here. */
- PRUint8 hdr[4];
-+ PRUint8 dtlsData[8];
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-@@ -9032,10 +9302,35 @@
- 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 and hello_verify_request messages
-+ * in the handshake hashes */
-+ if ((ss->ssl3.hs.msg_type != hello_request) &&
-+ (ss->ssl3.hs.msg_type != hello_verify_request)) {
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
- if (rv != SECSuccess) return rv; /* err code already set. */
-+
-+ /* Extra data to simulate a complete DTLS handshake fragment */
-+ if (IS_DTLS(ss)) {
-+ /* Sequence number */
-+ dtlsData[0] = MSB(ss->ssl3.hs.recvMessageSeq);
-+ dtlsData[1] = LSB(ss->ssl3.hs.recvMessageSeq);
-+
-+ /* Fragment offset */
-+ dtlsData[2] = 0;
-+ dtlsData[3] = 0;
-+ dtlsData[4] = 0;
-+
-+ /* Fragment length */
-+ dtlsData[5] = (PRUint8)(length >> 16);
-+ dtlsData[6] = (PRUint8)(length >> 8);
-+ dtlsData[7] = (PRUint8)(length );
-+
-+ rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) dtlsData,
-+ sizeof(dtlsData));
-+ if (rv != SECSuccess) return rv; /* err code already set. */
-+ }
-+
-+ /* The message body */
- rv = ssl3_UpdateHandshakeHashes(ss, b, length);
- if (rv != SECSuccess) return rv; /* err code already set. */
- }
-@@ -9071,6 +9366,14 @@
- }
- rv = ssl3_HandleServerHello(ss, b, length);
- break;
-+ case hello_verify_request:
-+ if (!IS_DTLS(ss) || ss->sec.isServer) {
-+ (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
-+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST);
-+ return SECFailure;
-+ }
-+ rv = dtls_HandleHelloVerifyRequest(ss, b, length);
-+ break;
- case certificate:
- if (ss->ssl3.hs.may_get_cert_status) {
- /* If we might get a CertificateStatus then we want to postpone the
-@@ -9169,6 +9472,12 @@
- PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
- rv = SECFailure;
- }
-+
-+ if (IS_DTLS(ss) && (rv == SECSuccess)) {
-+ /* Increment the expected sequence number */
-+ ss->ssl3.hs.recvMessageSeq++;
-+ }
-+
- return rv;
- }
-
-@@ -9331,6 +9640,7 @@
- SSL3Opaque hash[MAX_MAC_LENGTH];
- sslBuffer *plaintext;
- sslBuffer temp_buf;
-+ PRUint64 dtls_seq_num;
- unsigned int ivLen = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-@@ -9366,6 +9676,39 @@
- crSpec = ss->ssl3.crSpec;
- cipher_def = crSpec->cipher_def;
-
-+ /*
-+ * DTLS relevance checks:
-+ * Note that this code currently ignores all out-of-epoch packets,
-+ * which means we lose some in the case of rehandshake +
-+ * loss/reordering. Since DTLS is explicitly unreliable, this
-+ * seems like a good tradeoff for implementation effort and is
-+ * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1
-+ */
-+ if (IS_DTLS(ss)) {
-+ DTLSEpoch epoch = (cText->seq_num.high >> 16) & 0xffff;
-+
-+ if (crSpec->epoch != epoch) {
-+ ssl_ReleaseSpecReadLock(ss);
-+ SSL_DBG(("%d: SSL3[%d]: HandleRecord, received packet "
-+ "from irrelevant epoch %d", SSL_GETPID(), ss->fd, epoch));
-+ /* Silently drop the packet */
-+ databuf->len = 0; /* Needed to ensure data not left around */
-+ return SECSuccess;
-+ }
-+
-+ dtls_seq_num = (((PRUint64)(cText->seq_num.high & 0xffff)) << 32) |
-+ ((PRUint64)cText->seq_num.low);
-+
-+ if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
-+ ssl_ReleaseSpecReadLock(ss);
-+ SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
-+ "potentially replayed packet", SSL_GETPID(), ss->fd));
-+ /* Silently drop the packet */
-+ databuf->len = 0; /* Needed to ensure data not left around */
-+ return SECSuccess;
-+ }
-+ }
-+
- if (cipher_def->type == type_block &&
- crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
-@@ -9487,7 +9830,8 @@
- /* compute the MAC */
- rType = cText->type;
- rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer),
-- rType, cText->version, crSpec->read_seq_num,
-+ IS_DTLS(ss), rType, cText->version,
-+ IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
- plaintext->buf, plaintext->len, hash, &hashBytes);
- if (rv != SECSuccess) {
- padIsBad = PR_TRUE; /* really macIsBad */
-@@ -9499,19 +9843,27 @@
- crSpec->mac_size) != 0) {
- /* must not hold spec lock when calling SSL3_SendAlert. */
- ssl_ReleaseSpecReadLock(ss);
-- SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
-- /* always log mac error, in case attacker can read server logs. */
-- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
-
- SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
-
-- return SECFailure;
-+ if (!IS_DTLS(ss)) {
-+ SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
-+ /* always log mac error, in case attacker can read server logs. */
-+ PORT_SetError(SSL_ERROR_BAD_MAC_READ);
-+ return SECFailure;
-+ } else {
-+ /* Silently drop the packet */
-+ databuf->len = 0; /* Needed to ensure data not left around */
-+ return SECSuccess;
-+ }
- }
-
-+ if (!IS_DTLS(ss)) {
-+ ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
-+ } else {
-+ dtls_RecordSetRecvd(&crSpec->recvdRecords, dtls_seq_num);
-+ }
-
--
-- ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
--
- ssl_ReleaseSpecReadLock(ss); /*****************************************/
-
- /*
-@@ -9615,7 +9967,11 @@
- rv = ssl3_HandleAlert(ss, databuf);
- break;
- case content_handshake:
-- rv = ssl3_HandleHandshake(ss, databuf);
-+ if (!IS_DTLS(ss)) {
-+ rv = ssl3_HandleHandshake(ss, databuf);
-+ } else {
-+ rv = dtls_HandleHandshake(ss, databuf);
-+ }
- break;
- /*
- case content_application_data is handled before this switch
-@@ -9675,6 +10031,9 @@
- spec->read_seq_num.high = 0;
- spec->read_seq_num.low = 0;
-
-+ spec->epoch = 0;
-+ dtls_InitRecvdRecords(&spec->recvdRecords);
-+
- spec->version = ss->vrange.max;
- }
-
-@@ -9716,6 +10075,21 @@
-
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
-
-+ if (IS_DTLS(ss)) {
-+ ss->ssl3.hs.sendMessageSeq = 0;
-+ ss->ssl3.hs.recvMessageSeq = 0;
-+ ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
-+ ss->ssl3.hs.rtRetries = 0;
-+
-+ /* Have to allocate this because ssl_FreeSocket relocates
-+ * this structure in DEBUG mode */
-+ if (!(ss->ssl3.hs.lastMessageFlight = PORT_New(PRCList)))
-+ return SECFailure;
-+ ss->ssl3.hs.recvdHighWater = -1;
-+ PR_INIT_CLIST(ss->ssl3.hs.lastMessageFlight);
-+ dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
-+ }
-+
- rv = ssl3_NewHandshakeHashes(ss);
- if (rv == SECSuccess) {
- ss->ssl3.initialized = PR_TRUE;
-@@ -9968,6 +10342,11 @@
- PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
- return SECFailure;
- }
-+
-+ if (IS_DTLS(ss)) {
-+ dtls_RehandshakeCleanup(ss);
-+ }
-+
- if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
- PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
- return SECFailure;
-@@ -9982,7 +10361,7 @@
-
- /* start off a new handshake. */
- rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss)
-- : ssl3_SendClientHello(ss);
-+ : ssl3_SendClientHello(ss, PR_FALSE);
-
- ssl_ReleaseXmitBufLock(ss); /**************************************/
- return rv;
-@@ -10042,6 +10421,17 @@
- ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/);
- ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
-
-+ /* Destroy the DTLS data */
-+ if (IS_DTLS(ss)) {
-+ if (ss->ssl3.hs.lastMessageFlight) {
-+ dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
-+ PORT_Free(ss->ssl3.hs.lastMessageFlight);
-+ }
-+ if (ss->ssl3.hs.recvdFragments.buf) {
-+ PORT_Free(ss->ssl3.hs.recvdFragments.buf);
-+ }
-+ }
-+
- ss->ssl3.initialized = PR_FALSE;
-
- SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
-Index: net/third_party/nss/ssl/sslgathr.c
-===================================================================
---- net/third_party/nss/ssl/sslgathr.c (revision 127709)
-+++ net/third_party/nss/ssl/sslgathr.c (working copy)
-@@ -434,6 +434,8 @@
- gs->state = GS_INIT;
- gs->writeOffset = 0;
- gs->readOffset = 0;
-+ gs->dtlsPacketOffset = 0;
-+ gs->dtlsPacket.len = 0;
- status = sslBuffer_Grow(&gs->buf, 4096);
- return status;
- }
-@@ -445,6 +447,7 @@
- if (gs) { /* the PORT_*Free functions check for NULL pointers. */
- PORT_ZFree(gs->buf.buf, gs->buf.space);
- PORT_Free(gs->inbuf.buf);
-+ PORT_Free(gs->dtlsPacket.buf);
- }
- }
-
-Index: net/third_party/nss/ssl/dtls1con.c
-===================================================================
---- net/third_party/nss/ssl/dtls1con.c (revision 0)
-+++ net/third_party/nss/ssl/dtls1con.c (revision 0)
-@@ -0,0 +1,1164 @@
-+/*
-+ * DTLS Protocol
-+ *
-+ * ***** 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):
-+ * Eric Rescorla <ekr@rtfm.com>
-+ *
-+ * 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: $ */
-+
-+#include "ssl.h"
-+#include "sslimpl.h"
-+#include "sslproto.h"
-+
-+#ifndef PR_ARRAY_SIZE
-+#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
-+#endif
-+
-+static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
-+static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
-+static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
-+
-+/* -28 adjusts for the IP/UDP header */
-+static const PRUint16 COMMON_MTU_VALUES[] = {
-+ 1500 - 28, /* Ethernet MTU */
-+ 1280 - 28, /* IPv6 minimum MTU */
-+ 576 - 28, /* Common assumption */
-+ 256 - 28 /* We're in serious trouble now */
-+};
-+
-+#define DTLS_COOKIE_BYTES 32
-+
-+/* List copied from ssl3con.c:cipherSuites */
-+static const ssl3CipherSuite nonDTLSSuites[] = {
-+#ifdef NSS_ENABLE_ECC
-+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
-+ TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-+#endif /* NSS_ENABLE_ECC */
-+ TLS_DHE_DSS_WITH_RC4_128_SHA,
-+#ifdef NSS_ENABLE_ECC
-+ TLS_ECDH_RSA_WITH_RC4_128_SHA,
-+ TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
-+#endif /* NSS_ENABLE_ECC */
-+ SSL_RSA_WITH_RC4_128_MD5,
-+ SSL_RSA_WITH_RC4_128_SHA,
-+ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
-+ SSL_RSA_EXPORT_WITH_RC4_40_MD5,
-+ 0 /* End of list marker */
-+};
-+
-+/* Map back and forth between TLS and DTLS versions in wire format.
-+ * Mapping table is:
-+ *
-+ * TLS DTLS
-+ * 1.1 (0302) 1.0 (feff)
-+ */
-+SSL3ProtocolVersion
-+dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
-+{
-+ /* Anything other than TLS 1.1 is an error, so return
-+ * the invalid version ffff. */
-+ if (tlsv != SSL_LIBRARY_VERSION_TLS_1_1)
-+ return 0xffff;
-+
-+ return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
-+}
-+
-+/* Map known DTLS versions to known TLS versions.
-+ * - Invalid versions (< 1.0) return a version of 0
-+ * - Versions > known return a version one higher than we know of
-+ * to accomodate a theoretically newer version */
-+SSL3ProtocolVersion
-+dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
-+{
-+ if (MSB(dtlsv) == 0xff) {
-+ return 0;
-+ }
-+
-+ if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE)
-+ return SSL_LIBRARY_VERSION_TLS_1_1;
-+
-+ /* Return a fictional higher version than we know of */
-+ return SSL_LIBRARY_VERSION_TLS_1_1 + 1;
-+}
-+
-+/* On this socket, Disable non-DTLS cipher suites in the argument's list */
-+SECStatus
-+ssl3_DisableNonDTLSSuites(sslSocket * ss)
-+{
-+ const ssl3CipherSuite * suite;
-+
-+ for (suite = nonDTLSSuites; *suite; ++suite) {
-+ SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
-+
-+ PORT_Assert(rv == SECSuccess); /* else is coding error */
-+ }
-+ return SECSuccess;
-+}
-+
-+/* Allocate a DTLSQueuedMessage.
-+ *
-+ * Called from dtls_QueueMessage()
-+ */
-+static DTLSQueuedMessage *
-+dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
-+ const unsigned char *data, PRUint32 len)
-+{
-+ DTLSQueuedMessage *msg = NULL;
-+
-+ msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage));
-+ if (!msg)
-+ return NULL;
-+
-+ msg->data = PORT_Alloc(len);
-+ if (!msg->data) {
-+ PORT_Free(msg);
-+ return NULL;
-+ }
-+ PORT_Memcpy(msg->data, data, len);
-+
-+ msg->len = len;
-+ msg->epoch = epoch;
-+ msg->type = type;
-+
-+ return msg;
-+}
-+
-+/*
-+ * Free a handshake message
-+ *
-+ * Called from dtls_FreeHandshakeMessages()
-+ */
-+static void
-+dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
-+{
-+ if (!msg)
-+ return;
-+
-+ PORT_ZFree(msg->data, msg->len);
-+ PORT_Free(msg);
-+}
-+
-+/*
-+ * Free a list of handshake messages
-+ *
-+ * Called from:
-+ * dtls_HandleHandshake()
-+ * ssl3_DestroySSL3Info()
-+ */
-+void
-+dtls_FreeHandshakeMessages(PRCList *list)
-+{
-+ PRCList *cur_p;
-+
-+ while (!PR_CLIST_IS_EMPTY(list)) {
-+ cur_p = PR_LIST_TAIL(list);
-+ PR_REMOVE_LINK(cur_p);
-+ dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
-+ }
-+}
-+
-+/* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record.
-+ * origBuf is the decrypted ssl record content and is expected to contain
-+ * complete handshake records
-+ * Caller must hold the handshake and RecvBuf locks.
-+ *
-+ * Note that this code uses msg_len for two purposes:
-+ *
-+ * (1) To pass the length to ssl3_HandleHandshakeMessage()
-+ * (2) To carry the length of a message currently being reassembled
-+ *
-+ * However, unlike ssl3_HandleHandshake(), it is not used to carry
-+ * the state of reassembly (i.e., whether one is in progress). That
-+ * is carried in recvdHighWater and recvdFragments.
-+ */
-+#define OFFSET_BYTE(o) (o/8)
-+#define OFFSET_MASK(o) (1 << (o%8))
-+
-+SECStatus
-+dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
-+{
-+ /* XXX OK for now.
-+ * This doesn't work properly with asynchronous certificate validation.
-+ * because that returns a WOULDBLOCK error. The current DTLS
-+ * applications do not need asynchronous validation, but in the
-+ * future we will need to add this.
-+ */
-+ sslBuffer buf = *origBuf;
-+ SECStatus rv = SECSuccess;
-+
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-+
-+ while (buf.len > 0) {
-+ PRUint8 type;
-+ PRUint32 message_length;
-+ PRUint16 message_seq;
-+ PRUint32 fragment_offset;
-+ PRUint32 fragment_length;
-+ PRUint32 offset;
-+
-+ if (buf.len < 12) {
-+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
-+ rv = SECFailure;
-+ break;
-+ }
-+
-+ /* Parse the header */
-+ type = buf.buf[0];
-+ message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
-+ message_seq = (buf.buf[4] << 8) | buf.buf[5];
-+ fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
-+ fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];
-+
-+#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
-+ if (message_length > MAX_HANDSHAKE_MSG_LEN) {
-+ (void)ssl3_DecodeError(ss);
-+ PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
-+ return SECFailure;
-+ }
-+#undef MAX_HANDSHAKE_MSG_LEN
-+
-+ buf.buf += 12;
-+ buf.len -= 12;
-+
-+ /* This fragment must be complete */
-+ if (buf.len < fragment_length) {
-+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
-+ rv = SECFailure;
-+ break;
-+ }
-+
-+ /* Sanity check the packet contents */
-+ if ((fragment_length + fragment_offset) > message_length) {
-+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
-+ rv = SECFailure;
-+ break;
-+ }
-+
-+ /* There are three ways we could not be ready for this packet.
-+ *
-+ * 1. It's a partial next message.
-+ * 2. It's a partial or complete message beyond the next
-+ * 3. It's a message we've already seen
-+ *
-+ * If it's the complete next message we accept it right away.
-+ * This is the common case for short messages
-+ */
-+ if ((message_seq == ss->ssl3.hs.recvMessageSeq)
-+ && (fragment_offset == 0)
-+ && (fragment_length == message_length)) {
-+ /* Complete next message. Process immediately */
-+ ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
-+ ss->ssl3.hs.msg_len = message_length;
-+
-+ /* At this point we are advancing our state machine, so
-+ * we can free our last flight of messages */
-+ dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
-+ ss->ssl3.hs.recvdHighWater = -1;
-+ dtls_CancelTimer(ss);
-+
-+ /* Reset the timer to the initial value if the retry counter
-+ * is 0, per Sec. 4.2.4.1 */
-+ if (ss->ssl3.hs.rtRetries == 0) {
-+ ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
-+ }
-+
-+ rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
-+ if (rv == SECFailure) {
-+ /* Do not attempt to process rest of messages in this record */
-+ break;
-+ }
-+ } else {
-+ if (message_seq < ss->ssl3.hs.recvMessageSeq) {
-+ /* Case 3: we do an immediate retransmit if we're
-+ * in a waiting state*/
-+ if (ss->ssl3.hs.rtTimerCb == NULL) {
-+ /* Ignore */
-+ } else if (ss->ssl3.hs.rtTimerCb ==
-+ dtls_RetransmitTimerExpiredCb) {
-+ SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
-+ SSL_GETPID(), ss->fd));
-+ /* Check to see if we retransmitted recently. If so,
-+ * suppress the triggered retransmit. This avoids
-+ * retransmit wars after packet loss.
-+ * This is not in RFC 5346 but should be
-+ */
-+ if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
-+ (ss->ssl3.hs.rtTimeoutMs / 4)) {
-+ SSL_TRC(30,
-+ ("%d: SSL3[%d]: Shortcutting retransmit timer",
-+ SSL_GETPID(), ss->fd));
-+
-+ /* Cancel the timer and call the CB,
-+ * which re-arms the timer */
-+ dtls_CancelTimer(ss);
-+ dtls_RetransmitTimerExpiredCb(ss);
-+ rv = SECSuccess;
-+ break;
-+ } else {
-+ SSL_TRC(30,
-+ ("%d: SSL3[%d]: We just retransmitted. Ignoring.",
-+ SSL_GETPID(), ss->fd));
-+ rv = SECSuccess;
-+ break;
-+ }
-+ } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
-+ /* Retransmit the messages and re-arm the timer
-+ * Note that we are not backing off the timer here.
-+ * The spec isn't clear and my reasoning is that this
-+ * may be a re-ordered packet rather than slowness,
-+ * so let's be aggressive. */
-+ dtls_CancelTimer(ss);
-+ rv = dtls_TransmitMessageFlight(ss);
-+ if (rv == SECSuccess) {
-+ rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
-+ }
-+ if (rv != SECSuccess)
-+ return rv;
-+ break;
-+ }
-+ } else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
-+ /* Case 2
-+ *
-+ * Ignore this message. This means we don't handle out of
-+ * order complete messages that well, but we're still
-+ * compliant and this probably does not happen often
-+ *
-+ * XXX OK for now. Maybe do something smarter at some point?
-+ */
-+ } else {
-+ /* Case 1
-+ *
-+ * Buffer the fragment for reassembly
-+ */
-+ /* Make room for the message */
-+ if (ss->ssl3.hs.recvdHighWater == -1) {
-+ PRUint32 map_length = OFFSET_BYTE(message_length) + 1;
-+
-+ rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length);
-+ if (rv != SECSuccess)
-+ break;
-+ /* Make room for the fragment map */
-+ rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
-+ map_length);
-+ if (rv != SECSuccess)
-+ break;
-+
-+ /* Reset the reassembly map */
-+ ss->ssl3.hs.recvdHighWater = 0;
-+ PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
-+ ss->ssl3.hs.recvdFragments.space);
-+ ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
-+ ss->ssl3.hs.msg_len = message_length;
-+ }
-+
-+ /* If we have a message length mismatch, abandon the reassembly
-+ * in progress and hope that the next retransmit will give us
-+ * something sane
-+ */
-+ if (message_length != ss->ssl3.hs.msg_len) {
-+ ss->ssl3.hs.recvdHighWater = -1;
-+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
-+ rv = SECFailure;
-+ break;
-+ }
-+
-+ /* Now copy this fragment into the buffer */
-+ PORT_Assert((fragment_offset + fragment_length) <=
-+ ss->ssl3.hs.msg_body.space);
-+ PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset,
-+ buf.buf, fragment_length);
-+
-+ /* This logic is a bit tricky. We have two values for
-+ * reassembly state:
-+ *
-+ * - recvdHighWater contains the highest contiguous number of
-+ * bytes received
-+ * - recvdFragments contains a bitmask of packets received
-+ * above recvdHighWater
-+ *
-+ * This avoids having to fill in the bitmask in the common
-+ * case of adjacent fragments received in sequence
-+ */
-+ if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
-+ /* Either this is the adjacent fragment or an overlapping
-+ * fragment */
-+ ss->ssl3.hs.recvdHighWater = fragment_offset +
-+ fragment_length;
-+ } else {
-+ for (offset = fragment_offset;
-+ offset < fragment_offset + fragment_length;
-+ offset++) {
-+ ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |=
-+ OFFSET_MASK(offset);
-+ }
-+ }
-+
-+ /* Now figure out the new high water mark if appropriate */
-+ for (offset = ss->ssl3.hs.recvdHighWater;
-+ offset < ss->ssl3.hs.msg_len; offset++) {
-+ /* Note that this loop is not efficient, since it counts
-+ * bit by bit. If we have a lot of out-of-order packets,
-+ * we should optimize this */
-+ if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
-+ OFFSET_MASK(offset)) {
-+ ss->ssl3.hs.recvdHighWater++;
-+ } else {
-+ break;
-+ }
-+ }
-+
-+ /* If we have all the bytes, then we are good to go */
-+ if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) {
-+ ss->ssl3.hs.recvdHighWater = -1;
-+
-+ rv = ssl3_HandleHandshakeMessage(ss,
-+ ss->ssl3.hs.msg_body.buf,
-+ ss->ssl3.hs.msg_len);
-+ if (rv == SECFailure)
-+ break; /* Skip rest of record */
-+
-+ /* At this point we are advancing our state machine, so
-+ * we can free our last flight of messages */
-+ dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
-+ dtls_CancelTimer(ss);
-+
-+ /* If there have been no retries this time, reset the
-+ * timer value to the default per Section 4.2.4.1 */
-+ if (ss->ssl3.hs.rtRetries == 0) {
-+ ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
-+ }
-+ }
-+ }
-+ }
-+
-+ buf.buf += fragment_length;
-+ buf.len -= fragment_length;
-+ }
-+
-+ origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
-+
-+ /* XXX OK for now. In future handle rv == SECWouldBlock safely in order
-+ * to deal with asynchronous certificate verification */
-+ return rv;
-+}
-+
-+/* Enqueue a message (either handshake or CCS)
-+ *
-+ * Called from:
-+ * dtls_StageHandshakeMessage()
-+ * ssl3_SendChangeCipherSpecs()
-+ */
-+SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
-+ const SSL3Opaque *pIn, PRInt32 nIn)
-+{
-+ SECStatus rv = SECSuccess;
-+ DTLSQueuedMessage *msg = NULL;
-+
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-+
-+ msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn);
-+
-+ if (!msg) {
-+ PORT_SetError(SEC_ERROR_NO_MEMORY);
-+ rv = SECFailure;
-+ } else {
-+ PR_APPEND_LINK(&msg->link, ss->ssl3.hs.lastMessageFlight);
-+ }
-+
-+ return rv;
-+}
-+
-+/* Add DTLS handshake message to the pending queue
-+ * Empty the sendBuf buffer.
-+ * This function returns SECSuccess or SECFailure, never SECWouldBlock.
-+ * Always set sendBuf.len to 0, even when returning SECFailure.
-+ *
-+ * Called from:
-+ * ssl3_AppendHandshakeHeader()
-+ * dtls_FlushHandshake()
-+ */
-+SECStatus
-+dtls_StageHandshakeMessage(sslSocket *ss)
-+{
-+ SECStatus rv = SECSuccess;
-+
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-+
-+ /* This function is sometimes called when no data is actually to
-+ * be staged, so just return SECSuccess. */
-+ if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
-+ return rv;
-+
-+ rv = dtls_QueueMessage(ss, content_handshake,
-+ ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);
-+
-+ /* Whether we succeeded or failed, toss the old handshake data. */
-+ ss->sec.ci.sendBuf.len = 0;
-+ return rv;
-+}
-+
-+/* Enqueue the handshake message in sendBuf (if any) and then
-+ * transmit the resulting flight of handshake messages.
-+ *
-+ * Called from:
-+ * ssl3_FlushHandshake()
-+ */
-+SECStatus
-+dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
-+{
-+ SECStatus rv = SECSuccess;
-+
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-+
-+ rv = dtls_StageHandshakeMessage(ss);
-+ if (rv != SECSuccess)
-+ return rv;
-+
-+ if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
-+ rv = dtls_TransmitMessageFlight(ss);
-+ if (rv != SECSuccess)
-+ return rv;
-+
-+ if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
-+ ss->ssl3.hs.rtRetries = 0;
-+ rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
-+ }
-+ }
-+
-+ return rv;
-+}
-+
-+/* The callback for when the retransmit timer expires
-+ *
-+ * Called from:
-+ * dtls_CheckTimer()
-+ * dtls_HandleHandshake()
-+ */
-+static void
-+dtls_RetransmitTimerExpiredCb(sslSocket *ss)
-+{
-+ SECStatus rv = SECFailure;
-+
-+ ss->ssl3.hs.rtRetries++;
-+
-+ if (!(ss->ssl3.hs.rtRetries % 3)) {
-+ /* If one of the messages was potentially greater than > MTU,
-+ * then downgrade. Do this every time we have retransmitted a
-+ * message twice, per RFC 6347 Sec. 4.1.1 */
-+ dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
-+ }
-+
-+ rv = dtls_TransmitMessageFlight(ss);
-+ if (rv == SECSuccess) {
-+
-+ /* Re-arm the timer */
-+ rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
-+ }
-+
-+ if (rv == SECFailure) {
-+ /* XXX OK for now. In future maybe signal the stack that we couldn't
-+ * transmit. For now, let the read handle any real network errors */
-+ }
-+}
-+
-+/* Transmit a flight of handshake messages, stuffing them
-+ * into as few records as seems reasonable
-+ *
-+ * Called from:
-+ * dtls_FlushHandshake()
-+ * dtls_RetransmitTimerExpiredCb()
-+ */
-+static SECStatus
-+dtls_TransmitMessageFlight(sslSocket *ss)
-+{
-+ SECStatus rv = SECSuccess;
-+ PRCList *msg_p;
-+ PRUint16 room_left = ss->ssl3.mtu;
-+ PRInt32 sent;
-+
-+ ssl_GetXmitBufLock(ss);
-+ ssl_GetSpecReadLock(ss);
-+
-+ /* DTLS does not buffer its handshake messages in
-+ * ss->pendingBuf, but rather in the lastMessageFlight
-+ * structure. This is just a sanity check that
-+ * some programming error hasn't inadvertantly
-+ * stuffed something in ss->pendingBuf
-+ */
-+ PORT_Assert(!ss->pendingBuf.len);
-+ for (msg_p = PR_LIST_HEAD(ss->ssl3.hs.lastMessageFlight);
-+ msg_p != ss->ssl3.hs.lastMessageFlight;
-+ msg_p = PR_NEXT_LINK(msg_p)) {
-+ DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;
-+
-+ /* The logic here is:
-+ *
-+ * 1. If this is a message that will not fit into the remaining
-+ * space, then flush.
-+ * 2. If the message will now fit into the remaining space,
-+ * encrypt, buffer, and loop.
-+ * 3. If the message will not fit, then fragment.
-+ *
-+ * At the end of the function, flush.
-+ */
-+ if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
-+ /* The message will not fit into the remaining space, so flush */
-+ rv = dtls_SendSavedWriteData(ss);
-+ if (rv != SECSuccess)
-+ break;
-+
-+ room_left = ss->ssl3.mtu;
-+ }
-+
-+ if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
-+ /* The message will fit, so encrypt and then continue with the
-+ * next packet */
-+ sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
-+ msg->data, msg->len,
-+ ssl_SEND_FLAG_FORCE_INTO_BUFFER |
-+ ssl_SEND_FLAG_USE_EPOCH);
-+ if (sent != msg->len) {
-+ rv = SECFailure;
-+ if (sent != -1) {
-+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
-+ }
-+ break;
-+ }
-+
-+ room_left = ss->ssl3.mtu - ss->pendingBuf.len;
-+ } else {
-+ /* The message will not fit, so fragment.
-+ *
-+ * XXX OK for now. Arrange to coalesce the last fragment
-+ * of this message with the next message if possible.
-+ * That would be more efficient.
-+ */
-+ PRUint32 fragment_offset = 0;
-+ unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
-+ * plausible MTU */
-+
-+ /* Assert that we have already flushed */
-+ PORT_Assert(room_left == ss->ssl3.mtu);
-+
-+ /* Case 3: We now need to fragment this message
-+ * DTLS only supports fragmenting handshaking messages */
-+ PORT_Assert(msg->type == content_handshake);
-+
-+ /* The headers consume 12 bytes so the smalles possible
-+ * message (i.e., an empty one) is 12 bytes
-+ */
-+ PORT_Assert(msg->len >= 12);
-+
-+ while ((fragment_offset + 12) < msg->len) {
-+ PRUint32 fragment_len;
-+ const unsigned char *content = msg->data + 12;
-+ PRUint32 content_len = msg->len - 12;
-+
-+ /* The reason we use 8 here is that that's the length of
-+ * the new DTLS data that we add to the header */
-+ fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
-+ content_len - fragment_offset);
-+ PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
-+ /* Make totally sure that we are within the buffer.
-+ * Note that the only way that fragment len could get
-+ * adjusted here is if
-+ *
-+ * (a) we are in release mode so the PORT_Assert is compiled out
-+ * (b) either the MTU table is inconsistent with DTLS_MAX_MTU
-+ * or ss->ssl3.mtu has become corrupt.
-+ */
-+ fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
-+
-+ /* Construct an appropriate-sized fragment */
-+ /* Type, length, sequence */
-+ PORT_Memcpy(fragment, msg->data, 6);
-+
-+ /* Offset */
-+ fragment[6] = (fragment_offset >> 16) & 0xff;
-+ fragment[7] = (fragment_offset >> 8) & 0xff;
-+ fragment[8] = (fragment_offset) & 0xff;
-+
-+ /* Fragment length */
-+ fragment[9] = (fragment_len >> 16) & 0xff;
-+ fragment[10] = (fragment_len >> 8) & 0xff;
-+ fragment[11] = (fragment_len) & 0xff;
-+
-+ PORT_Memcpy(fragment + 12, content + fragment_offset,
-+ fragment_len);
-+
-+ /*
-+ * Send the record. We do this in two stages
-+ * 1. Encrypt
-+ */
-+ sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
-+ fragment, fragment_len + 12,
-+ ssl_SEND_FLAG_FORCE_INTO_BUFFER |
-+ ssl_SEND_FLAG_USE_EPOCH);
-+ if (sent != (fragment_len + 12)) {
-+ rv = SECFailure;
-+ if (sent != -1) {
-+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
-+ }
-+ break;
-+ }
-+
-+ /* 2. Flush */
-+ rv = dtls_SendSavedWriteData(ss);
-+ if (rv != SECSuccess)
-+ break;
-+
-+ fragment_offset += fragment_len;
-+ }
-+ }
-+ }
-+
-+ /* Finally, we need to flush */
-+ if (rv == SECSuccess)
-+ rv = dtls_SendSavedWriteData(ss);
-+
-+ /* Give up the locks */
-+ ssl_ReleaseSpecReadLock(ss);
-+ ssl_ReleaseXmitBufLock(ss);
-+
-+ return rv;
-+}
-+
-+/* Flush the data in the pendingBuf and update the max message sent
-+ * so we can adjust the MTU estimate if we need to.
-+ * Wrapper for ssl_SendSavedWriteData.
-+ *
-+ * Called from dtls_TransmitMessageFlight()
-+ */
-+static
-+SECStatus dtls_SendSavedWriteData(sslSocket *ss)
-+{
-+ PRInt32 sent;
-+
-+ sent = ssl_SendSavedWriteData(ss);
-+ if (sent < 0)
-+ return SECFailure;
-+
-+ /* We should always have complete writes b/c datagram sockets
-+ * don't really block */
-+ if (ss->pendingBuf.len > 0) {
-+ ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
-+ return SECFailure;
-+ }
-+
-+ /* Update the largest message sent so we can adjust the MTU
-+ * estimate if necessary */
-+ if (sent > ss->ssl3.hs.maxMessageSent)
-+ ss->ssl3.hs.maxMessageSent = sent;
-+
-+ return SECSuccess;
-+}
-+
-+/* Compress, MAC, encrypt a DTLS record. Allows specification of
-+ * the epoch using epoch value. If use_epoch is PR_TRUE then
-+ * we use the provided epoch. If use_epoch is PR_FALSE then
-+ * whatever the current value is in effect is used.
-+ *
-+ * Called from ssl3_SendRecord()
-+ */
-+SECStatus
-+dtls_CompressMACEncryptRecord(sslSocket * ss,
-+ DTLSEpoch epoch,
-+ PRBool use_epoch,
-+ SSL3ContentType type,
-+ const SSL3Opaque * pIn,
-+ PRUint32 contentLen,
-+ sslBuffer * wrBuf)
-+{
-+ SECStatus rv = SECFailure;
-+ ssl3CipherSpec * cwSpec;
-+
-+ ssl_GetSpecReadLock(ss); /********************************/
-+
-+ /* The reason for this switch-hitting code is that we might have
-+ * a flight of records spanning an epoch boundary, e.g.,
-+ *
-+ * ClientKeyExchange (epoch = 0)
-+ * ChangeCipherSpec (epoch = 0)
-+ * Finished (epoch = 1)
-+ *
-+ * Thus, each record needs a different cipher spec. The information
-+ * about which epoch to use is carried with the record.
-+ */
-+ if (use_epoch) {
-+ if (ss->ssl3.cwSpec->epoch == epoch)
-+ cwSpec = ss->ssl3.cwSpec;
-+ else if (ss->ssl3.pwSpec->epoch == epoch)
-+ cwSpec = ss->ssl3.pwSpec;
-+ else
-+ cwSpec = NULL;
-+ } else {
-+ cwSpec = ss->ssl3.cwSpec;
-+ }
-+
-+ if (cwSpec) {
-+ rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
-+ type, pIn, contentLen, wrBuf);
-+ } else {
-+ PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
-+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
-+ }
-+ ssl_ReleaseSpecReadLock(ss); /************************************/
-+
-+ return rv;
-+}
-+
-+/* Start a timer
-+ *
-+ * Called from:
-+ * dtls_HandleHandshake()
-+ * dtls_FlushHAndshake()
-+ * dtls_RestartTimer()
-+ */
-+SECStatus
-+dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb)
-+{
-+ PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
-+
-+ ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
-+ ss->ssl3.hs.rtTimerCb = cb;
-+
-+ return SECSuccess;
-+}
-+
-+/* Restart a timer with optional backoff
-+ *
-+ * Called from dtls_RetransmitTimerExpiredCb()
-+ */
-+SECStatus
-+dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
-+{
-+ if (backoff) {
-+ ss->ssl3.hs.rtTimeoutMs *= 2;
-+ if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
-+ ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
-+ }
-+
-+ return dtls_StartTimer(ss, cb);
-+}
-+
-+/* Cancel a pending timer
-+ *
-+ * Called from:
-+ * dtls_HandleHandshake()
-+ * dtls_CheckTimer()
-+ */
-+void
-+dtls_CancelTimer(sslSocket *ss)
-+{
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-+
-+ ss->ssl3.hs.rtTimerCb = NULL;
-+}
-+
-+/* Check the pending timer and fire the callback if it expired
-+ *
-+ * Called from ssl3_GatherCompleteHandshake()
-+ */
-+void
-+dtls_CheckTimer(sslSocket *ss)
-+{
-+ if (!ss->ssl3.hs.rtTimerCb)
-+ return;
-+
-+ if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
-+ PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
-+ /* Timer has expired */
-+ DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
-+
-+ /* Cancel the timer so that we can call the CB safely */
-+ dtls_CancelTimer(ss);
-+
-+ /* Now call the CB */
-+ cb(ss);
-+ }
-+}
-+
-+/* The callback to fire when the holddown timer for the Finished
-+ * message expires and we can delete it
-+ *
-+ * Called from dtls_CheckTimer()
-+ */
-+void
-+dtls_FinishedTimerCb(sslSocket *ss)
-+{
-+ ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
-+}
-+
-+/* Cancel the Finished hold-down timer and destroy the
-+ * pending cipher spec. Note that this means that
-+ * successive rehandshakes will fail if the Finished is
-+ * lost.
-+ *
-+ * XXX OK for now. Figure out how to handle the combination
-+ * of Finished lost and rehandshake
-+ */
-+void
-+dtls_RehandshakeCleanup(sslSocket *ss)
-+{
-+ dtls_CancelTimer(ss);
-+ ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
-+ ss->ssl3.hs.sendMessageSeq = 0;
-+ ss->ssl3.hs.recvMessageSeq = 0;
-+}
-+
-+/* Set the MTU to the next step less than or equal to the
-+ * advertised value. Also used to downgrade the MTU by
-+ * doing dtls_SetMTU(ss, biggest packet set).
-+ *
-+ * Passing 0 means set this to the largest MTU known
-+ * (effectively resetting the PMTU backoff value).
-+ *
-+ * Called by:
-+ * ssl3_InitState()
-+ * dtls_RetransmitTimerExpiredCb()
-+ */
-+void
-+dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
-+{
-+ int i;
-+
-+ if (advertised == 0) {
-+ ss->ssl3.mtu = COMMON_MTU_VALUES[0];
-+ SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
-+ return;
-+ }
-+
-+ for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
-+ if (COMMON_MTU_VALUES[i] <= advertised) {
-+ ss->ssl3.mtu = COMMON_MTU_VALUES[i];
-+ SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
-+ return;
-+ }
-+ }
-+
-+ /* Fallback */
-+ ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
-+ SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
-+}
-+
-+/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a
-+ * DTLS hello_verify_request
-+ * Caller must hold Handshake and RecvBuf locks.
-+ */
-+SECStatus
-+dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-+{
-+ int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
-+ SECStatus rv;
-+ PRInt32 temp;
-+ SECItem cookie = {siBuffer, NULL, 0};
-+ SSL3AlertDescription desc = illegal_parameter;
-+
-+ SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
-+ SSL_GETPID(), ss->fd));
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-+
-+ if (ss->ssl3.hs.ws != wait_server_hello) {
-+ errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
-+ desc = unexpected_message;
-+ goto alert_loser;
-+ }
-+
-+ /* The version */
-+ temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
-+ if (temp < 0) {
-+ goto loser; /* alert has been sent */
-+ }
-+
-+ if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
-+ /* Note: this will need adjustment for DTLS 1.2 per Section 4.2.1 */
-+ goto alert_loser;
-+ }
-+
-+ /* The cookie */
-+ rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
-+ if (rv != SECSuccess) {
-+ goto loser; /* alert has been sent */
-+ }
-+ if (cookie.len > DTLS_COOKIE_BYTES) {
-+ desc = decode_error;
-+ goto alert_loser; /* malformed. */
-+ }
-+
-+ PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
-+ ss->ssl3.hs.cookieLen = cookie.len;
-+
-+
-+ ssl_GetXmitBufLock(ss); /*******************************/
-+
-+ /* Now re-send the client hello */
-+ rv = ssl3_SendClientHello(ss, PR_TRUE);
-+
-+ ssl_ReleaseXmitBufLock(ss); /*******************************/
-+
-+ if (rv == SECSuccess)
-+ return rv;
-+
-+alert_loser:
-+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
-+
-+loser:
-+ errCode = ssl_MapLowLevelError(errCode);
-+ return SECFailure;
-+}
-+
-+/* Initialize the DTLS anti-replay window
-+ *
-+ * Called from:
-+ * ssl3_SetupPendingCipherSpec()
-+ * ssl3_InitCipherSpec()
-+ */
-+void
-+dtls_InitRecvdRecords(DTLSRecvdRecords *records)
-+{
-+ PORT_Memset(records->data, 0, sizeof(records->data));
-+ records->left = 0;
-+ records->right = DTLS_RECVD_RECORDS_WINDOW - 1;
-+}
-+
-+/*
-+ * Has this DTLS record been received? Return values are:
-+ * -1 -- out of range to the left
-+ * 0 -- not received yet
-+ * 1 -- replay
-+ *
-+ * Called from: dtls_HandleRecord()
-+ */
-+int
-+dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
-+{
-+ PRUint64 offset;
-+
-+ /* Out of range to the left */
-+ if (seq < records->left) {
-+ return -1;
-+ }
-+
-+ /* Out of range to the right; since we advance the window on
-+ * receipt, that means that this packet has not been received
-+ * yet */
-+ if (seq > records->right)
-+ return 0;
-+
-+ offset = seq % DTLS_RECVD_RECORDS_WINDOW;
-+
-+ return !!(records->data[offset / 8] & (1 << (offset % 8)));
-+}
-+
-+/* Update the DTLS anti-replay window
-+ *
-+ * Called from ssl3_HandleRecord()
-+ */
-+void
-+dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
-+{
-+ PRUint64 offset;
-+
-+ if (seq < records->left)
-+ return;
-+
-+ if (seq > records->right) {
-+ PRUint64 new_left;
-+ PRUint64 new_right;
-+ PRUint64 right;
-+
-+ /* Slide to the right; this is the tricky part
-+ *
-+ * 1. new_top is set to have room for seq, on the
-+ * next byte boundary by setting the right 8
-+ * bits of seq
-+ * 2. new_left is set to compensate.
-+ * 3. Zero all bits between top and new_top. Since
-+ * this is a ring, this zeroes everything as-yet
-+ * unseen. Because we always operate on byte
-+ * boundaries, we can zero one byte at a time
-+ */
-+ new_right = seq | 0x07;
-+ new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
-+
-+ for (right = records->right + 8; right <= new_right; right += 8) {
-+ offset = right % DTLS_RECVD_RECORDS_WINDOW;
-+ records->data[offset / 8] = 0;
-+ }
-+
-+ records->right = new_right;
-+ records->left = new_left;
-+ }
-+
-+ offset = seq % DTLS_RECVD_RECORDS_WINDOW;
-+
-+ records->data[offset / 8] |= (1 << (offset % 8));
-+}
-+
-+SECStatus
-+DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
-+{
-+ sslSocket * ss = NULL;
-+ PRIntervalTime elapsed;
-+ PRIntervalTime desired;
-+
-+ ss = ssl_FindSocket(socket);
-+
-+ if (!ss)
-+ return SECFailure;
-+
-+ if (!IS_DTLS(ss))
-+ return SECFailure;
-+
-+ if (!ss->ssl3.hs.rtTimerCb)
-+ return SECFailure;
-+
-+ elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted;
-+ desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs);
-+ if (elapsed > desired) {
-+ /* Timer expired */
-+ *timeout = PR_INTERVAL_NO_WAIT;
-+ } else {
-+ *timeout = desired - elapsed;
-+ }
-+
-+ return SECSuccess;
-+}
-
-Property changes on: net/third_party/nss/ssl/dtls1con.c
-___________________________________________________________________
-Added: svn:eol-style
- + LF
-
-Index: net/third_party/nss/ssl/sslproto.h
-===================================================================
---- net/third_party/nss/ssl/sslproto.h (revision 127709)
-+++ net/third_party/nss/ssl/sslproto.h (working copy)
-@@ -49,10 +49,15 @@
- #define SSL_LIBRARY_VERSION_3_0 0x0300
- #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
- #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
-+/* Note: this is the internal format, not the wire format */
-+#define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302
-
- /* deprecated old name */
- #define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
-
-+/* The DTLS version used in the spec */
-+#define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE ((~0x0100) & 0xffff)
-+
- /* Header lengths of some of the messages */
- #define SSL_HL_ERROR_HBYTES 3
- #define SSL_HL_CLIENT_HELLO_HBYTES 9
-Index: net/third_party/nss/ssl/sslt.h
-===================================================================
---- net/third_party/nss/ssl/sslt.h (revision 127709)
-+++ net/third_party/nss/ssl/sslt.h (working copy)
-@@ -190,7 +190,8 @@
- } SSLCipherSuiteInfo;
-
- typedef enum {
-- ssl_variant_stream = 0
-+ ssl_variant_stream = 0,
-+ ssl_variant_datagram = 1
- } SSLProtocolVariant;
-
- typedef struct SSLVersionRangeStr {
diff --git a/net/third_party/nss/patches/dtlssrtp.patch b/net/third_party/nss/patches/dtlssrtp.patch
deleted file mode 100644
index fefc6c4..0000000
--- a/net/third_party/nss/patches/dtlssrtp.patch
+++ /dev/null
@@ -1,468 +0,0 @@
-Index: net/third_party/nss/ssl/ssl.h
-===================================================================
---- net/third_party/nss/ssl/ssl.h (revision 140534)
-+++ net/third_party/nss/ssl/ssl.h (revision 140535)
-@@ -834,6 +834,28 @@
- struct SECKEYPrivateKeyStr **pRetKey);
-
- /*
-+** Configure DTLS-SRTP (RFC 5764) cipher suite preferences.
-+** Input is a list of ciphers in descending preference order and a length
-+** of the list. As a side effect, this causes the use_srtp extension to be
-+** negotiated.
-+**
-+** Invalid or unimplemented cipher suites in |ciphers| are ignored. If at
-+** least one cipher suite in |ciphers| is implemented, returns SECSuccess.
-+** Otherwise returns SECFailure.
-+*/
-+SSL_IMPORT SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
-+ const PRUint16 *ciphers,
-+ unsigned int numCiphers);
-+
-+/*
-+** Get the selected DTLS-SRTP cipher suite (if any).
-+** To be called after the handshake completes.
-+** Returns SECFailure if not negotiated.
-+*/
-+SSL_IMPORT SECStatus SSL_GetSRTPCipher(PRFileDesc *fd,
-+ PRUint16 *cipher);
-+
-+/*
- * Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
- * Returns SECSuccess if so, SECFailure if not.
-Index: net/third_party/nss/ssl/sslimpl.h
-===================================================================
---- net/third_party/nss/ssl/sslimpl.h (revision 140534)
-+++ net/third_party/nss/ssl/sslimpl.h (revision 140535)
-@@ -328,6 +328,8 @@
- #define ssl_V3_SUITES_IMPLEMENTED 30
- #endif /* NSS_ENABLE_ECC */
-
-+#define MAX_DTLS_SRTP_CIPHER_SUITES 4
-+
- typedef struct sslOptionsStr {
- /* If SSL_SetNextProtoNego has been called, then this contains the
- * list of supported protocols. */
-@@ -951,6 +953,11 @@
- SSLNextProtoState nextProtoState;
-
- PRUint16 mtu; /* Our estimate of the MTU */
-+
-+ /* DTLS-SRTP cipher suite preferences (if any) */
-+ PRUint16 dtlsSRTPCiphers[MAX_DTLS_SRTP_CIPHER_SUITES];
-+ PRUint16 dtlsSRTPCipherCount;
-+ PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */
- };
-
- #define DTLS_MAX_MTU 1500 /* Ethernet MTU but without subtracting the
-Index: net/third_party/nss/ssl/ssl3ext.c
-===================================================================
---- net/third_party/nss/ssl/ssl3ext.c (revision 140534)
-+++ net/third_party/nss/ssl/ssl3ext.c (revision 140535)
-@@ -88,6 +88,10 @@
- PRUint32 maxBytes);
- static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-+static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
-+ PRUint32 maxBytes);
-+static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
-+ SECItem *data);
-
- /*
- * Write bytes. Using this function means the SECItem structure
-@@ -246,6 +250,7 @@
- { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
-+ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
- { -1, NULL }
- };
-
-@@ -259,6 +264,7 @@
- { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
- { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
- { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
-+ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn},
- { -1, NULL }
- };
-
-@@ -284,7 +290,8 @@
- { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
- { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
-- { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
-+ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
-+ { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }
- /* any extra entries will appear as { 0, NULL } */
- };
-
-@@ -1782,3 +1789,206 @@
- return rv;
- }
-
-+static PRInt32
-+ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
-+{
-+ PRUint32 ext_data_len;
-+ PRInt16 i;
-+ SECStatus rv;
-+
-+ if (!ss)
-+ return 0;
-+
-+ if (!ss->sec.isServer) {
-+ /* Client side */
-+
-+ if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
-+ return 0; /* Not relevant */
-+
-+ ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
-+
-+ if (append && maxBytes >= 4 + ext_data_len) {
-+ /* Extension type */
-+ rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
-+ if (rv != SECSuccess) return -1;
-+ /* Length of extension data */
-+ rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
-+ if (rv != SECSuccess) return -1;
-+ /* Length of the SRTP cipher list */
-+ rv = ssl3_AppendHandshakeNumber(ss,
-+ 2 * ss->ssl3.dtlsSRTPCipherCount,
-+ 2);
-+ if (rv != SECSuccess) return -1;
-+ /* The SRTP ciphers */
-+ for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
-+ rv = ssl3_AppendHandshakeNumber(ss,
-+ ss->ssl3.dtlsSRTPCiphers[i],
-+ 2);
-+ }
-+ /* Empty MKI value */
-+ ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
-+
-+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
-+ ssl_use_srtp_xtn;
-+ }
-+
-+ return 4 + ext_data_len;
-+ }
-+
-+ /* Server side */
-+ if (append && maxBytes >= 9) {
-+ /* Extension type */
-+ rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
-+ if (rv != SECSuccess) return -1;
-+ /* Length of extension data */
-+ rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
-+ if (rv != SECSuccess) return -1;
-+ /* Length of the SRTP cipher list */
-+ rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
-+ if (rv != SECSuccess) return -1;
-+ /* The selected cipher */
-+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
-+ if (rv != SECSuccess) return -1;
-+ /* Empty MKI value */
-+ ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
-+ }
-+
-+ return 9;
-+}
-+
-+static SECStatus
-+ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
-+{
-+ SECStatus rv;
-+ SECItem ciphers = {siBuffer, NULL, 0};
-+ PRInt16 i;
-+ PRInt16 j;
-+ PRUint16 cipher = 0;
-+ PRBool found = PR_FALSE;
-+ SECItem litem;
-+
-+ if (!ss->sec.isServer) {
-+ /* Client side */
-+ if (!data->data || !data->len) {
-+ /* malformed */
-+ return SECFailure;
-+ }
-+
-+ /* Get the cipher list */
-+ rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
-+ &data->data, &data->len);
-+ if (rv != SECSuccess) {
-+ return SECFailure;
-+ }
-+ /* Now check that the number of ciphers listed is 1 (len = 2) */
-+ if (ciphers.len != 2) {
-+ return SECFailure;
-+ }
-+
-+ /* Get the selected cipher */
-+ cipher = (ciphers.data[0] << 8) | ciphers.data[1];
-+
-+ /* Now check that this is one of the ciphers we offered */
-+ for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
-+ if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
-+ found = PR_TRUE;
-+ break;
-+ }
-+ }
-+
-+ if (!found) {
-+ return SECFailure;
-+ }
-+
-+ /* Get the srtp_mki value */
-+ rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
-+ &data->data, &data->len);
-+ if (rv != SECSuccess) {
-+ return SECFailure;
-+ }
-+
-+ /* We didn't offer an MKI, so this must be 0 length */
-+ /* XXX RFC 5764 Section 4.1.3 says:
-+ * If the client detects a nonzero-length MKI in the server's
-+ * response that is different than the one the client offered,
-+ * then the client MUST abort the handshake and SHOULD send an
-+ * invalid_parameter alert.
-+ *
-+ * Due to a limitation of the ssl3_HandleHelloExtensions function,
-+ * returning SECFailure here won't abort the handshake. It will
-+ * merely cause the use_srtp extension to be not negotiated. We
-+ * should fix this. See NSS bug 753136.
-+ */
-+ if (litem.len != 0) {
-+ return SECFailure;
-+ }
-+
-+ if (data->len != 0) {
-+ /* malformed */
-+ return SECFailure;
-+ }
-+
-+ /* OK, this looks fine. */
-+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
-+ ss->ssl3.dtlsSRTPCipherSuite = cipher;
-+ return SECSuccess;
-+ }
-+
-+ /* Server side */
-+ if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
-+ /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
-+ * preferences have been set. */
-+ return SECSuccess;
-+ }
-+
-+ if (!data->data || data->len < 5) {
-+ /* malformed */
-+ return SECFailure;
-+ }
-+
-+ /* Get the cipher list */
-+ rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
-+ &data->data, &data->len);
-+ if (rv != SECSuccess) {
-+ return SECFailure;
-+ }
-+ /* Check that the list is even length */
-+ if (ciphers.len % 2) {
-+ return SECFailure;
-+ }
-+
-+ /* Walk through the offered list and pick the most preferred of our
-+ * ciphers, if any */
-+ for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
-+ for (j = 0; j + 1 < ciphers.len; j += 2) {
-+ cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
-+ if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
-+ found = PR_TRUE;
-+ break;
-+ }
-+ }
-+ }
-+
-+ /* Get the srtp_mki value */
-+ rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
-+ if (rv != SECSuccess) {
-+ return SECFailure;
-+ }
-+
-+ if (data->len != 0) {
-+ return SECFailure; /* Malformed */
-+ }
-+
-+ /* Now figure out what to do */
-+ if (!found) {
-+ /* No matching ciphers */
-+ return SECSuccess;
-+ }
-+
-+ /* OK, we have a valid cipher and we've selected it */
-+ ss->ssl3.dtlsSRTPCipherSuite = cipher;
-+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
-+
-+ return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
-+ ssl3_SendUseSRTPXtn);
-+}
-Index: net/third_party/nss/ssl/sslsock.c
-===================================================================
---- net/third_party/nss/ssl/sslsock.c (revision 140534)
-+++ net/third_party/nss/ssl/sslsock.c (revision 140535)
-@@ -223,6 +223,13 @@
- char lockStatus[] = "Locks are ENABLED. ";
- #define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
-
-+/* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
-+static const PRUint16 srtpCiphers[] = {
-+ SRTP_AES128_CM_HMAC_SHA1_80,
-+ SRTP_AES128_CM_HMAC_SHA1_32,
-+ 0
-+};
-+
- /* forward declarations. */
- static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
- static SECStatus ssl_MakeLocks(sslSocket *ss);
-@@ -288,12 +295,6 @@
- sslSocket *ss;
- SECStatus rv;
-
-- /* Not implemented for datagram */
-- if (IS_DTLS(os)) {
-- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
-- return NULL;
-- }
--
- ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
- if (ss) {
- ss->opt = os->opt;
-@@ -314,6 +315,9 @@
- ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
- ss->chosenPreference = os->chosenPreference;
- PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
-+ PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
-+ sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
-+ ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
-
- if (os->cipherSpecs) {
- ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
-@@ -1574,6 +1578,75 @@
- return SECSuccess;
- }
-
-+SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
-+ const PRUint16 *ciphers,
-+ unsigned int numCiphers)
-+{
-+ sslSocket *ss;
-+ int i;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss || !IS_DTLS(ss)) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSRTPCiphers",
-+ SSL_GETPID(), fd));
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ return SECFailure;
-+ }
-+
-+ if (numCiphers > MAX_DTLS_SRTP_CIPHER_SUITES) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ return SECFailure;
-+ }
-+
-+ ss->ssl3.dtlsSRTPCipherCount = 0;
-+ for (i = 0; i < numCiphers; i++) {
-+ const PRUint16 *srtpCipher = srtpCiphers;
-+
-+ while (*srtpCipher) {
-+ if (ciphers[i] == *srtpCipher)
-+ break;
-+ srtpCipher++;
-+ }
-+ if (*srtpCipher) {
-+ ss->ssl3.dtlsSRTPCiphers[ss->ssl3.dtlsSRTPCipherCount++] =
-+ ciphers[i];
-+ } else {
-+ SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
-+ "suite specified: 0x%04hx", SSL_GETPID(), fd,
-+ ciphers[i]));
-+ }
-+ }
-+
-+ if (ss->ssl3.dtlsSRTPCipherCount == 0) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ return SECFailure;
-+ }
-+
-+ return SECSuccess;
-+}
-+
-+SECStatus
-+SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
-+{
-+ sslSocket * ss;
-+
-+ ss = ssl_FindSocket(fd);
-+ if (!ss) {
-+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSRTPCipher",
-+ SSL_GETPID(), fd));
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ return SECFailure;
-+ }
-+
-+ if (!ss->ssl3.dtlsSRTPCipherSuite) {
-+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
-+ return SECFailure;
-+ }
-+
-+ *cipher = ss->ssl3.dtlsSRTPCipherSuite;
-+ return SECSuccess;
-+}
-+
- PRFileDesc *
- SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
- {
-@@ -1607,6 +1680,9 @@
- ss->opt = sm->opt;
- ss->vrange = sm->vrange;
- PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
-+ PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
-+ sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
-+ ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
-
- if (!ss->opt.useSecurity) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
-Index: net/third_party/nss/ssl/sslproto.h
-===================================================================
---- net/third_party/nss/ssl/sslproto.h (revision 140534)
-+++ net/third_party/nss/ssl/sslproto.h (revision 140535)
-@@ -237,4 +237,11 @@
- #define SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA 0xfeff
- #define SSL_RSA_FIPS_WITH_DES_CBC_SHA 0xfefe
-
-+/* DTLS-SRTP cipher suites from RFC 5764 */
-+/* If you modify this, also modify MAX_DTLS_SRTP_CIPHER_SUITES in sslimpl.h */
-+#define SRTP_AES128_CM_HMAC_SHA1_80 0x0001
-+#define SRTP_AES128_CM_HMAC_SHA1_32 0x0002
-+#define SRTP_NULL_HMAC_SHA1_80 0x0005
-+#define SRTP_NULL_HMAC_SHA1_32 0x0006
-+
- #endif /* __sslproto_h_ */
-Index: net/third_party/nss/ssl/sslt.h
-===================================================================
---- net/third_party/nss/ssl/sslt.h (revision 140534)
-+++ net/third_party/nss/ssl/sslt.h (revision 140535)
-@@ -213,12 +213,13 @@
- ssl_elliptic_curves_xtn = 10,
- ssl_ec_point_formats_xtn = 11,
- #endif
-+ ssl_use_srtp_xtn = 14,
- ssl_session_ticket_xtn = 35,
- ssl_next_proto_nego_xtn = 13172,
- ssl_channel_id_xtn = 30031,
- ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
- } SSLExtensionType;
-
--#define SSL_MAX_EXTENSIONS 8
-+#define SSL_MAX_EXTENSIONS 9
-
- #endif /* __sslt_h_ */
diff --git a/net/third_party/nss/patches/ecpointform.patch b/net/third_party/nss/patches/ecpointform.patch
new file mode 100644
index 0000000..cfe2930
--- /dev/null
+++ b/net/third_party/nss/patches/ecpointform.patch
@@ -0,0 +1,19 @@
+diff -pu -r a/net/third_party/nss/ssl/ssl3ecc.c b/net/third_party/nss/ssl/ssl3ecc.c
+--- a/net/third_party/nss/ssl/ssl3ecc.c 2012-06-10 19:38:30.000000000 -0700
++++ b/net/third_party/nss/ssl/ssl3ecc.c 2012-11-12 15:57:59.222697369 -0800
+@@ -33,6 +33,15 @@
+
+ #ifdef NSS_ENABLE_ECC
+
++/*
++ * In NSS 3.13.2 the definition of the EC_POINT_FORM_UNCOMPRESSED macro
++ * was moved from the internal header ec.h to the public header blapit.h.
++ * Define the macro here when compiling against older system NSS headers.
++ */
++#ifndef EC_POINT_FORM_UNCOMPRESSED
++#define EC_POINT_FORM_UNCOMPRESSED 0x04
++#endif
++
+ #ifndef PK11_SETATTRS
+ #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
+ (x)->pValue=(v); (x)->ulValueLen = (l);
diff --git a/net/third_party/nss/patches/falsestartnpn.patch b/net/third_party/nss/patches/falsestartnpn.patch
index 5516fb7..55d726d 100644
--- a/net/third_party/nss/patches/falsestartnpn.patch
+++ b/net/third_party/nss/patches/falsestartnpn.patch
@@ -1,8 +1,7 @@
-diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
-index e8a7f01..b6f4313 100644
---- a/net/third_party/nss/ssl/ssl3con.c
-+++ b/net/third_party/nss/ssl/ssl3con.c
-@@ -6087,10 +6087,17 @@ ssl3_CanFalseStart(sslSocket *ss) {
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:53:13.884846338 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:54:18.975797410 -0800
+@@ -6244,10 +6244,17 @@ ssl3_CanFalseStart(sslSocket *ss) {
!ss->sec.isServer &&
!ss->ssl3.hs.isResuming &&
ss->ssl3.cwSpec &&
@@ -23,11 +22,10 @@ index e8a7f01..b6f4313 100644
ssl_ReleaseSpecReadLock(ss);
return rv;
}
-diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
-index 80c1f7f..6d5866b 100644
---- a/net/third_party/nss/ssl/ssl3ext.c
-+++ b/net/third_party/nss/ssl/ssl3ext.c
-@@ -567,6 +567,12 @@ ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat
+diff -pu -r a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
+--- a/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 15:39:36.842891686 -0800
++++ b/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 15:56:10.157421377 -0800
+@@ -537,6 +537,12 @@ ssl3_ServerHandleNextProtoNegoXtn(sslSoc
return SECFailure;
}
@@ -40,7 +38,7 @@ index 80c1f7f..6d5866b 100644
return SECSuccess;
}
-@@ -635,6 +641,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
+@@ -605,6 +611,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSoc
return SECFailure;
}
diff --git a/net/third_party/nss/patches/getchannelinfo.patch b/net/third_party/nss/patches/getchannelinfo.patch
deleted file mode 100644
index f6bd0e0..0000000
--- a/net/third_party/nss/patches/getchannelinfo.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Index: net/third_party/nss/ssl/sslinfo.c
-===================================================================
---- net/third_party/nss/ssl/sslinfo.c (revision 143014)
-+++ net/third_party/nss/ssl/sslinfo.c (revision 143015)
-@@ -97,11 +97,11 @@
- } else if (ss->ssl3.initialized) { /* SSL3 and TLS */
- ssl_GetSpecReadLock(ss);
- /* XXX The cipher suite should be in the specs and this
-- * function should get it from crSpec rather than from the "hs".
-+ * function should get it from cwSpec rather than from the "hs".
- * See bug 275744 comment 69.
- */
- inf.cipherSuite = ss->ssl3.hs.cipher_suite;
-- inf.compressionMethod = ss->ssl3.crSpec->compression_method;
-+ inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
- ssl_ReleaseSpecReadLock(ss);
- inf.compressionMethodName =
- ssl_GetCompressionMethodName(inf.compressionMethod);
-@@ -336,7 +336,7 @@
- ss->ssl3.initialized) { /* TLS */
- SECItem *crsName;
- ssl_GetSpecReadLock(ss); /*********************************/
-- crsName = &ss->ssl3.crSpec->srvVirtName;
-+ crsName = &ss->ssl3.cwSpec->srvVirtName;
- if (crsName->data) {
- sniName = SECITEM_DupItem(crsName);
- }
diff --git a/net/third_party/nss/patches/getrequestedclientcerttypes.patch b/net/third_party/nss/patches/getrequestedclientcerttypes.patch
index 0b47707..050568e 100644
--- a/net/third_party/nss/patches/getrequestedclientcerttypes.patch
+++ b/net/third_party/nss/patches/getrequestedclientcerttypes.patch
@@ -1,27 +1,7 @@
-diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h
---- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:23:52.089678011 -0800
-+++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:43:25.796676478 -0800
-@@ -648,6 +648,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWith
- PRBool flushCache,
- PRIntervalTime timeout);
-
-+/* Returns a SECItem containing the certificate_types field of the
-+** CertificateRequest message. Each byte of the data is a TLS
-+** ClientCertificateType value, and they are ordered from most preferred to
-+** least. This function should only be called from the
-+** SSL_GetClientAuthDataHook callback, and will return NULL if called at any
-+** other time. The returned value is valid only until the callback returns, and
-+** should not be freed.
-+*/
-+SSL_IMPORT const SECItem *
-+SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd);
-
- #ifdef SSL_DEPRECATED_FUNCTION
- /* deprecated!
-diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c
---- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:23:52.089678011 -0800
-+++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:43:25.796676478 -0800
-@@ -5567,6 +5567,9 @@ ssl3_HandleCertificateRequest(sslSocket
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:39:36.842891686 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:47:24.309734248 -0800
+@@ -5946,6 +5946,9 @@ ssl3_HandleCertificateRequest(sslSocket
if (rv != SECSuccess)
goto loser; /* malformed, alert has been sent */
@@ -31,7 +11,7 @@ diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/s
arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL)
goto no_mem;
-@@ -5756,6 +5759,7 @@ loser:
+@@ -6135,6 +6138,7 @@ loser:
PORT_SetError(errCode);
rv = SECFailure;
done:
@@ -39,10 +19,30 @@ diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/s
if (arena != NULL)
PORT_FreeArena(arena, PR_FALSE);
#ifdef NSS_PLATFORM_CLIENT_AUTH
-diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h
---- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:23:52.089678011 -0800
-+++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:43:25.796676478 -0800
-@@ -1097,6 +1097,10 @@ struct sslSocketStr {
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 15:44:43.337377864 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:47:24.309734248 -0800
+@@ -709,6 +709,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWith
+ PRBool flushCache,
+ PRIntervalTime timeout);
+
++/* Returns a SECItem containing the certificate_types field of the
++** CertificateRequest message. Each byte of the data is a TLS
++** ClientCertificateType value, and they are ordered from most preferred to
++** least. This function should only be called from the
++** SSL_GetClientAuthDataHook callback, and will return NULL if called at any
++** other time. The returned value is valid only until the callback returns, and
++** should not be freed.
++*/
++SSL_IMPORT const SECItem *
++SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd);
+
+ #ifdef SSL_DEPRECATED_FUNCTION
+ /* deprecated!
+diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:39:36.942893150 -0800
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:47:24.309734248 -0800
+@@ -1141,6 +1141,10 @@ struct sslSocketStr {
unsigned int sizeCipherSpecs;
const unsigned char * preferredCipher;
@@ -53,10 +53,10 @@ diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/s
ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
/* Callbacks */
-diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c
---- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:12:15.750044671 -0800
-+++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:43:25.796676478 -0800
-@@ -1615,6 +1615,20 @@ SSL_HandshakeResumedSession(PRFileDesc *
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:44:43.337377864 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:47:24.309734248 -0800
+@@ -1926,6 +1926,20 @@ SSL_HandshakeResumedSession(PRFileDesc *
return SECSuccess;
}
@@ -77,7 +77,7 @@ diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/s
/************************************************************************/
/* The following functions are the TOP LEVEL SSL functions.
** They all get called through the NSPRIOMethods table below.
-@@ -2643,6 +2657,7 @@ ssl_NewSocket(PRBool makeLocks)
+@@ -2957,6 +2971,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
sc->serverKeyPair = NULL;
sc->serverKeyBits = 0;
}
diff --git a/net/third_party/nss/patches/keylog.patch b/net/third_party/nss/patches/keylog.patch
deleted file mode 100644
index 10a9285..0000000
--- a/net/third_party/nss/patches/keylog.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
-index 6780a84..4cf011b 100644
---- a/net/third_party/nss/ssl/ssl3con.c
-+++ b/net/third_party/nss/ssl/ssl3con.c
-@@ -4793,6 +4793,17 @@ done:
- return unwrappedWrappingKey;
- }
-
-+/* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2|
-+ * bytes to |out|. */
-+static void hexEncode(char *out, const unsigned char *in, size_t length) {
-+ static const char hextable[] = "0123456789abcdef";
-+ size_t i;
-+
-+ for (i = 0; i < length; i++) {
-+ *(out++) = hextable[in[i] >> 4];
-+ *(out++) = hextable[in[i] & 15];
-+ }
-+}
-
- /* Called from ssl3_SendClientKeyExchange(). */
- /* Presently, this always uses PKCS11. There is no bypass for this. */
-@@ -4832,16 +4843,17 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
- goto loser;
- }
-
--#if defined(TRACE)
-- if (ssl_trace >= 100 || ssl_keylog_iob) {
-+ if (ssl_keylog_iob) {
- SECStatus extractRV = PK11_ExtractKeyValue(pms);
- if (extractRV == SECSuccess) {
- SECItem * keyData = PK11_GetKeyData(pms);
- if (keyData && keyData->data && keyData->len) {
-+#ifdef TRACE
- if (ssl_trace >= 100) {
- ssl_PrintBuf(ss, "Pre-Master Secret",
- keyData->data, keyData->len);
- }
-+#endif
- if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) {
- /* https://developer.mozilla.org/en/NSS_Key_Log_Format */
-
-@@ -4849,21 +4861,11 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
- * keylog, so we have to do everything in a single call to
- * fwrite. */
- char buf[4 + 8*2 + 1 + 48*2 + 1];
-- static const char hextable[16] = "0123456789abcdef";
-- unsigned int i;
-
- strcpy(buf, "RSA ");
--
-- for (i = 0; i < 8; i++) {
-- buf[4 + i*2] = hextable[enc_pms.data[i] >> 4];
-- buf[4 + i*2 + 1] = hextable[enc_pms.data[i] & 15];
-- }
-+ hexEncode(buf + 4, enc_pms.data, 8);
- buf[20] = ' ';
--
-- for (i = 0; i < 48; i++) {
-- buf[21 + i*2] = hextable[keyData->data[i] >> 4];
-- buf[21 + i*2 + 1] = hextable[keyData->data[i] & 15];
-- }
-+ hexEncode(buf + 21, keyData->data, 48);
- buf[sizeof(buf) - 1] = '\n';
-
- fwrite(buf, sizeof(buf), 1, ssl_keylog_iob);
-@@ -4872,7 +4874,6 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
- }
- }
- }
--#endif
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-@@ -9046,6 +9047,69 @@ ssl3_RestartHandshakeAfterChannelIDReq(sslSocket *ss,
- return SECSuccess;
- }
-
-+/* called from ssl3_SendFinished
-+ *
-+ * Caller must already hold the SpecReadLock. (wish we could assert that!).
-+ * This function is simply a debugging aid and therefore does not return a
-+ * SECStatus. */
-+static void
-+ssl3_RecordKeyLog(sslSocket *ss)
-+{
-+ sslSessionID *sid;
-+ SECStatus rv;
-+ SECItem *keyData;
-+ char buf[14 /* "CLIENT_RANDOM " */ +
-+ SSL3_RANDOM_LENGTH*2 /* client_random */ +
-+ 1 /* " " */ +
-+ 48*2 /* master secret */ +
-+ 1 /* new line */];
-+ unsigned int j;
-+
-+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-+
-+ sid = ss->sec.ci.sid;
-+
-+ if (!ssl_keylog_iob)
-+ return;
-+
-+ rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret);
-+ if (rv != SECSuccess)
-+ return;
-+
-+ ssl_GetSpecReadLock(ss);
-+
-+ /* keyData does not need to be freed. */
-+ keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret);
-+ if (!keyData || !keyData->data || keyData->len != 48) {
-+ ssl_ReleaseSpecReadLock(ss);
-+ return;
-+ }
-+
-+ /* https://developer.mozilla.org/en/NSS_Key_Log_Format */
-+
-+ /* There could be multiple, concurrent writers to the
-+ * keylog, so we have to do everything in a single call to
-+ * fwrite. */
-+
-+ memcpy(buf, "CLIENT_RANDOM ", 14);
-+ j = 14;
-+ hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
-+ j += SSL3_RANDOM_LENGTH*2;
-+ buf[j++] = ' ';
-+ hexEncode(buf + j, keyData->data, 48);
-+ j += 48*2;
-+ buf[j++] = '\n';
-+
-+ PORT_Assert(j == sizeof(buf));
-+
-+ ssl_ReleaseSpecReadLock(ss);
-+
-+ if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1)
-+ return;
-+ fflush(ssl_keylog_iob);
-+ return;
-+}
-+
- /* called from ssl3_HandleServerHelloDone
- * ssl3_HandleClientHello
- * ssl3_HandleFinished
-@@ -9107,6 +9171,9 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
- if (rv != SECSuccess) {
- goto fail; /* error code set by ssl3_FlushHandshake */
- }
-+
-+ ssl3_RecordKeyLog(ss);
-+
- return SECSuccess;
-
- fail:
-diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
-index c61ab44..9387a21 100644
---- a/net/third_party/nss/ssl/sslsock.c
-+++ b/net/third_party/nss/ssl/sslsock.c
-@@ -2903,22 +2903,22 @@ ssl_SetDefaultsFromEnvironment(void)
- ssl_trace = atoi(ev);
- SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
- }
-+#endif /* TRACE */
-+ ev = getenv("SSLDEBUG");
-+ if (ev && ev[0]) {
-+ ssl_debug = atoi(ev);
-+ SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
-+ }
-+#endif /* DEBUG */
- ev = getenv("SSLKEYLOGFILE");
- if (ev && ev[0]) {
- ssl_keylog_iob = fopen(ev, "a");
- if (ftell(ssl_keylog_iob) == 0) {
-- fputs("# pre-master secret log file, generated by NSS\n",
-+ fputs("# SSL/TLS secrets log file, generated by NSS\n",
- ssl_keylog_iob);
- }
- SSL_TRACE(("SSL: logging pre-master secrets to %s", ev));
- }
--#endif /* TRACE */
-- ev = getenv("SSLDEBUG");
-- if (ev && ev[0]) {
-- ssl_debug = atoi(ev);
-- SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
-- }
--#endif /* DEBUG */
- ev = getenv("SSLBYPASS");
- if (ev && ev[0]) {
- ssl_defaults.bypassPKCS11 = (ev[0] == '1');
diff --git a/net/third_party/nss/patches/negotiatedextension.patch b/net/third_party/nss/patches/negotiatedextension.patch
index 98fbc07..b2b12de 100644
--- a/net/third_party/nss/patches/negotiatedextension.patch
+++ b/net/third_party/nss/patches/negotiatedextension.patch
@@ -1,17 +1,7 @@
-From 577e6655d4edc789eb4c572b303daf888676a454 Mon Sep 17 00:00:00 2001
-From: Adam Langley <agl@chromium.org>
-Date: Mon, 3 Oct 2011 12:27:21 -0400
-Subject: [PATCH] negotiatedextension.patch
-
----
- mozilla/security/nss/lib/ssl/sslreveal.c | 9 +--------
- 1 files changed, 1 insertions(+), 8 deletions(-)
-
-diff --git a/mozilla/security/nss/lib/ssl/sslreveal.c b/mozilla/security/nss/lib/ssl/sslreveal.c
-index 94b2c2f..0b9bb82 100644
---- a/mozilla/security/nss/lib/ssl/sslreveal.c
-+++ b/mozilla/security/nss/lib/ssl/sslreveal.c
-@@ -111,7 +111,6 @@ SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
+diff -pu -r a/net/third_party/nss/ssl/sslreveal.c b/net/third_party/nss/ssl/sslreveal.c
+--- a/net/third_party/nss/ssl/sslreveal.c 2012-04-25 07:50:12.000000000 -0700
++++ b/net/third_party/nss/ssl/sslreveal.c 2012-11-09 15:45:44.118267683 -0800
+@@ -79,7 +79,6 @@ SSL_HandshakeNegotiatedExtension(PRFileD
/* some decisions derived from SSL_GetChannelInfo */
sslSocket * sslsocket = NULL;
SECStatus rv = SECFailure;
@@ -19,7 +9,7 @@ index 94b2c2f..0b9bb82 100644
if (!pYes)
return rv;
-@@ -123,14 +122,8 @@ SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
+@@ -91,14 +90,8 @@ SSL_HandshakeNegotiatedExtension(PRFileD
return rv;
}
diff --git a/net/third_party/nss/patches/ocspstapling.patch b/net/third_party/nss/patches/ocspstapling.patch
index af01ca3..0abbfe2b 100644
--- a/net/third_party/nss/patches/ocspstapling.patch
+++ b/net/third_party/nss/patches/ocspstapling.patch
@@ -1,42 +1,7 @@
-diff -pu -r a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h
---- a/src/net/third_party/nss/ssl/ssl.h 2012-03-19 14:34:10.103984357 -0700
-+++ b/src/net/third_party/nss/ssl/ssl.h 2012-03-19 14:34:51.624539293 -0700
-@@ -184,6 +184,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi
- * accept fragmented alerts).
- */
- #define SSL_CBC_RANDOM_IV 23
-+#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
-
- #ifdef SSL_DEPRECATED_FUNCTION
- /* Old deprecated function names */
-@@ -435,6 +436,23 @@ SSL_IMPORT SECStatus SSL_PeerCertificate
- PRFileDesc *fd, CERTCertificate **certs,
- unsigned int *numCerts, unsigned int maxNumCerts);
-
-+/* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by
-+ * the TLS server. The resulting data is copied to |out_data|. On entry, |*len|
-+ * must contain the size of |out_data|. On exit, |*len| will contain the size
-+ * of the OCSP stapled response. If the stapled response is too large to fit in
-+ * |out_data| then it will be truncated. If no OCSP response was given by the
-+ * server then it has zero length.
-+ *
-+ * You must set the SSL_ENABLE_OCSP_STAPLING option in order for OCSP responses
-+ * to be provided by a server.
-+ *
-+ * You can call this function during the certificate verification callback or
-+ * any time afterwards.
-+ */
-+SSL_IMPORT SECStatus SSL_GetStapledOCSPResponse(PRFileDesc *fd,
-+ unsigned char *out_data,
-+ unsigned int *len);
-+
- /*
- ** Authenticate certificate hook. Called when a certificate comes in
- ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
-diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c
---- a/src/net/third_party/nss/ssl/ssl3con.c 2012-03-19 14:34:10.093984221 -0700
-+++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-03-19 14:34:51.624539293 -0700
-@@ -7899,6 +7899,57 @@ ssl3_CopyPeerCertsToSID(ssl3CertNode *ce
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:21:56.747322689 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:28:27.933078020 -0800
+@@ -8365,6 +8365,57 @@ ssl3_CopyPeerCertsToSID(ssl3CertNode *ce
}
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
@@ -94,7 +59,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ss
* ssl3 Certificate message.
* Caller must hold Handshake and RecvBuf locks.
*/
-@@ -8707,6 +8758,26 @@ ssl3_FinishHandshake(sslSocket * ss)
+@@ -9248,6 +9299,26 @@ ssl3_FinishHandshake(sslSocket * ss)
return SECSuccess;
}
@@ -121,8 +86,8 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ss
/* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
* hanshake message.
* Caller must hold Handshake and RecvBuf locks.
-@@ -8801,14 +8872,42 @@ ssl3_HandleHandshakeMessage(sslSocket *s
- rv = ssl3_HandleServerHello(ss, b, length);
+@@ -9376,14 +9447,42 @@ ssl3_HandleHandshakeMessage(sslSocket *s
+ rv = dtls_HandleHelloVerifyRequest(ss, b, length);
break;
case certificate:
+ if (ss->ssl3.hs.may_get_cert_status) {
@@ -164,7 +129,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ss
rv = ssl3_HandleServerKeyExchange(ss, b, length);
break;
case certificate_request:
-@@ -8817,6 +8916,9 @@ ssl3_HandleHandshakeMessage(sslSocket *s
+@@ -9392,6 +9491,9 @@ ssl3_HandleHandshakeMessage(sslSocket *s
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST);
return SECFailure;
}
@@ -174,7 +139,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ss
rv = ssl3_HandleCertificateRequest(ss, b, length);
break;
case server_hello_done:
-@@ -8830,6 +8932,9 @@ ssl3_HandleHandshakeMessage(sslSocket *s
+@@ -9405,6 +9507,9 @@ ssl3_HandleHandshakeMessage(sslSocket *s
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
return SECFailure;
}
@@ -184,7 +149,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ss
rv = ssl3_HandleServerHelloDone(ss);
break;
case certificate_verify:
-@@ -9719,6 +9824,12 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -10369,6 +10474,12 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ss->ssl3.hs.messages.len = 0;
ss->ssl3.hs.messages.space = 0;
}
@@ -197,28 +162,28 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ss
/* free the SSL3Buffer (msg_body) */
PORT_Free(ss->ssl3.hs.msg_body.buf);
-diff -pu -r a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c
---- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-03-12 12:14:12.000000000 -0700
-+++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-03-19 14:34:51.624539293 -0700
-@@ -253,6 +253,7 @@ static const ssl3HelloExtensionHandler s
- { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
+diff -pu -r a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
+--- a/net/third_party/nss/ssl/ssl3ext.c 2012-09-20 17:28:05.000000000 -0700
++++ b/net/third_party/nss/ssl/ssl3ext.c 2012-11-09 15:32:11.606363256 -0800
+@@ -234,6 +234,7 @@ static const ssl3HelloExtensionHandler s
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
+ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
{ -1, NULL }
};
-@@ -276,7 +277,8 @@ ssl3HelloExtensionSender clientHelloSend
- { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
+@@ -258,7 +259,8 @@ ssl3HelloExtensionSender clientHelloSend
#endif
{ ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
-- { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }
-+ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
+- { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }
++ { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
/* any extra entries will appear as { 0, NULL } */
};
-@@ -658,6 +660,80 @@ loser:
+@@ -640,6 +642,80 @@ loser:
return -1;
}
@@ -299,10 +264,10 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ss
/*
* NewSessionTicket
* Called from ssl3_HandleFinished
-diff -pu -r a/src/net/third_party/nss/ssl/ssl3prot.h b/src/net/third_party/nss/ssl/ssl3prot.h
---- a/src/net/third_party/nss/ssl/ssl3prot.h 2011-10-28 17:29:11.000000000 -0700
-+++ b/src/net/third_party/nss/ssl/ssl3prot.h 2012-03-19 14:34:51.624539293 -0700
-@@ -158,6 +158,7 @@ typedef enum {
+diff -pu -r a/net/third_party/nss/ssl/ssl3prot.h b/net/third_party/nss/ssl/ssl3prot.h
+--- a/net/third_party/nss/ssl/ssl3prot.h 2012-04-25 07:50:12.000000000 -0700
++++ b/net/third_party/nss/ssl/ssl3prot.h 2012-11-09 15:28:27.933078020 -0800
+@@ -129,6 +129,7 @@ typedef enum {
certificate_verify = 15,
client_key_exchange = 16,
finished = 20,
@@ -310,32 +275,67 @@ diff -pu -r a/src/net/third_party/nss/ssl/ssl3prot.h b/src/net/third_party/nss/s
next_proto = 67
} SSL3HandshakeType;
-diff -pu -r a/src/net/third_party/nss/ssl/sslerr.h b/src/net/third_party/nss/ssl/sslerr.h
---- a/src/net/third_party/nss/ssl/sslerr.h 2012-03-10 20:32:35.000000000 -0800
-+++ b/src/net/third_party/nss/ssl/sslerr.h 2012-03-19 14:35:47.275278925 -0700
-@@ -213,6 +213,8 @@ SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIE
+diff -pu -r a/net/third_party/nss/ssl/sslerr.h b/net/third_party/nss/ssl/sslerr.h
+--- a/net/third_party/nss/ssl/sslerr.h 2012-07-12 17:51:57.000000000 -0700
++++ b/net/third_party/nss/ssl/sslerr.h 2012-11-09 15:30:36.804971319 -0800
+@@ -188,6 +188,8 @@ SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQ
- SSL_ERROR_INVALID_VERSION_RANGE = (SSL_ERROR_BASE + 120),
+ SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION = (SSL_ERROR_BASE + 124),
-+SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 121),
++SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 125),
+
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */
-diff -pu -r a/src/net/third_party/nss/ssl/SSLerrs.h b/src/net/third_party/nss/ssl/SSLerrs.h
---- a/src/net/third_party/nss/ssl/SSLerrs.h 2012-03-10 20:32:34.000000000 -0800
-+++ b/src/net/third_party/nss/ssl/SSLerrs.h 2012-03-19 14:38:37.757544584 -0700
-@@ -420,3 +420,6 @@ ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_
+diff -pu -r a/net/third_party/nss/ssl/SSLerrs.h b/net/third_party/nss/ssl/SSLerrs.h
+--- a/net/third_party/nss/ssl/SSLerrs.h 2012-07-12 17:51:57.000000000 -0700
++++ b/net/third_party/nss/ssl/SSLerrs.h 2012-11-09 15:30:19.924723400 -0800
+@@ -400,3 +400,6 @@ ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY
- ER3(SSL_ERROR_INVALID_VERSION_RANGE, (SSL_ERROR_BASE + 120),
- "SSL version range is not valid.")
+ ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, (SSL_ERROR_BASE + 124),
+ "SSL feature not supported for the protocol version.")
+
-+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 121),
++ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 125),
+"SSL received an unexpected Certificate Status handshake message.")
-diff -pu -r a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h
---- a/src/net/third_party/nss/ssl/sslimpl.h 2012-03-19 14:34:10.093984221 -0700
-+++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-03-19 14:34:51.634539426 -0700
-@@ -339,6 +339,7 @@ typedef struct sslOptionsStr {
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 15:27:15.952019947 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:28:27.933078020 -0800
+@@ -158,6 +158,7 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
+ * accept fragmented alerts).
+ */
+ #define SSL_CBC_RANDOM_IV 23
++#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
+
+ #ifdef SSL_DEPRECATED_FUNCTION
+ /* Old deprecated function names */
+@@ -409,6 +410,23 @@ SSL_IMPORT SECStatus SSL_PeerCertificate
+ PRFileDesc *fd, CERTCertificate **certs,
+ unsigned int *numCerts, unsigned int maxNumCerts);
+
++/* SSL_GetStapledOCSPResponse returns the OCSP response that was provided by
++ * the TLS server. The resulting data is copied to |out_data|. On entry, |*len|
++ * must contain the size of |out_data|. On exit, |*len| will contain the size
++ * of the OCSP stapled response. If the stapled response is too large to fit in
++ * |out_data| then it will be truncated. If no OCSP response was given by the
++ * server then it has zero length.
++ *
++ * You must set the SSL_ENABLE_OCSP_STAPLING option in order for OCSP responses
++ * to be provided by a server.
++ *
++ * You can call this function during the certificate verification callback or
++ * any time afterwards.
++ */
++SSL_IMPORT SECStatus SSL_GetStapledOCSPResponse(PRFileDesc *fd,
++ unsigned char *out_data,
++ unsigned int *len);
++
+ /*
+ ** Authenticate certificate hook. Called when a certificate comes in
+ ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
+diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:21:56.747322689 -0800
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:28:27.943078167 -0800
+@@ -316,6 +316,7 @@ typedef struct sslOptionsStr {
unsigned int requireSafeNegotiation : 1; /* 22 */
unsigned int enableFalseStart : 1; /* 23 */
unsigned int cbcRandomIV : 1; /* 24 */
@@ -343,7 +343,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ss
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
-@@ -783,6 +784,14 @@ const ssl3CipherSuiteDef *suite_def;
+@@ -795,6 +796,14 @@ const ssl3CipherSuiteDef *suite_def;
PRBool isResuming; /* are we resuming a session */
PRBool usedStepDownKey; /* we did a server key exchange. */
PRBool sendingSCSV; /* instead of empty RI */
@@ -358,7 +358,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ss
sslBuffer msgState; /* current state for handshake messages*/
/* protected by recvBufLock */
sslBuffer messages; /* Accumulated handshake messages */
-@@ -1548,6 +1557,8 @@ extern SECStatus ssl3_HandleSupportedPoi
+@@ -1625,6 +1634,8 @@ extern SECStatus ssl3_HandleSupportedPoi
PRUint16 ex_type, SECItem *data);
extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss,
PRUint16 ex_type, SECItem *data);
@@ -367,7 +367,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ss
extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
PRUint16 ex_type, SECItem *data);
-@@ -1557,6 +1568,8 @@ extern SECStatus ssl3_ServerHandleSessio
+@@ -1634,6 +1645,8 @@ extern SECStatus ssl3_ServerHandleSessio
*/
extern PRInt32 ssl3_SendSessionTicketXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
@@ -376,10 +376,10 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ss
/* ClientHello and ServerHello extension senders.
* The code is in ssl3ext.c.
-diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c
---- a/src/net/third_party/nss/ssl/sslsock.c 2012-03-19 14:34:10.083984085 -0700
-+++ b/src/net/third_party/nss/ssl/sslsock.c 2012-03-19 14:34:51.634539426 -0700
-@@ -185,7 +185,8 @@ static sslOptions ssl_defaults = {
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:17:00.432983977 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:28:27.943078167 -0800
+@@ -153,7 +153,8 @@ static sslOptions ssl_defaults = {
2, /* enableRenegotiation (default: requires extension) */
PR_FALSE, /* requireSafeNegotiation */
PR_FALSE, /* enableFalseStart */
@@ -389,7 +389,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ss
};
/*
-@@ -812,6 +813,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
+@@ -827,6 +828,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
ss->opt.cbcRandomIV = on;
break;
@@ -400,7 +400,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ss
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
-@@ -881,6 +886,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
+@@ -896,6 +901,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
on = ss->opt.requireSafeNegotiation; break;
case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break;
case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break;
@@ -408,7 +408,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ss
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
-@@ -939,6 +945,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
+@@ -954,6 +960,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
break;
case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break;
case SSL_CBC_RANDOM_IV: on = ssl_defaults.cbcRandomIV; break;
@@ -418,7 +418,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ss
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
-@@ -1098,6 +1107,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
+@@ -1117,6 +1126,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
ssl_defaults.cbcRandomIV = on;
break;
@@ -429,7 +429,7 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ss
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
-@@ -1735,6 +1748,36 @@ SSL_VersionRangeSet(PRFileDesc *fd, cons
+@@ -1859,6 +1872,36 @@ SSL_VersionRangeSet(PRFileDesc *fd, cons
return SECSuccess;
}
@@ -466,10 +466,10 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ss
/************************************************************************/
/* The following functions are the TOP LEVEL SSL functions.
** They all get called through the NSPRIOMethods table below.
-diff -pu -r a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/sslt.h
---- a/src/net/third_party/nss/ssl/sslt.h 2012-03-15 18:23:55.000000000 -0700
-+++ b/src/net/third_party/nss/ssl/sslt.h 2012-03-19 14:34:51.634539426 -0700
-@@ -207,6 +207,7 @@ typedef enum {
+diff -pu -r a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
+--- a/net/third_party/nss/ssl/sslt.h 2012-06-06 19:06:19.000000000 -0700
++++ b/net/third_party/nss/ssl/sslt.h 2012-11-09 15:29:10.333701086 -0800
+@@ -175,6 +175,7 @@ typedef enum {
/* Update SSL_MAX_EXTENSIONS whenever a new extension type is added. */
typedef enum {
ssl_server_name_xtn = 0,
@@ -477,11 +477,11 @@ diff -pu -r a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/s
#ifdef NSS_ENABLE_ECC
ssl_elliptic_curves_xtn = 10,
ssl_ec_point_formats_xtn = 11,
-@@ -216,6 +217,6 @@ typedef enum {
+@@ -185,6 +186,6 @@ typedef enum {
ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
} SSLExtensionType;
--#define SSL_MAX_EXTENSIONS 6
-+#define SSL_MAX_EXTENSIONS 7
+-#define SSL_MAX_EXTENSIONS 7
++#define SSL_MAX_EXTENSIONS 8
#endif /* __sslt_h_ */
diff --git a/net/third_party/nss/patches/peercertchain.patch b/net/third_party/nss/patches/peercertchain.patch
index 4a3966a..b54bce7 100644
--- a/net/third_party/nss/patches/peercertchain.patch
+++ b/net/third_party/nss/patches/peercertchain.patch
@@ -1,52 +1,7 @@
-Index: mozilla/security/nss/lib/ssl/ssl.h
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v
-retrieving revision 1.49
-diff -u -p -8 -r1.49 ssl.h
---- mozilla/security/nss/lib/ssl/ssl.h 15 Feb 2012 21:52:08 -0000 1.49
-+++ mozilla/security/nss/lib/ssl/ssl.h 29 Feb 2012 02:12:05 -0000
-@@ -331,16 +331,28 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(
- ** it will always return the server's certificate. If the server calls
- ** this, it may return NULL if client authentication is not enabled or
- ** if the client had no certificate when asked.
- ** "fd" the socket "file" descriptor
- */
- SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
-
- /*
-+** Return references to the certificates presented by the SSL peer.
-+** |maxNumCerts| must contain the size of the |certs| array. On successful
-+** return, |*numCerts| contains the number of certificates available and
-+** |certs| will contain references to as many certificates as would fit.
-+** Therefore if |*numCerts| contains a value less than or equal to
-+** |maxNumCerts|, then all certificates were returned.
-+*/
-+SSL_IMPORT SECStatus SSL_PeerCertificateChain(
-+ PRFileDesc *fd, CERTCertificate **certs,
-+ unsigned int *numCerts, unsigned int maxNumCerts);
-+
-+/*
- ** Authenticate certificate hook. Called when a certificate comes in
- ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
- ** certificate.
- **
- ** The authenticate certificate hook must return SECSuccess to indicate the
- ** certificate is valid, SECFailure to indicate the certificate is invalid,
- ** or SECWouldBlock if the application will authenticate the certificate
- ** asynchronously. SECWouldBlock is only supported for non-blocking sockets.
-Index: mozilla/security/nss/lib/ssl/sslauth.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslauth.c,v
-retrieving revision 1.17
-diff -u -p -8 -r1.17 sslauth.c
---- mozilla/security/nss/lib/ssl/sslauth.c 3 Aug 2010 18:48:45 -0000 1.17
-+++ mozilla/security/nss/lib/ssl/sslauth.c 29 Feb 2012 02:12:05 -0000
-@@ -55,16 +55,51 @@ SSL_PeerCertificate(PRFileDesc *fd)
- }
- if (ss->opt.useSecurity && ss->sec.peerCert) {
- return CERT_DupCertificate(ss->sec.peerCert);
- }
- return 0;
+diff -pu -r a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth.c
+--- a/net/third_party/nss/ssl/sslauth.c 2012-04-25 07:50:12.000000000 -0700
++++ b/net/third_party/nss/ssl/sslauth.c 2012-11-09 15:22:49.448098805 -0800
+@@ -28,6 +28,41 @@ SSL_PeerCertificate(PRFileDesc *fd)
}
/* NEED LOCKS IN HERE. */
@@ -88,8 +43,25 @@ diff -u -p -8 -r1.17 sslauth.c
CERTCertificate *
SSL_LocalCertificate(PRFileDesc *fd)
{
- sslSocket *ss;
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-09-21 14:58:43.000000000 -0700
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:22:49.448098805 -0800
+@@ -398,6 +398,18 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(
+ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
+ /*
++** Return references to the certificates presented by the SSL peer.
++** |maxNumCerts| must contain the size of the |certs| array. On successful
++** return, |*numCerts| contains the number of certificates available and
++** |certs| will contain references to as many certificates as would fit.
++** Therefore if |*numCerts| contains a value less than or equal to
++** |maxNumCerts|, then all certificates were returned.
++*/
++SSL_IMPORT SECStatus SSL_PeerCertificateChain(
++ PRFileDesc *fd, CERTCertificate **certs,
++ unsigned int *numCerts, unsigned int maxNumCerts);
++
++/*
+ ** Authenticate certificate hook. Called when a certificate comes in
+ ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
+ ** certificate.
diff --git a/net/third_party/nss/patches/recordlayerversion.patch b/net/third_party/nss/patches/recordlayerversion.patch
deleted file mode 100644
index 68135c7..0000000
--- a/net/third_party/nss/patches/recordlayerversion.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-Index: mozilla/security/nss/lib/ssl/sslimpl.h
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslimpl.h,v
-retrieving revision 1.106
-diff -u -p -r1.106 sslimpl.h
---- mozilla/security/nss/lib/ssl/sslimpl.h 14 Jun 2012 19:03:29 -0000 1.106
-+++ mozilla/security/nss/lib/ssl/sslimpl.h 17 Aug 2012 02:10:02 -0000
-@@ -251,6 +251,8 @@ struct sslSocketOpsStr {
- #define ssl_SEND_FLAG_NO_BUFFER 0x20000000
- #define ssl_SEND_FLAG_USE_EPOCH 0x10000000 /* DTLS only */
- #define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
-+#define ssl_SEND_FLAG_CAP_RECORD_VERSION \
-+ 0x04000000 /* TLS only */
- #define ssl_SEND_FLAG_MASK 0x7f000000
-
- /*
-@@ -1327,6 +1329,7 @@ extern SECStatus
- ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
- PRBool isServer,
- PRBool isDTLS,
-+ PRBool capRecordVersion,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen,
-Index: mozilla/security/nss/lib/ssl/ssl3con.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v
-retrieving revision 1.186
-diff -u -p -r1.186 ssl3con.c
---- mozilla/security/nss/lib/ssl/ssl3con.c 30 Jul 2012 00:47:36 -0000 1.186
-+++ mozilla/security/nss/lib/ssl/ssl3con.c 17 Aug 2012 02:10:02 -0000
-@@ -2060,6 +2060,7 @@ SECStatus
- ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
- PRBool isServer,
- PRBool isDTLS,
-+ PRBool capRecordVersion,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen,
-@@ -2219,8 +2220,13 @@ ssl3_CompressMACEncryptRecord(ssl3Cipher
- wrBuf->buf[11] = MSB(cipherBytes);
- wrBuf->buf[12] = LSB(cipherBytes);
- } else {
-- wrBuf->buf[1] = MSB(cwSpec->version);
-- wrBuf->buf[2] = LSB(cwSpec->version);
-+ SSL3ProtocolVersion version = cwSpec->version;
-+
-+ if (capRecordVersion) {
-+ version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
-+ }
-+ wrBuf->buf[1] = MSB(version);
-+ wrBuf->buf[2] = LSB(version);
- wrBuf->buf[3] = MSB(cipherBytes);
- wrBuf->buf[4] = LSB(cipherBytes);
- }
-@@ -2250,7 +2256,14 @@ ssl3_CompressMACEncryptRecord(ssl3Cipher
- * all ciphertext into the pending ciphertext buffer.
- * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
- * Forces the use of the provided epoch
-- *
-+ * ssl_SEND_FLAG_CAP_RECORD_VERSION
-+ * Caps the record layer version number of TLS ClientHello to { 3, 1 }
-+ * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
-+ * ClientHello.client_version and use the record layer version number
-+ * (TLSPlaintext.version) instead when negotiating protocol versions. In
-+ * addition, if the record layer version number of ClientHello is { 3, 2 }
-+ * (TLS 1.1) or higher, these servers reset the TCP connections. Set this
-+ * flag to work around such servers.
- */
- PRInt32
- ssl3_SendRecord( sslSocket * ss,
-@@ -2263,6 +2276,7 @@ ssl3_SendRecord( sslSocket * ss
- sslBuffer * wrBuf = &ss->sec.writeBuf;
- SECStatus rv;
- PRInt32 totalSent = 0;
-+ PRBool capRecordVersion;
-
- SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
- SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
-@@ -2271,6 +2285,17 @@ ssl3_SendRecord( sslSocket * ss
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
-+ capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
-+
-+ if (capRecordVersion) {
-+ /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
-+ * TLS initial ClientHello. */
-+ PORT_Assert(!IS_DTLS(ss));
-+ PORT_Assert(!ss->firstHsDone);
-+ PORT_Assert(type == content_handshake);
-+ PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
-+ }
-+
- if (ss->ssl3.initialized == PR_FALSE) {
- /* This can happen on a server if the very first incoming record
- ** looks like a defective ssl3 record (e.g. too long), and we're
-@@ -2327,7 +2352,8 @@ ssl3_SendRecord( sslSocket * ss
-
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
- ss->sec.isServer, IS_DTLS(ss),
-- type, pIn, 1, wrBuf);
-+ capRecordVersion, type, pIn,
-+ 1, wrBuf);
- if (rv != SECSuccess)
- goto spec_locked_loser;
-
-@@ -2340,7 +2366,8 @@ ssl3_SendRecord( sslSocket * ss
-
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
- ss->sec.isServer, IS_DTLS(ss),
-- type, pIn + 1, contentLen - 1,
-+ capRecordVersion, type,
-+ pIn + 1, contentLen - 1,
- &secondRecord);
- if (rv == SECSuccess) {
- PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
-@@ -2352,6 +2379,7 @@ ssl3_SendRecord( sslSocket * ss
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
- ss->sec.isServer,
- IS_DTLS(ss),
-+ capRecordVersion,
- type, pIn,
- contentLen, wrBuf);
- } else {
-@@ -2563,6 +2591,8 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt
- static SECStatus
- ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
- {
-+ static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
-+ ssl_SEND_FLAG_CAP_RECORD_VERSION;
- PRInt32 rv = SECSuccess;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-@@ -2571,9 +2601,9 @@ ssl3_FlushHandshakeMessages(sslSocket *s
- if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
- return rv;
-
-- /* only this flag is allowed */
-- PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER));
-- if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) {
-+ /* only these flags are allowed */
-+ PORT_Assert(!(flags & ~allowedFlags));
-+ if ((flags & ~allowedFlags) != 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
-@@ -4000,8 +4030,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- int num_suites;
- int actual_count = 0;
- PRBool isTLS = PR_FALSE;
-+ PRBool requestingResume = PR_FALSE;
- PRInt32 total_exten_len = 0;
- unsigned numCompressionMethods;
-+ PRInt32 flags;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
- ss->fd));
-@@ -4090,6 +4122,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- }
-
- if (sid) {
-+ requestingResume = PR_TRUE;
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
-
- /* Are we attempting a stateless session resume? */
-@@ -4325,7 +4358,11 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- ssl_renegotiation_info_xtn;
- }
-
-- rv = ssl3_FlushHandshake(ss, 0);
-+ flags = 0;
-+ if (!ss->firstHsDone && !requestingResume && !IS_DTLS(ss)) {
-+ flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
-+ }
-+ rv = ssl3_FlushHandshake(ss, flags);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
-Index: mozilla/security/nss/lib/ssl/dtlscon.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/dtlscon.c,v
-retrieving revision 1.3
-diff -u -p -r1.3 dtlscon.c
---- mozilla/security/nss/lib/ssl/dtlscon.c 4 Jul 2012 15:21:47 -0000 1.3
-+++ mozilla/security/nss/lib/ssl/dtlscon.c 17 Aug 2012 02:10:02 -0000
-@@ -802,7 +802,8 @@ dtls_CompressMACEncryptRecord(sslSocket
-
- if (cwSpec) {
- rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
-- type, pIn, contentLen, wrBuf);
-+ PR_FALSE, type, pIn, contentLen,
-+ wrBuf);
- } else {
- PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
diff --git a/net/third_party/nss/patches/renegoclientversion.patch b/net/third_party/nss/patches/renegoclientversion.patch
deleted file mode 100644
index 718d941..0000000
--- a/net/third_party/nss/patches/renegoclientversion.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-Index: mozilla/security/nss/lib/ssl/ssl3con.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v
-retrieving revision 1.186
-diff -u -p -r1.186 ssl3con.c
---- mozilla/security/nss/lib/ssl/ssl3con.c 30 Jul 2012 00:47:36 -0000 1.186
-+++ mozilla/security/nss/lib/ssl/ssl3con.c 17 Aug 2012 02:23:29 -0000
-@@ -4028,6 +4028,23 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- return rv;
- }
-
-+ /*
-+ * During a renegotiation, ss->clientHelloVersion will be used again to
-+ * work around a Windows SChannel bug. Ensure that it is still enabled.
-+ */
-+ if (ss->firstHsDone) {
-+ if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-+ PORT_SetError(SSL_ERROR_SSL_DISABLED);
-+ return SECFailure;
-+ }
-+
-+ if (ss->clientHelloVersion < ss->vrange.min ||
-+ ss->clientHelloVersion > ss->vrange.max) {
-+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-+ return SECFailure;
-+ }
-+ }
-+
- /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
- * handles expired entries and other details.
- * XXX If we've been called from ssl2_BeginClientHandshake, then
-@@ -4075,9 +4092,41 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- sidOK = PR_FALSE;
- }
-
-- if (sidOK && ssl3_NegotiateVersion(ss, sid->version,
-- PR_FALSE) != SECSuccess) {
-- sidOK = PR_FALSE;
-+ /* TLS 1.0 (RFC 2246) Appendix E says:
-+ * Whenever a client already knows the highest protocol known to
-+ * a server (for example, when resuming a session), it should
-+ * initiate the connection in that native protocol.
-+ * So we pass sid->version to ssl3_NegotiateVersion() here, except
-+ * when renegotiating.
-+ *
-+ * Windows SChannel compares the client_version inside the RSA
-+ * EncryptedPreMasterSecret of a renegotiation with the
-+ * client_version of the initial ClientHello rather than the
-+ * ClientHello in the renegotiation. To work around this bug, we
-+ * continue to use the client_version used in the initial
-+ * ClientHello when renegotiating.
-+ */
-+ if (sidOK) {
-+ if (ss->firstHsDone) {
-+ /*
-+ * The client_version of the initial ClientHello is still
-+ * available in ss->clientHelloVersion. Ensure that
-+ * sid->version is bounded within
-+ * [ss->vrange.min, ss->clientHelloVersion], otherwise we
-+ * can't use sid.
-+ */
-+ if (sid->version >= ss->vrange.min &&
-+ sid->version <= ss->clientHelloVersion) {
-+ ss->version = ss->clientHelloVersion;
-+ } else {
-+ sidOK = PR_FALSE;
-+ }
-+ } else {
-+ if (ssl3_NegotiateVersion(ss, sid->version,
-+ PR_FALSE) != SECSuccess) {
-+ sidOK = PR_FALSE;
-+ }
-+ }
- }
-
- if (!sidOK) {
-@@ -4104,10 +4153,22 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- } else {
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
-
-- rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
-- PR_TRUE);
-- if (rv != SECSuccess)
-- return rv; /* error code was set */
-+ /*
-+ * Windows SChannel compares the client_version inside the RSA
-+ * EncryptedPreMasterSecret of a renegotiation with the
-+ * client_version of the initial ClientHello rather than the
-+ * ClientHello in the renegotiation. To work around this bug, we
-+ * continue to use the client_version used in the initial
-+ * ClientHello when renegotiating.
-+ */
-+ if (ss->firstHsDone) {
-+ ss->version = ss->clientHelloVersion;
-+ } else {
-+ rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
-+ PR_TRUE);
-+ if (rv != SECSuccess)
-+ return rv; /* error code was set */
-+ }
-
- sid = ssl3_NewSessionID(ss, PR_FALSE);
- if (!sid) {
-@@ -4207,6 +4268,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
-+ if (ss->firstHsDone) {
-+ /* Work around the Windows SChannel bug described above. */
-+ PORT_Assert(ss->version == ss->clientHelloVersion);
-+ }
- ss->clientHelloVersion = ss->version;
- if (IS_DTLS(ss)) {
- PRUint16 version;
diff --git a/net/third_party/nss/patches/renegoscsv.patch b/net/third_party/nss/patches/renegoscsv.patch
index ffade26..14822a1 100644
--- a/net/third_party/nss/patches/renegoscsv.patch
+++ b/net/third_party/nss/patches/renegoscsv.patch
@@ -1,7 +1,7 @@
-diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c
---- a/src/net/third_party/nss/ssl/ssl3con.c 2012-03-17 17:31:19.000000000 -0700
-+++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-03-19 12:35:33.058193252 -0700
-@@ -3966,9 +3966,9 @@ ssl3_SendClientHello(sslSocket *ss)
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-09-27 22:10:25.000000000 -0700
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:18:00.923858639 -0800
+@@ -4236,9 +4236,9 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
return SECFailure; /* ssl3_config_match_init has set error code. */
/* HACK for SCSV in SSL 3.0. On initial handshake, prepend SCSV,
diff --git a/net/third_party/nss/patches/restartclientauth.patch b/net/third_party/nss/patches/restartclientauth.patch
index df31c37..b92b24e 100644
--- a/net/third_party/nss/patches/restartclientauth.patch
+++ b/net/third_party/nss/patches/restartclientauth.patch
@@ -1,22 +1,7 @@
-diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h
---- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 17:49:08.431530583 -0800
-+++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 19:07:19.298439815 -0800
-@@ -306,6 +306,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(
- SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
- PRIntervalTime timeout);
-
-+SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd,
-+ CERTCertificate *cert,
-+ SECKEYPrivateKey *key,
-+ CERTCertificateList *certChain);
-+
- /*
- ** Query security status of socket. *on is set to one if security is
- ** enabled. *keySize will contain the stream key size used. *issuer will
-diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c
---- a/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 17:49:08.431530583 -0800
-+++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-02-29 18:55:27.038466043 -0800
-@@ -5769,6 +5769,85 @@ done:
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:48:41.260860199 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 15:49:25.751511020 -0800
+@@ -6148,6 +6148,85 @@ done:
return rv;
}
@@ -102,10 +87,25 @@ diff -up a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/s
PRBool
ssl3_CanFalseStart(sslSocket *ss) {
PRBool rv;
-diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h
---- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 17:49:08.431530583 -0800
-+++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 19:05:27.766882356 -0800
-@@ -1392,15 +1392,16 @@ extern SECStatus ssl3_MasterKeyDeriveBy
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 15:48:41.260860199 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 15:49:25.751511020 -0800
+@@ -367,6 +367,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(
+ SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
+ PRIntervalTime timeout);
+
++SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd,
++ CERTCertificate *cert,
++ SECKEYPrivateKey *key,
++ CERTCertificateList *certChain);
++
+ /*
+ ** Query security status of socket. *on is set to one if security is
+ ** enabled. *keySize will contain the stream key size used. *issuer will
+diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:48:41.260860199 -0800
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 15:51:26.623278555 -0800
+@@ -1484,16 +1484,17 @@ extern SECStatus ssl3_MasterKeyDeriveBy
/* These functions are called from secnav, even though they're "private". */
extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
@@ -117,6 +117,7 @@ diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/s
extern void ssl_FreeSocket(struct sslSocketStr *ssl);
extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
SSL3AlertDescription desc);
+ extern SECStatus ssl3_DecodeError(sslSocket *ss);
+extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
+ CERTCertificate * cert,
@@ -126,10 +127,10 @@ diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/s
extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
/*
-diff -up a/src/net/third_party/nss/ssl/sslsecur.c b/src/net/third_party/nss/ssl/sslsecur.c
---- a/src/net/third_party/nss/ssl/sslsecur.c 2012-02-28 16:15:34.790321976 -0800
-+++ b/src/net/third_party/nss/ssl/sslsecur.c 2012-02-29 19:01:32.303586125 -0800
-@@ -1468,17 +1468,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT
+diff -pu -r a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c
+--- a/net/third_party/nss/ssl/sslsecur.c 2012-11-09 15:17:00.432983977 -0800
++++ b/net/third_party/nss/ssl/sslsecur.c 2012-11-09 15:49:25.751511020 -0800
+@@ -1437,17 +1437,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT
return SECSuccess;
}
diff --git a/net/third_party/nss/patches/secretexporterlocks.patch b/net/third_party/nss/patches/secretexporterlocks.patch
new file mode 100644
index 0000000..a7fe305
--- /dev/null
+++ b/net/third_party/nss/patches/secretexporterlocks.patch
@@ -0,0 +1,44 @@
+diff -pu -r a/net/third_party/nss/ssl/sslinfo.c b/net/third_party/nss/ssl/sslinfo.c
+--- a/net/third_party/nss/ssl/sslinfo.c 2012-08-03 16:54:31.000000000 -0700
++++ b/net/third_party/nss/ssl/sslinfo.c 2012-11-12 16:14:30.596704310 -0800
+@@ -342,8 +342,13 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
+ return SECFailure;
+ }
+
++ ssl_GetRecvBufLock(ss);
++ ssl_GetSSL3HandshakeLock(ss);
++
+ if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
+ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
++ ssl_ReleaseSSL3HandshakeLock(ss);
++ ssl_ReleaseRecvBufLock(ss);
+ return SECFailure;
+ }
+
+@@ -354,13 +359,17 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
+ }
+ val = PORT_Alloc(valLen);
+ if (!val) {
++ ssl_ReleaseSSL3HandshakeLock(ss);
++ ssl_ReleaseRecvBufLock(ss);
+ return SECFailure;
+ }
+ i = 0;
++
+ PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
+ i += SSL3_RANDOM_LENGTH;
+ PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
+ i += SSL3_RANDOM_LENGTH;
++
+ if (hasContext) {
+ val[i++] = contextLen >> 8;
+ val[i++] = contextLen;
+@@ -381,6 +390,8 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
+ valLen, out, outLen);
+ }
+ ssl_ReleaseSpecReadLock(ss);
++ ssl_ReleaseSSL3HandshakeLock(ss);
++ ssl_ReleaseRecvBufLock(ss);
+
+ PORT_ZFree(val, valLen);
+ return rv;
diff --git a/net/third_party/nss/patches/sslkeylogerror.patch b/net/third_party/nss/patches/sslkeylogerror.patch
index 7dd57c2..048d0cc 100644
--- a/net/third_party/nss/patches/sslkeylogerror.patch
+++ b/net/third_party/nss/patches/sslkeylogerror.patch
@@ -1,8 +1,7 @@
-diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
-index 1823a1c..2a93dae 100644
---- a/net/third_party/nss/ssl/sslsock.c
-+++ b/net/third_party/nss/ssl/sslsock.c
-@@ -2934,11 +2934,15 @@ ssl_SetDefaultsFromEnvironment(void)
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 16:16:23.715038258 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 16:19:18.517565894 -0800
+@@ -2906,11 +2906,15 @@ ssl_SetDefaultsFromEnvironment(void)
ev = getenv("SSLKEYLOGFILE");
if (ev && ev[0]) {
ssl_keylog_iob = fopen(ev, "a");
@@ -16,9 +15,9 @@ index 1823a1c..2a93dae 100644
+ fputs("# SSL/TLS secrets log file, generated by NSS\n",
+ ssl_keylog_iob);
+ }
-+ SSL_TRACE(("SSL: logging pre-master secrets to %s", ev));
++ SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
}
-- SSL_TRACE(("SSL: logging pre-master secrets to %s", ev));
+- SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
}
+ #ifndef NO_PKCS11_BYPASS
ev = getenv("SSLBYPASS");
- if (ev && ev[0]) {
diff --git a/net/third_party/nss/patches/sslprotocolvariant.patch b/net/third_party/nss/patches/sslprotocolvariant.patch
deleted file mode 100644
index 181645d..0000000
--- a/net/third_party/nss/patches/sslprotocolvariant.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-Index: mozilla/security/nss/lib/ssl/ssl3con.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v
-retrieving revision 1.186
-diff -u -p -8 -r1.186 ssl3con.c
---- mozilla/security/nss/lib/ssl/ssl3con.c 30 Jul 2012 00:47:36 -0000 1.186
-+++ mozilla/security/nss/lib/ssl/ssl3con.c 15 Aug 2012 00:29:49 -0000
-@@ -770,17 +770,17 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL
-
- if (peerVersion < ss->vrange.min ||
- (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
-
- ss->version = PR_MIN(peerVersion, ss->vrange.max);
-- PORT_Assert(ssl3_VersionIsSupported(ssl_variant_stream, ss->version));
-+ PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version));
-
- return SECSuccess;
- }
-
- static SECStatus
- ssl3_GetNewRandom(SSL3Random *random)
- {
- PRUint32 gmt = ssl_Time();
-Index: mozilla/security/nss/lib/ssl/sslsock.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsock.c,v
-retrieving revision 1.93
-diff -u -p -8 -r1.93 sslsock.c
---- mozilla/security/nss/lib/ssl/sslsock.c 14 Jun 2012 19:03:29 -0000 1.93
-+++ mozilla/security/nss/lib/ssl/sslsock.c 15 Aug 2012 00:29:49 -0000
-@@ -1843,17 +1843,17 @@ SSL_VersionRangeSet(PRFileDesc *fd, cons
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeSet",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
-- if (!ssl3_VersionRangeIsValid(ssl_variant_stream, vrange)) {
-+ if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
- PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- ss->vrange = *vrange;
diff --git a/net/third_party/nss/patches/tlsunique.patch b/net/third_party/nss/patches/tlsunique.patch
index ed7fe49..a4214a4 100644
--- a/net/third_party/nss/patches/tlsunique.patch
+++ b/net/third_party/nss/patches/tlsunique.patch
@@ -1,40 +1,7 @@
-diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
-index bb8c0b7..518cb21 100644
---- a/net/third_party/nss/ssl/ssl.h
-+++ b/net/third_party/nss/ssl/ssl.h
-@@ -282,6 +282,27 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
- SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
- SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
-
-+/* SSLChannelBindingType enumerates the types of supported channel binding
-+ * values. See RFC 5929. */
-+typedef enum SSLChannelBindingType {
-+ SSL_CHANNEL_BINDING_TLS_UNIQUE = 1,
-+} SSLChannelBindingType;
-+
-+/* SSL_GetChannelBinding copies the requested channel binding value, as defined
-+ * in RFC 5929, into |out|. The full length of the binding value is written
-+ * into |*outLen|.
-+ *
-+ * At most |outLenMax| bytes of data are copied. If |outLenMax| is
-+ * insufficient then the function returns SECFailure and sets the error to
-+ * SEC_ERROR_OUTPUT_LEN, but |*outLen| is still set.
-+ *
-+ * This call will fail if made during a renegotiation. */
-+SSL_IMPORT SECStatus SSL_GetChannelBinding(PRFileDesc *fd,
-+ SSLChannelBindingType binding_type,
-+ unsigned char *out,
-+ unsigned int *outLen,
-+ unsigned int outLenMax);
-+
- /* SSL Version Range API
- **
- ** This API should be used to control SSL 3.0 & TLS support instead of the
-diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
-index 0f1cdc6..1f6def2 100644
---- a/net/third_party/nss/ssl/ssl3con.c
-+++ b/net/third_party/nss/ssl/ssl3con.c
-@@ -10539,6 +10539,68 @@ ssl3_InitSocketPolicy(sslSocket *ss)
+diff -pu -r a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
+--- a/net/third_party/nss/ssl/ssl3con.c 2012-11-09 16:13:22.012407752 -0800
++++ b/net/third_party/nss/ssl/ssl3con.c 2012-11-09 16:14:14.123162240 -0800
+@@ -10719,6 +10719,68 @@ ssl3_InitSocketPolicy(sslSocket *ss)
PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
}
@@ -103,11 +70,41 @@ index 0f1cdc6..1f6def2 100644
/* ssl3_config_match_init must have already been called by
* the caller of this function.
*/
-diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
-index adad5d0..eda1885 100644
---- a/net/third_party/nss/ssl/sslimpl.h
-+++ b/net/third_party/nss/ssl/sslimpl.h
-@@ -1775,6 +1775,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
+diff -pu -r a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
+--- a/net/third_party/nss/ssl/ssl.h 2012-11-09 16:13:22.062408475 -0800
++++ b/net/third_party/nss/ssl/ssl.h 2012-11-09 16:14:14.123162240 -0800
+@@ -250,6 +250,27 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDe
+ SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
+ SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
+
++/* SSLChannelBindingType enumerates the types of supported channel binding
++ * values. See RFC 5929. */
++typedef enum SSLChannelBindingType {
++ SSL_CHANNEL_BINDING_TLS_UNIQUE = 1,
++} SSLChannelBindingType;
++
++/* SSL_GetChannelBinding copies the requested channel binding value, as defined
++ * in RFC 5929, into |out|. The full length of the binding value is written
++ * into |*outLen|.
++ *
++ * At most |outLenMax| bytes of data are copied. If |outLenMax| is
++ * insufficient then the function returns SECFailure and sets the error to
++ * SEC_ERROR_OUTPUT_LEN, but |*outLen| is still set.
++ *
++ * This call will fail if made during a renegotiation. */
++SSL_IMPORT SECStatus SSL_GetChannelBinding(PRFileDesc *fd,
++ SSLChannelBindingType binding_type,
++ unsigned char *out,
++ unsigned int *outLen,
++ unsigned int outLenMax);
++
+ /* SSL Version Range API
+ **
+ ** This API should be used to control SSL 3.0 & TLS support instead of the
+diff -pu -r a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
+--- a/net/third_party/nss/ssl/sslimpl.h 2012-11-09 16:13:22.062408475 -0800
++++ b/net/third_party/nss/ssl/sslimpl.h 2012-11-09 16:14:14.123162240 -0800
+@@ -1732,6 +1732,11 @@ extern PRBool ssl_GetSessionTicketKeysPK
extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
unsigned int length);
@@ -119,11 +116,10 @@ index adad5d0..eda1885 100644
/* Construct a new NSPR socket for the app to use */
extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
extern void ssl_FreePRSocket(PRFileDesc *fd);
-diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
-index 9387a21..1823a1c 100644
---- a/net/third_party/nss/ssl/sslsock.c
-+++ b/net/third_party/nss/ssl/sslsock.c
-@@ -1382,6 +1382,27 @@ NSS_SetFrancePolicy(void)
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-11-09 16:13:22.062408475 -0800
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 16:14:14.123162240 -0800
+@@ -1354,6 +1354,27 @@ NSS_SetFrancePolicy(void)
return NSS_SetDomesticPolicy();
}
diff --git a/net/third_party/nss/patches/versionskew.patch b/net/third_party/nss/patches/versionskew.patch
index c55df5a..0b62b67 100644
--- a/net/third_party/nss/patches/versionskew.patch
+++ b/net/third_party/nss/patches/versionskew.patch
@@ -1,18 +1,7 @@
-From 9a71b466147bcd334243d62996558a609657c07c Mon Sep 17 00:00:00 2001
-From: Adam Langley <agl@chromium.org>
-Date: Mon, 3 Oct 2011 12:19:48 -0400
-Subject: [PATCH] versionskew.patch
-
----
- mozilla/security/nss/lib/ssl/sslsecur.c | 5 +++++
- mozilla/security/nss/lib/ssl/sslsock.c | 6 ++++++
- 2 files changed, 11 insertions(+), 0 deletions(-)
-
-diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ssl/sslsecur.c
-index a0cae54..816b8f6 100644
---- a/mozilla/security/nss/lib/ssl/sslsecur.c
-+++ b/mozilla/security/nss/lib/ssl/sslsecur.c
-@@ -1316,6 +1316,10 @@ SSL_SetURL(PRFileDesc *fd, const char *url)
+diff -pu -r a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c
+--- a/net/third_party/nss/ssl/sslsecur.c 2012-05-24 13:34:51.000000000 -0700
++++ b/net/third_party/nss/ssl/sslsecur.c 2012-11-09 15:15:21.901558709 -0800
+@@ -1312,6 +1312,10 @@ SSL_SetURL(PRFileDesc *fd, const char *u
SECStatus
SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
{
@@ -23,7 +12,7 @@ index a0cae54..816b8f6 100644
sslSocket * ss = ssl_FindSocket(fd);
CERTDistNames *names = NULL;
-@@ -1343,6 +1347,7 @@ SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
+@@ -1339,6 +1343,7 @@ SSL_SetTrustAnchors(PRFileDesc *fd, CERT
ssl_Release1stHandshakeLock(ss);
return SECSuccess;
@@ -31,11 +20,10 @@ index a0cae54..816b8f6 100644
}
/*
-diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c
-index 4c8fbfd..b7e32a2 100644
---- a/mozilla/security/nss/lib/ssl/sslsock.c
-+++ b/mozilla/security/nss/lib/ssl/sslsock.c
-@@ -1343,6 +1343,11 @@ SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf,
+diff -pu -r a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
+--- a/net/third_party/nss/ssl/sslsock.c 2012-09-24 16:57:42.000000000 -0700
++++ b/net/third_party/nss/ssl/sslsock.c 2012-11-09 15:15:21.901558709 -0800
+@@ -1603,6 +1603,11 @@ SSL_GetSRTPCipher(PRFileDesc *fd, PRUint
PRFileDesc *
SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
{
@@ -46,12 +34,12 @@ index 4c8fbfd..b7e32a2 100644
+#if 0
sslSocket * sm = NULL, *ss = NULL;
int i;
- sslServerCerts * mc = sm->serverCerts;
-@@ -1445,6 +1450,7 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
+ sslServerCerts * mc = NULL;
+@@ -1711,6 +1716,7 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile
return fd;
loser:
return NULL;
+#endif
}
- /************************************************************************/
+ PRBool