Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * SSL3 Protocol | 2 * SSL3 Protocol |
| 3 * | 3 * |
| 4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
| 5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 7 | 7 |
| 8 /* TLS extension code moved here from ssl3ecc.c */ | 8 /* TLS extension code moved here from ssl3ecc.c */ |
| 9 /* $Id$ */ | 9 /* $Id$ */ |
| 10 | 10 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, | 46 static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, |
| 47 PRUint32 *aes_key_length, const unsigned char **mac_key, | 47 PRUint32 *aes_key_length, const unsigned char **mac_key, |
| 48 PRUint32 *mac_key_length); | 48 PRUint32 *mac_key_length); |
| 49 #endif | 49 #endif |
| 50 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, | 50 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, |
| 51 PRBool append, PRUint32 maxBytes); | 51 PRBool append, PRUint32 maxBytes); |
| 52 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, | 52 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, |
| 53 PRUint16 ex_type, SECItem *data); | 53 PRUint16 ex_type, SECItem *data); |
| 54 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, | 54 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, |
| 55 PRUint16 ex_type, SECItem *data); | 55 PRUint16 ex_type, SECItem *data); |
| 56 static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss, | |
| 57 PRUint16 ex_type, SECItem *data); | |
| 56 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, | 58 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, |
| 57 PRUint16 ex_type, SECItem *data); | 59 PRUint16 ex_type, SECItem *data); |
| 60 static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, | |
| 61 PRUint32 maxBytes); | |
| 58 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, | 62 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, |
| 59 PRUint32 maxBytes); | 63 PRUint32 maxBytes); |
| 60 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, | 64 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, |
| 61 PRUint32 maxBytes); | 65 PRUint32 maxBytes); |
| 62 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, | 66 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, |
| 63 SECItem *data); | 67 SECItem *data); |
| 64 static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, | 68 static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, |
| 65 PRUint16 ex_type, SECItem *data); | 69 PRUint16 ex_type, SECItem *data); |
| 66 static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, | 70 static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, |
| 67 PRUint32 maxBytes); | 71 PRUint32 maxBytes); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, | 244 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
| 241 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, | 245 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, |
| 242 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, | 246 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, |
| 243 { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, | 247 { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, |
| 244 { -1, NULL } | 248 { -1, NULL } |
| 245 }; | 249 }; |
| 246 | 250 |
| 247 /* These two tables are used by the client, to handle server hello | 251 /* These two tables are used by the client, to handle server hello |
| 248 * extensions. */ | 252 * extensions. */ |
| 249 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { | 253 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { |
| 250 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, | 254 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
| 251 /* TODO: add a handler for ssl_ec_point_formats_xtn */ | 255 /* TODO: add a handler for ssl_ec_point_formats_xtn */ |
| 252 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, | 256 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
| 253 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 257 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 254 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, | 258 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, |
| 255 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, | 259 { ssl_application_layer_protocol, &ssl3_ClientHandleAppProtoXtn }, |
| 256 { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, | 260 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, |
| 257 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, | 261 { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, |
| 262 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, | |
| 258 { -1, NULL } | 263 { -1, NULL } |
| 259 }; | 264 }; |
| 260 | 265 |
| 261 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { | 266 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { |
| 262 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 267 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 263 { -1, NULL } | 268 { -1, NULL } |
| 264 }; | 269 }; |
| 265 | 270 |
| 266 /* Tables of functions to format TLS hello extensions, one function per | 271 /* Tables of functions to format TLS hello extensions, one function per |
| 267 * extension. | 272 * extension. |
| 268 * These static tables are for the formatting of client hello extensions. | 273 * These static tables are for the formatting of client hello extensions. |
| 269 * The server's table of hello senders is dynamic, in the socket struct, | 274 * The server's table of hello senders is dynamic, in the socket struct, |
| 270 * and sender functions are registered there. | 275 * and sender functions are registered there. |
| 271 */ | 276 */ |
| 272 static const | 277 static const |
| 273 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { | 278 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { |
| 274 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, | 279 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, |
| 275 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, | 280 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, |
| 276 #ifdef NSS_ENABLE_ECC | 281 #ifdef NSS_ENABLE_ECC |
| 277 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, | 282 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |
| 278 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, | 283 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
| 279 #endif | 284 #endif |
| 280 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, | 285 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
| 281 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, | 286 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, |
| 282 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, | 287 { ssl_application_layer_protocol, &ssl3_ClientSendAppProtoXtn }, |
| 283 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, | 288 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, |
| 284 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, | 289 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, |
| 290 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, | |
| 285 { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn } | 291 { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn } |
| 286 /* any extra entries will appear as { 0, NULL } */ | 292 /* any extra entries will appear as { 0, NULL } */ |
| 287 }; | 293 }; |
| 288 | 294 |
| 289 static const | 295 static const |
| 290 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { | 296 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { |
| 291 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } | 297 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } |
| 292 /* any extra entries will appear as { 0, NULL } */ | 298 /* any extra entries will appear as { 0, NULL } */ |
| 293 }; | 299 }; |
| 294 | 300 |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 static SECStatus | 605 static SECStatus |
| 600 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 606 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 601 SECItem *data) | 607 SECItem *data) |
| 602 { | 608 { |
| 603 SECStatus rv; | 609 SECStatus rv; |
| 604 unsigned char resultBuffer[255]; | 610 unsigned char resultBuffer[255]; |
| 605 SECItem result = { siBuffer, resultBuffer, 0 }; | 611 SECItem result = { siBuffer, resultBuffer, 0 }; |
| 606 | 612 |
| 607 PORT_Assert(!ss->firstHsDone); | 613 PORT_Assert(!ss->firstHsDone); |
| 608 | 614 |
| 615 if (ssl3_ExtensionNegotiated(ss, ssl_application_layer_protocol)) { | |
| 616 PORT_SetError(SSL_ERROR_BOTH_NPN_AND_ALPN); | |
| 617 return SECFailure; | |
| 618 } | |
| 619 | |
| 609 rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 620 rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 610 if (rv != SECSuccess) | 621 if (rv != SECSuccess) |
| 611 return rv; | 622 return rv; |
| 612 | 623 |
| 613 /* ss->nextProtoCallback cannot normally be NULL if we negotiated the | 624 /* ss->nextProtoCallback cannot normally be NULL if we negotiated the |
| 614 * extension. However, It is possible that an application erroneously | 625 * extension. However, It is possible that an application erroneously |
| 615 * cleared the callback between the time we sent the ClientHello and now. | 626 * cleared the callback between the time we sent the ClientHello and now. |
| 616 */ | 627 */ |
| 617 PORT_Assert(ss->nextProtoCallback != NULL); | 628 PORT_Assert(ss->nextProtoCallback != NULL); |
| 618 if (!ss->nextProtoCallback) { | 629 if (!ss->nextProtoCallback) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 632 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | 643 PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
| 633 return SECFailure; | 644 return SECFailure; |
| 634 } | 645 } |
| 635 | 646 |
| 636 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 647 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 637 | 648 |
| 638 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | 649 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 639 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); | 650 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); |
| 640 } | 651 } |
| 641 | 652 |
| 653 static SECStatus | |
| 654 ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | |
| 655 { | |
| 656 const unsigned char* d = data->data; | |
| 657 PRUint16 name_list_len; | |
| 658 SECItem protocol_name; | |
| 659 | |
| 660 if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) { | |
| 661 PORT_SetError(SSL_ERROR_BOTH_NPN_AND_ALPN); | |
| 662 return SECFailure; | |
|
Ryan Sleevi
2013/07/02 18:36:48
This won't actually abort the connection - it will
agl
2013/07/02 18:42:22
Hmm, I was planning on aborting the connection but
| |
| 663 } | |
| 664 | |
| 665 /* The extension data from the server has the following format: | |
| 666 * uint16 name_list_len; | |
| 667 * uint8 len; | |
| 668 * uint8 protocol_name[len]; */ | |
| 669 if (data->len < 4 || data->len > 2 + 1 + 255) { | |
| 670 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | |
| 671 return SECFailure; | |
| 672 } | |
| 673 | |
| 674 name_list_len = ((PRUint16) d[0]) << 8 | | |
| 675 ((PRUint16) d[1]); | |
| 676 if (name_list_len != data->len - 2 || | |
| 677 d[2] != data->len - 3) { | |
| 678 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | |
| 679 return SECFailure; | |
| 680 } | |
| 681 | |
| 682 protocol_name.data = data->data + 3; | |
| 683 protocol_name.len = data->len - 3; | |
| 684 | |
| 685 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | |
| 686 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED; | |
| 687 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 688 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name); | |
| 689 } | |
| 690 | |
| 642 static PRInt32 | 691 static PRInt32 |
| 643 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append, | 692 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append, |
| 644 PRUint32 maxBytes) | 693 PRUint32 maxBytes) |
| 645 { | 694 { |
| 646 PRInt32 extension_length; | 695 PRInt32 extension_length; |
| 647 | 696 |
| 648 /* Renegotiations do not send this extension. */ | 697 /* Renegotiations do not send this extension. */ |
| 649 if (!ss->nextProtoCallback || ss->firstHsDone) { | 698 if (!ss->nextProtoCallback || ss->firstHsDone) { |
| 650 return 0; | 699 return 0; |
| 651 } | 700 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 665 } else if (maxBytes < extension_length) { | 714 } else if (maxBytes < extension_length) { |
| 666 return 0; | 715 return 0; |
| 667 } | 716 } |
| 668 | 717 |
| 669 return extension_length; | 718 return extension_length; |
| 670 | 719 |
| 671 loser: | 720 loser: |
| 672 return -1; | 721 return -1; |
| 673 } | 722 } |
| 674 | 723 |
| 724 static PRInt32 | |
| 725 ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) | |
| 726 { | |
| 727 PRInt32 extension_length; | |
| 728 | |
| 729 /* Renegotiations do not send this extension. */ | |
| 730 if (!ss->opt.nextProtoNego.data || ss->firstHsDone) { | |
| 731 return 0; | |
| 732 } | |
| 733 | |
| 734 extension_length = 2 /* extension type */ + 2 /* extension length */ + | |
| 735 2 /* protocol name list length */ + | |
| 736 ss->opt.nextProtoNego.len; | |
| 737 | |
| 738 if (append && maxBytes >= extension_length) { | |
| 739 SECStatus rv; | |
| 740 rv = ssl3_AppendHandshakeNumber(ss, ssl_application_layer_protocol, 2); | |
| 741 if (rv != SECSuccess) | |
| 742 goto loser; | |
| 743 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | |
| 744 if (rv != SECSuccess) | |
| 745 goto loser; | |
| 746 rv = ssl3_AppendHandshakeVariable(ss, ss->opt.nextProtoNego.data, | |
| 747 ss->opt.nextProtoNego.len, 2); | |
| 748 if (rv != SECSuccess) | |
| 749 goto loser; | |
| 750 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = | |
| 751 ssl_application_layer_protocol; | |
| 752 } else if (maxBytes < extension_length) { | |
| 753 return 0; | |
| 754 } | |
| 755 | |
| 756 return extension_length; | |
| 757 | |
| 758 loser: | |
| 759 return -1; | |
| 760 } | |
| 761 | |
| 675 static SECStatus | 762 static SECStatus |
| 676 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, | 763 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, |
| 677 SECItem *data) | 764 SECItem *data) |
| 678 { | 765 { |
| 679 PORT_Assert(ss->getChannelID != NULL); | 766 PORT_Assert(ss->getChannelID != NULL); |
| 680 | 767 |
| 681 if (data->len) { | 768 if (data->len) { |
| 682 PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); | 769 PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); |
| 683 return SECFailure; | 770 return SECFailure; |
| 684 } | 771 } |
| (...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2150 } else if (maxBytes < extension_length) { | 2237 } else if (maxBytes < extension_length) { |
| 2151 PORT_Assert(0); | 2238 PORT_Assert(0); |
| 2152 return 0; | 2239 return 0; |
| 2153 } | 2240 } |
| 2154 | 2241 |
| 2155 return extension_length; | 2242 return extension_length; |
| 2156 | 2243 |
| 2157 loser: | 2244 loser: |
| 2158 return -1; | 2245 return -1; |
| 2159 } | 2246 } |
| OLD | NEW |