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

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: Sync before checkin Created 8 years, 6 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
« no previous file with comments | « net/third_party/nss/ssl/ssl.h ('k') | net/third_party/nss/ssl/sslimpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, 81 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
82 PRUint16 ex_type, SECItem *data); 82 PRUint16 ex_type, SECItem *data);
83 static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, 83 static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss,
84 PRUint16 ex_type, SECItem *data); 84 PRUint16 ex_type, SECItem *data);
85 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, 85 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
86 PRUint16 ex_type, SECItem *data); 86 PRUint16 ex_type, SECItem *data);
87 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, 87 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
88 PRUint32 maxBytes); 88 PRUint32 maxBytes);
89 static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, 89 static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
90 PRUint32 maxBytes); 90 PRUint32 maxBytes);
91 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
92 PRUint32 maxBytes);
93 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
94 SECItem *data);
91 95
92 /* 96 /*
93 * Write bytes. Using this function means the SECItem structure 97 * Write bytes. Using this function means the SECItem structure
94 * cannot be freed. The caller is expected to call this function 98 * cannot be freed. The caller is expected to call this function
95 * on a shallow copy of the structure. 99 * on a shallow copy of the structure.
96 */ 100 */
97 static SECStatus 101 static SECStatus
98 ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes) 102 ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
99 { 103 {
100 if (bytes > item->len) 104 if (bytes > item->len)
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 /* This table is used by the server, to handle client hello extensions. */ 243 /* This table is used by the server, to handle client hello extensions. */
240 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { 244 static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
241 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 245 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
242 #ifdef NSS_ENABLE_ECC 246 #ifdef NSS_ENABLE_ECC
243 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, 247 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
244 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, 248 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
245 #endif 249 #endif
246 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, 250 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
247 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 251 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
248 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, 252 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
253 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
249 { -1, NULL } 254 { -1, NULL }
250 }; 255 };
251 256
252 /* These two tables are used by the client, to handle server hello 257 /* These two tables are used by the client, to handle server hello
253 * extensions. */ 258 * extensions. */
254 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { 259 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
255 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 260 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
256 /* TODO: add a handler for ssl_ec_point_formats_xtn */ 261 /* TODO: add a handler for ssl_ec_point_formats_xtn */
257 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, 262 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
258 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 263 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
259 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, 264 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
260 { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, 265 { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
261 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, 266 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
267 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn},
262 { -1, NULL } 268 { -1, NULL }
263 }; 269 };
264 270
265 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { 271 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
266 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 272 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
267 { -1, NULL } 273 { -1, NULL }
268 }; 274 };
269 275
270 /* Tables of functions to format TLS hello extensions, one function per 276 /* Tables of functions to format TLS hello extensions, one function per
271 * extension. 277 * extension.
272 * These static tables are for the formatting of client hello extensions. 278 * These static tables are for the formatting of client hello extensions.
273 * The server's table of hello senders is dynamic, in the socket struct, 279 * The server's table of hello senders is dynamic, in the socket struct,
274 * and sender functions are registered there. 280 * and sender functions are registered there.
275 */ 281 */
276 static const 282 static const
277 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { 283 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
278 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, 284 { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
279 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, 285 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
280 #ifdef NSS_ENABLE_ECC 286 #ifdef NSS_ENABLE_ECC
281 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, 287 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
282 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, 288 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
283 #endif 289 #endif
284 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, 290 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
285 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, 291 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
286 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, 292 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
287 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } 293 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
294 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }
288 /* any extra entries will appear as { 0, NULL } */ 295 /* any extra entries will appear as { 0, NULL } */
289 }; 296 };
290 297
291 static const 298 static const
292 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { 299 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
293 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } 300 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
294 /* any extra entries will appear as { 0, NULL } */ 301 /* any extra entries will appear as { 0, NULL } */
295 }; 302 };
296 303
297 static PRBool 304 static PRBool
(...skipping 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 ss->peerRequestedProtection = 1; 1782 ss->peerRequestedProtection = 1;
1776 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 1783 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
1777 if (ss->sec.isServer) { 1784 if (ss->sec.isServer) {
1778 /* prepare to send back the appropriate response */ 1785 /* prepare to send back the appropriate response */
1779 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, 1786 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
1780 ssl3_SendRenegotiationInfoXtn); 1787 ssl3_SendRenegotiationInfoXtn);
1781 } 1788 }
1782 return rv; 1789 return rv;
1783 } 1790 }
1784 1791
1792 static PRInt32
1793 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
1794 {
1795 PRUint32 ext_data_len;
1796 PRInt16 i;
1797 SECStatus rv;
1798
1799 if (!ss)
1800 return 0;
1801
1802 if (!ss->sec.isServer) {
1803 /* Client side */
1804
1805 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
1806 return 0; /* Not relevant */
1807
1808 ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
1809
1810 if (append && maxBytes >= 4 + ext_data_len) {
1811 /* Extension type */
1812 rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
1813 if (rv != SECSuccess) return -1;
1814 /* Length of extension data */
1815 rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
1816 if (rv != SECSuccess) return -1;
1817 /* Length of the SRTP cipher list */
1818 rv = ssl3_AppendHandshakeNumber(ss,
1819 2 * ss->ssl3.dtlsSRTPCipherCount,
1820 2);
1821 if (rv != SECSuccess) return -1;
1822 /* The SRTP ciphers */
1823 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
1824 rv = ssl3_AppendHandshakeNumber(ss,
1825 ss->ssl3.dtlsSRTPCiphers[i],
1826 2);
1827 }
1828 /* Empty MKI value */
1829 ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
1830
1831 ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
1832 ssl_use_srtp_xtn;
1833 }
1834
1835 return 4 + ext_data_len;
1836 }
1837
1838 /* Server side */
1839 if (append && maxBytes >= 9) {
1840 /* Extension type */
1841 rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
1842 if (rv != SECSuccess) return -1;
1843 /* Length of extension data */
1844 rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
1845 if (rv != SECSuccess) return -1;
1846 /* Length of the SRTP cipher list */
1847 rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
1848 if (rv != SECSuccess) return -1;
1849 /* The selected cipher */
1850 rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
1851 if (rv != SECSuccess) return -1;
1852 /* Empty MKI value */
1853 ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
1854 }
1855
1856 return 9;
1857 }
1858
1859 static SECStatus
1860 ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
1861 {
1862 SECStatus rv;
1863 SECItem ciphers = {siBuffer, NULL, 0};
1864 PRInt16 i;
1865 PRInt16 j;
1866 PRUint16 cipher = 0;
1867 PRBool found = PR_FALSE;
1868 SECItem litem;
1869
1870 if (!ss->sec.isServer) {
1871 /* Client side */
1872 if (!data->data || !data->len) {
1873 /* malformed */
1874 return SECFailure;
1875 }
1876
1877 /* Get the cipher list */
1878 rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
1879 &data->data, &data->len);
1880 if (rv != SECSuccess) {
1881 return SECFailure;
1882 }
1883 /* Now check that the number of ciphers listed is 1 (len = 2) */
1884 if (ciphers.len != 2) {
1885 return SECFailure;
1886 }
1887
1888 /* Get the selected cipher */
1889 cipher = (ciphers.data[0] << 8) | ciphers.data[1];
1890
1891 /* Now check that this is one of the ciphers we offered */
1892 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
1893 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
1894 found = PR_TRUE;
1895 break;
1896 }
1897 }
1898
1899 if (!found) {
1900 return SECFailure;
1901 }
1902
1903 /* Get the srtp_mki value */
1904 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
1905 &data->data, &data->len);
1906 if (rv != SECSuccess) {
1907 return SECFailure;
1908 }
1909
1910 /* We didn't offer an MKI, so this must be 0 length */
1911 /* XXX RFC 5764 Section 4.1.3 says:
1912 * If the client detects a nonzero-length MKI in the server's
1913 * response that is different than the one the client offered,
1914 * then the client MUST abort the handshake and SHOULD send an
1915 * invalid_parameter alert.
1916 *
1917 * Due to a limitation of the ssl3_HandleHelloExtensions function,
1918 * returning SECFailure here won't abort the handshake. It will
1919 * merely cause the use_srtp extension to be not negotiated. We
1920 * should fix this. See NSS bug 753136.
1921 */
1922 if (litem.len != 0) {
1923 return SECFailure;
1924 }
1925
1926 if (data->len != 0) {
1927 /* malformed */
1928 return SECFailure;
1929 }
1930
1931 /* OK, this looks fine. */
1932 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
1933 ss->ssl3.dtlsSRTPCipherSuite = cipher;
1934 return SECSuccess;
1935 }
1936
1937 /* Server side */
1938 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
1939 /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
1940 * preferences have been set. */
1941 return SECSuccess;
1942 }
1943
1944 if (!data->data || data->len < 5) {
1945 /* malformed */
1946 return SECFailure;
1947 }
1948
1949 /* Get the cipher list */
1950 rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
1951 &data->data, &data->len);
1952 if (rv != SECSuccess) {
1953 return SECFailure;
1954 }
1955 /* Check that the list is even length */
1956 if (ciphers.len % 2) {
1957 return SECFailure;
1958 }
1959
1960 /* Walk through the offered list and pick the most preferred of our
1961 * ciphers, if any */
1962 for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
1963 for (j = 0; j + 1 < ciphers.len; j += 2) {
1964 cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
1965 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
1966 found = PR_TRUE;
1967 break;
1968 }
1969 }
1970 }
1971
1972 /* Get the srtp_mki value */
1973 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
1974 if (rv != SECSuccess) {
1975 return SECFailure;
1976 }
1977
1978 if (data->len != 0) {
1979 return SECFailure; /* Malformed */
1980 }
1981
1982 /* Now figure out what to do */
1983 if (!found) {
1984 /* No matching ciphers */
1985 return SECSuccess;
1986 }
1987
1988 /* OK, we have a valid cipher and we've selected it */
1989 ss->ssl3.dtlsSRTPCipherSuite = cipher;
1990 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
1991
1992 return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
1993 ssl3_SendUseSRTPXtn);
1994 }
OLDNEW
« no previous file with comments | « net/third_party/nss/ssl/ssl.h ('k') | net/third_party/nss/ssl/sslimpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698