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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * SSL3 Protocol 2 * SSL3 Protocol
3 * 3 *
4 * ***** BEGIN LICENSE BLOCK ***** 4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * 6 *
7 * The contents of this file are subject to the Mozilla Public License Version 7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with 8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at 9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/ 10 * http://www.mozilla.org/MPL/
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, 83 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
84 PRUint16 ex_type, SECItem *data); 84 PRUint16 ex_type, SECItem *data);
85 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, 85 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
86 PRUint32 maxBytes); 86 PRUint32 maxBytes);
87 static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, 87 static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss,
88 PRUint16 ex_type, SECItem *data); 88 PRUint16 ex_type, SECItem *data);
89 static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, 89 static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss,
90 PRUint16 ex_type, SECItem *data); 90 PRUint16 ex_type, SECItem *data);
91 static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, 91 static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss,
92 PRBool append, PRUint32 maxBytes); 92 PRBool append, PRUint32 maxBytes);
93 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
94 PRUint32 maxBytes);
95 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
96 SECItem *data);
93 97
94 /* 98 /*
95 * Write bytes. Using this function means the SECItem structure 99 * Write bytes. Using this function means the SECItem structure
96 * cannot be freed. The caller is expected to call this function 100 * cannot be freed. The caller is expected to call this function
97 * on a shallow copy of the structure. 101 * on a shallow copy of the structure.
98 */ 102 */
99 static SECStatus 103 static SECStatus
100 ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes) 104 ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
101 { 105 {
102 if (bytes > item->len) 106 if (bytes > item->len)
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 247 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
244 #ifdef NSS_ENABLE_ECC 248 #ifdef NSS_ENABLE_ECC
245 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, 249 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
246 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, 250 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
247 #endif 251 #endif
248 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, 252 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
249 { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, 253 { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn },
250 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 254 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
251 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, 255 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
252 { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, 256 { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn },
257 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
253 { -1, NULL } 258 { -1, NULL }
254 }; 259 };
255 260
256 /* These two tables are used by the client, to handle server hello 261 /* These two tables are used by the client, to handle server hello
257 * extensions. */ 262 * extensions. */
258 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { 263 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
259 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 264 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
260 /* TODO: add a handler for ssl_ec_point_formats_xtn */ 265 /* TODO: add a handler for ssl_ec_point_formats_xtn */
261 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, 266 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
262 { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, 267 { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn },
263 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 268 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
264 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, 269 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
265 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, 270 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
266 { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, 271 { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn },
272 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn},
267 { -1, NULL } 273 { -1, NULL }
268 }; 274 };
269 275
270 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { 276 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
271 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 277 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
272 { -1, NULL } 278 { -1, NULL }
273 }; 279 };
274 280
275 /* Tables of functions to format TLS hello extensions, one function per 281 /* Tables of functions to format TLS hello extensions, one function per
276 * extension. 282 * extension.
277 * These static tables are for the formatting of client hello extensions. 283 * These static tables are for the formatting of client hello extensions.
278 * The server's table of hello senders is dynamic, in the socket struct, 284 * The server's table of hello senders is dynamic, in the socket struct,
279 * and sender functions are registered there. 285 * and sender functions are registered there.
280 */ 286 */
281 static const 287 static const
282 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { 288 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
283 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, 289 { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
284 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, 290 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
285 #ifdef NSS_ENABLE_ECC 291 #ifdef NSS_ENABLE_ECC
286 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, 292 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
287 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, 293 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
288 #endif 294 #endif
289 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, 295 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
290 { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, 296 { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn },
291 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, 297 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
292 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, 298 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
293 { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } 299 { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn },
300 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }
294 /* any extra entries will appear as { 0, NULL } */ 301 /* any extra entries will appear as { 0, NULL } */
295 }; 302 };
296 303
297 static const 304 static const
298 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { 305 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
299 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } 306 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
300 /* any extra entries will appear as { 0, NULL } */ 307 /* any extra entries will appear as { 0, NULL } */
301 }; 308 };
302 309
303 static PRBool 310 static PRBool
(...skipping 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 1868
1862 /* The echoed extension must be empty. */ 1869 /* The echoed extension must be empty. */
1863 if (data->len != 0) 1870 if (data->len != 0)
1864 return SECFailure; 1871 return SECFailure;
1865 1872
1866 /* Keep track of negotiated extensions. */ 1873 /* Keep track of negotiated extensions. */
1867 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 1874 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
1868 1875
1869 return SECSuccess; 1876 return SECSuccess;
1870 } 1877 }
1878
1879 static PRInt32
1880 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
1881 {
1882 PRUint32 ext_data_len;
1883 PRInt16 i;
1884 SECStatus rv;
1885
1886 if (!ss)
1887 return 0;
1888
1889 if (!ss->sec.isServer) {
1890 /* Client side */
1891
1892 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
1893 return 0; /* Not relevant */
1894
1895 ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
1896
1897 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
1898 /* Extension type */
1899 rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
1900 if (rv != SECSuccess) return -1;
1901 /* Length of extension data */
1902 rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
1903 if (rv != SECSuccess) return -1;
1904 /* Length of the SRTP cipher list */
1905 rv = ssl3_AppendHandshakeNumber(ss,
1906 2 * ss->ssl3.dtlsSRTPCipherCount,
1907 2);
1908 if (rv != SECSuccess) return -1;
1909 /* The SRTP ciphers */
1910 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
1911 rv = ssl3_AppendHandshakeNumber(ss,
1912 ss->ssl3.dtlsSRTPCiphers[i],
1913 2);
1914 }
1915 /* Empty MKI value */
1916 ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
1917
1918 ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
1919 ssl_use_srtp_xtn;
1920 }
1921
1922 return 4 + ext_data_len;
1923 }
1924
1925 /* Server side */
1926 if (append && maxBytes >= 9) {
1927 /* Extension type */
1928 rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
1929 if (rv != SECSuccess) return -1;
1930 /* Length of extension data */
1931 rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
1932 if (rv != SECSuccess) return -1;
1933 /* Length of the SRTP cipher list */
1934 rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
1935 if (rv != SECSuccess) return -1;
1936 /* The selected cipher */
1937 rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
1938 if (rv != SECSuccess) return -1;
1939 /* Empty MKI value */
1940 ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
1941 }
1942
1943 return 9;
1944 }
1945
1946 static SECStatus
1947 ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
1948 {
1949 SECStatus rv;
1950 PRInt16 i;
1951 PRInt16 bestIndex;
1952 PRBool found = PR_FALSE;
1953 SECItem litem;
1954 PRInt32 cipherLenBytes;
1955 PRInt32 cipher;
1956
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;
1957 if (!ss->sec.isServer) {
1958 /* Client side */
1959 if (!data->data || !data->len) {
1960 /* malformed */
1961 return SECFailure;
1962 }
1963
1964 if (data->len != 5) { /* Must always be 5 since we don't offer MKI */
1965 /* malformed */
1966 return SECFailure;
1967 }
1968
1969 /* Now check that the number of ciphers listed is 1 (len = 2) */
1970 cipherLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2,
1971 &data->data, &data->len);
1972 if (cipherLenBytes != 2)
1973 return SECFailure;
1974
1975 /* Get the selected cipher */
1976 cipher = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1977
1978 /* Now check that this is one of the ciphers we offered */
1979 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
1980 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
1981 found = PR_TRUE;
1982 break;
1983 }
1984 }
1985
1986 if (!found)
1987 return SECFailure;
1988
1989 /* Get the srtp_mki value */
1990 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
1991 &data->data, &data->len);
1992 if (rv != SECSuccess) {
1993 return SECFailure;
1994 }
1995 /* 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
1996 if (litem.len != 0)
1997 return SECFailure;
1998
1999 /* OK, this looks fine. */
2000 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
2001 ss->ssl3.dtlsSRTPCipherSuite = cipher;
2002 return SECSuccess;
2003 }
2004
2005 /* Server side */
2006 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
2007 /* Ignore the extension. */
2008 return SECSuccess;
ekr 2012/04/26 14:33:42 I would change this comment to say /* Ignore the e
2009 }
2010
2011 if (!data->data || data->len < 5) {
2012 /* malformed */
2013 return SECFailure;
2014 }
2015
2016 /* Get the length of the cipher list */
2017 cipherLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2,
2018 &data->data, &data->len);
2019 /* Check that there is room for the ciphers and that the list is even
2020 * length */
2021 if ((cipherLenBytes > (data->len - 1)) || (cipherLenBytes % 2))
2022 return SECFailure;
2023
2024 /* Walk through the offered list one at a time and pick the most preferred
2025 * of our ciphers, if any */
2026 while (cipherLenBytes > 0) {
2027 cipher = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
2028 cipherLenBytes -= 2;
2029
2030 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
2031 /* Unknown ciphers just go through the entire list */
2032 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
2033 if (!found || i < bestIndex) {
2034 bestIndex = i;
2035 }
2036 found = PR_TRUE;
2037 break;
2038 }
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
2039 }
2040 }
2041
2042 /* Get the srtp_mki value */
2043 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
2044 if (rv != SECSuccess) {
2045 return SECFailure;
2046 }
2047
2048 if (data->len)
2049 return SECFailure; /* Malformed */
2050
2051 /* Now figure out what to do */
2052 if (!found) {
2053 /* No matching ciphers */
2054 return SECSuccess;
2055 }
2056
2057 /* OK, we have a valid cipher and we've selected it */
2058 ss->ssl3.dtlsSRTPCipherSuite = ss->ssl3.dtlsSRTPCiphers[bestIndex];
2059 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
2060
2061 return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
2062 ssl3_SendUseSRTPXtn);
2063 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698