Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(797)

Unified Diff: net/third_party/nss/ssl/ssl3ext.c

Issue 9982019: Implement RFC 5764 (DTLS-SRTP). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: First full review Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/third_party/nss/ssl/ssl3ext.c
===================================================================
--- net/third_party/nss/ssl/ssl3ext.c (revision 130750)
+++ net/third_party/nss/ssl/ssl3ext.c (working copy)
@@ -90,6 +90,10 @@
PRUint16 ex_type, SECItem *data);
static PRInt32 ssl3_SendEncryptedClientCertsXtn(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
@@ -250,6 +254,7 @@
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
{ ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn },
+ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
{ -1, NULL }
};
@@ -264,6 +269,7 @@
{ ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
{ ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn },
+ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn},
{ -1, NULL }
};
@@ -290,7 +296,8 @@
{ ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn },
{ ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
- { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn }
+ { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn },
+ { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }
/* any extra entries will appear as { 0, NULL } */
};
@@ -1868,3 +1875,189 @@
return SECSuccess;
}
+
+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) {
ekr 2012/04/26 14:33:42 As a matter of style, I tend to add parentheses wh
wtc 2012/04/27 01:06:09 I removed these parentheses because I found the ot
ekr 2012/04/27 03:36:34 If it were me, I would do the first of these, but
+ /* 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;
+ PRInt16 i;
+ PRInt16 bestIndex;
+ PRBool found = PR_FALSE;
+ SECItem litem;
+ PRInt32 cipherLenBytes;
+ PRInt32 cipher;
+
ekr 2012/04/26 14:33:42 Why are these signed? Doesn't the encoding require
wtc 2012/04/27 01:06:09 These two variables are used to store the return v
ekr 2012/04/27 03:36:34 Ouch, that's not a good state of affairs, esp. sin
wtc 2012/04/27 17:32:55 We can also do if (x < 0) return SECFailure;
+ if (!ss->sec.isServer) {
+ /* Client side */
+ if (!data->data || !data->len) {
+ /* malformed */
+ return SECFailure;
+ }
+
+ if (data->len != 5) { /* Must always be 5 since we don't offer MKI */
+ /* malformed */
+ return SECFailure;
+ }
+
+ /* Now check that the number of ciphers listed is 1 (len = 2) */
+ cipherLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2,
+ &data->data, &data->len);
+ if (cipherLenBytes != 2)
+ return SECFailure;
+
+ /* Get the selected cipher */
+ cipher = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+
+ /* 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 */
wtc 2012/04/20 02:02:13 The RFC says: If the client detects a nonzero-le
ekr 2012/04/26 14:33:42 Did I misread your comment in c55 where it sounded
wtc 2012/04/27 01:06:09 You read my comment in c55 correctly. I did volun
ekr 2012/04/27 03:36:34 I think failing with no alert would be satisfactor
+ if (litem.len != 0)
+ 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. */
+ return SECSuccess;
ekr 2012/04/26 14:33:42 I would change this comment to say /* Ignore the e
+ }
+
+ if (!data->data || data->len < 5) {
+ /* malformed */
+ return SECFailure;
+ }
+
+ /* Get the length of the cipher list */
+ cipherLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2,
+ &data->data, &data->len);
+ /* Check that there is room for the ciphers and that the list is even
+ * length */
+ if ((cipherLenBytes > (data->len - 1)) || (cipherLenBytes % 2))
+ return SECFailure;
+
+ /* Walk through the offered list one at a time and pick the most preferred
+ * of our ciphers, if any */
+ while (cipherLenBytes > 0) {
+ cipher = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ cipherLenBytes -= 2;
+
+ for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
+ /* Unknown ciphers just go through the entire list */
+ if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
+ if (!found || i < bestIndex) {
+ bestIndex = i;
+ }
+ found = PR_TRUE;
+ break;
+ }
ekr 2012/04/26 14:33:42 This is arguably slightly less clear because it in
wtc 2012/04/27 01:06:09 This was my attempt to do bestIndex = i; in on
ekr 2012/04/27 03:36:34 I'm not sure I'm knowledgeable enough about SECIte
wtc 2012/04/27 17:32:55 Yes, I'll be happy to do that. I can make all the
+ }
+ }
+
+ /* Get the srtp_mki value */
+ rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ if (data->len)
+ 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 = ss->ssl3.dtlsSRTPCiphers[bestIndex];
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
+
+ return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
+ ssl3_SendUseSRTPXtn);
+}

Powered by Google App Engine
This is Rietveld 408576698