| Index: net/third_party/nss/patches/dtlssrtp.patch
|
| ===================================================================
|
| --- net/third_party/nss/patches/dtlssrtp.patch (revision 166942)
|
| +++ net/third_party/nss/patches/dtlssrtp.patch (working copy)
|
| @@ -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_ */
|
|
|