Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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) { | |
| 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 SECItem ciphers = {siBuffer, NULL, 0}; | |
| 1951 PRInt16 i; | |
| 1952 PRInt16 j; | |
| 1953 PRUint16 cipher = 0; | |
| 1954 PRBool found = PR_FALSE; | |
| 1955 SECItem litem; | |
| 1956 | |
| 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 /* Get the cipher list */ | |
| 1970 rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, | |
| 1971 &data->data, &data->len); | |
| 1972 if (rv != SECSuccess) { | |
| 1973 return SECFailure; | |
| 1974 } | |
| 1975 /* Now check that the number of ciphers listed is 1 (len = 2) */ | |
| 1976 if (ciphers.len != 2) | |
| 1977 return SECFailure; | |
| 1978 | |
| 1979 /* Get the selected cipher */ | |
| 1980 cipher = (ciphers.data[0] << 8) | ciphers.data[1]; | |
| 1981 | |
| 1982 /* Now check that this is one of the ciphers we offered */ | |
| 1983 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { | |
| 1984 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) { | |
| 1985 found = PR_TRUE; | |
| 1986 break; | |
| 1987 } | |
| 1988 } | |
| 1989 | |
| 1990 if (!found) | |
| 1991 return SECFailure; | |
| 1992 | |
| 1993 /* Get the srtp_mki value */ | |
| 1994 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, | |
| 1995 &data->data, &data->len); | |
| 1996 if (rv != SECSuccess) { | |
| 1997 return SECFailure; | |
| 1998 } | |
| 1999 /* We didn't offer an MKI, so this must be 0 length */ | |
| 2000 /* XXX RFC 5764 Section 4.1.3 says: | |
| 2001 * If the client detects a nonzero-length MKI in the server's | |
| 2002 * response that is different than the one the client offered, | |
| 2003 * then the client MUST abort the handshake and SHOULD send an | |
| 2004 * invalid_parameter alert. | |
| 2005 * | |
| 2006 * Due to a limitation of the ssl3_HandleHelloExtensions function, | |
| 2007 * returning SECFailure here won't abort the handshake. It will | |
| 2008 * merely cause the use_srtp extension to be not negotiated. We | |
| 2009 * should fix this. See NSS bug xxxxx. | |
| 2010 */ | |
|
ekr
2012/05/07 22:51:00
I'd still like to find a way to abort the handshak
wtc
2012/05/08 22:15:11
I filed NSS bug 753136 and described how to fix th
| |
| 2011 if (litem.len != 0) | |
| 2012 return SECFailure; | |
| 2013 | |
| 2014 /* OK, this looks fine. */ | |
| 2015 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; | |
| 2016 ss->ssl3.dtlsSRTPCipherSuite = cipher; | |
| 2017 return SECSuccess; | |
| 2018 } | |
| 2019 | |
| 2020 /* Server side */ | |
| 2021 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) { | |
| 2022 /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP | |
| 2023 * preferences have been set. */ | |
| 2024 return SECSuccess; | |
| 2025 } | |
| 2026 | |
| 2027 if (!data->data || data->len < 5) { | |
| 2028 /* malformed */ | |
| 2029 return SECFailure; | |
| 2030 } | |
| 2031 | |
| 2032 /* Get the cipher list */ | |
| 2033 rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, | |
| 2034 &data->data, &data->len); | |
| 2035 if (rv != SECSuccess) { | |
| 2036 return SECFailure; | |
| 2037 } | |
| 2038 /* Check that the list is even length */ | |
| 2039 if (ciphers.len % 2) | |
| 2040 return SECFailure; | |
| 2041 | |
| 2042 /* Walk through the offered list and pick the most preferred of our | |
| 2043 * ciphers, if any */ | |
| 2044 for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) { | |
| 2045 for (j = 0; j + 1 < ciphers.len; j += 2) { | |
| 2046 cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1]; | |
| 2047 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) { | |
| 2048 found = PR_TRUE; | |
| 2049 break; | |
| 2050 } | |
| 2051 } | |
| 2052 } | |
| 2053 | |
| 2054 /* Get the srtp_mki value */ | |
| 2055 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len); | |
| 2056 if (rv != SECSuccess) { | |
| 2057 return SECFailure; | |
| 2058 } | |
| 2059 | |
| 2060 if (data->len) | |
| 2061 return SECFailure; /* Malformed */ | |
| 2062 | |
| 2063 /* Now figure out what to do */ | |
| 2064 if (!found) { | |
| 2065 /* No matching ciphers */ | |
| 2066 return SECSuccess; | |
| 2067 } | |
| 2068 | |
| 2069 /* OK, we have a valid cipher and we've selected it */ | |
| 2070 ss->ssl3.dtlsSRTPCipherSuite = cipher; | |
| 2071 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; | |
| 2072 | |
| 2073 return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn, | |
| 2074 ssl3_SendUseSRTPXtn); | |
| 2075 } | |
| OLD | NEW |