summaryrefslogtreecommitdiffstats
path: root/net/third_party/nss
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-19 00:44:45 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-19 00:44:45 +0000
commitce8b05730722ba50d9cb6877adef9f53258dd9ca (patch)
tree78c6ed7a1dacb874a322406b3344b12ae2449818 /net/third_party/nss
parent0aee3ae07de2362b81598fab60f4009c96cbcbfe (diff)
downloadchromium_src-ce8b05730722ba50d9cb6877adef9f53258dd9ca.zip
chromium_src-ce8b05730722ba50d9cb6877adef9f53258dd9ca.tar.gz
chromium_src-ce8b05730722ba50d9cb6877adef9f53258dd9ca.tar.bz2
Add the NSS patch file for RFC 5764 (DTLS-SRTP) support.
I forgot to do this in https://chromiumcodereview.appspot.com/9982019. TBR=rsleevi@chromium.org,ekr@rtfm.com BUG=120938 TEST=none Review URL: https://chromiumcodereview.appspot.com/10572010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142878 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party/nss')
-rw-r--r--net/third_party/nss/README.chromium4
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh2
-rw-r--r--net/third_party/nss/patches/dtlssrtp.patch468
3 files changed, 474 insertions, 0 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index 2d11f97..8c5cb4a 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -65,6 +65,10 @@ Patches:
* Add support for TLS Channel IDs
patches/channelid.patch
+ * Add DTLS-SRTP (RFC 5764) support.
+ https://bugzilla.mozilla.org/show_bug.cgi?id=737178
+ patches/dtlssrtp.patch
+
* Move SSL keylogging out from behind the TRACE and DEBUG defines and add
support for CLIENT_RANDOM keylogging to support ECDHE-RSA and others.
patches/keylog.patch
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index 2fe85a2..4ee279d 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -38,4 +38,6 @@ patch -p5 < $patches_dir/dhvalues.patch
patch -p4 < $patches_dir/channelid.patch
+patch -p4 < $patches_dir/dtlssrtp.patch
+
patch -p4 < $patches_dir/keylog.patch
diff --git a/net/third_party/nss/patches/dtlssrtp.patch b/net/third_party/nss/patches/dtlssrtp.patch
new file mode 100644
index 0000000..fefc6c4
--- /dev/null
+++ b/net/third_party/nss/patches/dtlssrtp.patch
@@ -0,0 +1,468 @@
+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_ */