diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-19 00:44:45 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-19 00:44:45 +0000 |
commit | ce8b05730722ba50d9cb6877adef9f53258dd9ca (patch) | |
tree | 78c6ed7a1dacb874a322406b3344b12ae2449818 /net/third_party/nss | |
parent | 0aee3ae07de2362b81598fab60f4009c96cbcbfe (diff) | |
download | chromium_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.chromium | 4 | ||||
-rwxr-xr-x | net/third_party/nss/patches/applypatches.sh | 2 | ||||
-rw-r--r-- | net/third_party/nss/patches/dtlssrtp.patch | 468 |
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_ */ |