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 | 9 |
10 #include "nssrenam.h" | 10 #include "nssrenam.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, | 49 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, |
50 PRBool append, PRUint32 maxBytes); | 50 PRBool append, PRUint32 maxBytes); |
51 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, | 51 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, |
52 PRUint16 ex_type, SECItem *data); | 52 PRUint16 ex_type, SECItem *data); |
53 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, | 53 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, |
54 PRUint16 ex_type, SECItem *data); | 54 PRUint16 ex_type, SECItem *data); |
55 static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss, | 55 static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss, |
56 PRUint16 ex_type, SECItem *data); | 56 PRUint16 ex_type, SECItem *data); |
57 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, | 57 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, |
58 PRUint16 ex_type, SECItem *data); | 58 PRUint16 ex_type, SECItem *data); |
59 static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, | |
60 SECItem *data); | |
61 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, | |
62 PRUint32 maxBytes); | |
59 static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, | 63 static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, |
60 PRUint32 maxBytes); | 64 PRUint32 maxBytes); |
61 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, | 65 static PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append, |
62 » » » » » PRUint32 maxBytes); | 66 PRUint32 maxBytes); |
63 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, | 67 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, |
64 PRUint32 maxBytes); | 68 PRUint32 maxBytes); |
65 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, | 69 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, |
66 SECItem *data); | 70 SECItem *data); |
67 static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, | 71 static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, |
68 PRUint16 ex_type, SECItem *data); | 72 PRUint16 ex_type, SECItem *data); |
69 static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, | 73 static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, |
70 PRUint32 maxBytes); | 74 PRUint32 maxBytes); |
71 static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss, | 75 static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss, |
72 PRBool append, PRUint32 maxBytes); | 76 PRBool append, PRUint32 maxBytes); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 /* This table is used by the server, to handle client hello extensions. */ | 244 /* This table is used by the server, to handle client hello extensions. */ |
241 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { | 245 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { |
242 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, | 246 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
243 #ifdef NSS_ENABLE_ECC | 247 #ifdef NSS_ENABLE_ECC |
244 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, | 248 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, |
245 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, | 249 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, |
246 #endif | 250 #endif |
247 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, | 251 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
248 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 252 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
249 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, | 253 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
254 { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn }, | |
250 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, | 255 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, |
251 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, | 256 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, |
252 { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, | 257 { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, |
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 }, |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
571 } | 576 } |
572 return extension_length; | 577 return extension_length; |
573 | 578 |
574 loser: | 579 loser: |
575 ss->xtnData.ticketTimestampVerified = PR_FALSE; | 580 ss->xtnData.ticketTimestampVerified = PR_FALSE; |
576 return -1; | 581 return -1; |
577 } | 582 } |
578 | 583 |
579 /* handle an incoming Next Protocol Negotiation extension. */ | 584 /* handle an incoming Next Protocol Negotiation extension. */ |
580 static SECStatus | 585 static SECStatus |
581 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat a) | 586 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, |
587 SECItem *data) | |
582 { | 588 { |
583 if (ss->firstHsDone || data->len != 0) { | 589 if (ss->firstHsDone || data->len != 0) { |
584 /* Clients MUST send an empty NPN extension, if any. */ | 590 /* Clients MUST send an empty NPN extension, if any. */ |
585 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | 591 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
586 return SECFailure; | 592 return SECFailure; |
587 } | 593 } |
588 | 594 |
589 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 595 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
590 | 596 |
591 /* TODO: server side NPN support would require calling | 597 /* TODO: server side NPN support would require calling |
(...skipping 24 matching lines...) Expand all Loading... | |
616 } | 622 } |
617 | 623 |
618 if (offset > length) { | 624 if (offset > length) { |
619 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | 625 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
620 return SECFailure; | 626 return SECFailure; |
621 } | 627 } |
622 | 628 |
623 return SECSuccess; | 629 return SECSuccess; |
624 } | 630 } |
625 | 631 |
632 /* protocol selection handler for ALPN (server side) and NPN (client side) */ | |
633 static SECStatus | |
634 ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data) | |
635 { | |
636 SECStatus rv; | |
637 unsigned char resultBuffer[255]; | |
638 SECItem result = { siBuffer, resultBuffer, 0 }; | |
639 | |
640 rv = ssl3_ValidateNextProtoNego(data->data, data->len); | |
641 if (rv != SECSuccess) | |
642 return rv; | |
643 | |
644 PORT_Assert(ss->nextProtoCallback); | |
645 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, | |
646 result.data, &result.len, sizeof resultBuffer); | |
647 if (rv != SECSuccess) | |
648 return rv; | |
649 /* If the callback wrote more than allowed to |result| it has corrupted our | |
650 * stack. */ | |
651 if (result.len > sizeof resultBuffer) { | |
652 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | |
653 return SECFailure; | |
654 } | |
655 | |
656 if (ex_type == ssl_app_layer_protocol_xtn && | |
657 ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) { | |
658 /* The callback might say OK, but then it's picked a default. | |
agl
2014/09/26 17:39:46
It's acceptable for ALPN too. Most implementations
wtc
2014/09/26 18:12:00
Are you suggesting that we should delete this if s
agl
2014/09/26 18:14:53
I imagine that he's following the wording of the R
wtc
2014/09/26 18:16:56
OK, I took a quick look. This if statement is the
wtc
2014/09/29 17:59:10
Yes, I'd like to merge the current NSS upstream as
| |
659 * That's OK for NPN, but not ALPN. */ | |
660 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | |
661 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL); | |
662 (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol); | |
663 return SECFailure; | |
664 } | |
665 | |
666 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
667 | |
668 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | |
669 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); | |
670 } | |
671 | |
672 /* handle an incoming ALPN extension at the server */ | |
673 static SECStatus | |
674 ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | |
675 { | |
676 int count; | |
677 SECStatus rv; | |
678 | |
679 /* We expressly don't want to allow ALPN on renegotiation, | |
680 * despite it being permitted by the spec. */ | |
681 if (ss->firstHsDone || data->len == 0) { | |
682 /* Clients MUST send a non-empty ALPN extension. */ | |
683 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | |
684 return SECFailure; | |
685 } | |
686 | |
687 /* unlike NPN, ALPN has extra redundant length information so that | |
688 * the extension is the same in both ClientHello and ServerHello */ | |
689 count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | |
690 if (count < 0) { | |
691 return SECFailure; /* fatal alert was sent */ | |
692 } | |
693 if (count != data->len) { | |
694 return ssl3_DecodeError(ss); | |
695 } | |
696 | |
697 if (!ss->nextProtoCallback) { | |
698 /* we're not configured for it */ | |
699 return SECSuccess; | |
700 } | |
701 | |
702 rv = ssl3_SelectAppProtocol(ss, ex_type, data); | |
703 if (rv != SECSuccess) { | |
704 return rv; | |
705 } | |
706 | |
707 /* prepare to send back a response, if we negotiated */ | |
708 if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) { | |
709 return ssl3_RegisterServerHelloExtensionSender( | |
710 ss, ex_type, ssl3_ServerSendAppProtoXtn); | |
711 } | |
712 return SECSuccess; | |
713 } | |
714 | |
626 static SECStatus | 715 static SECStatus |
627 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 716 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
628 » » » » SECItem *data) | 717 SECItem *data) |
629 { | 718 { |
630 SECStatus rv; | |
631 unsigned char resultBuffer[255]; | |
632 SECItem result = { siBuffer, resultBuffer, 0 }; | |
633 | |
634 PORT_Assert(!ss->firstHsDone); | 719 PORT_Assert(!ss->firstHsDone); |
635 | 720 |
636 if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) { | 721 if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) { |
637 /* If the server negotiated ALPN then it has already told us what protoc ol | 722 /* If the server negotiated ALPN then it has already told us what protoc ol |
638 * to use, so it doesn't make sense for us to try to negotiate a differe nt | 723 * to use, so it doesn't make sense for us to try to negotiate a differe nt |
639 * one by sending the NPN handshake message. However, if we've negotiate d | 724 * one by sending the NPN handshake message. However, if we've negotiate d |
640 * NPN then we're required to send the NPN handshake message. Thus, thes e | 725 * NPN then we're required to send the NPN handshake message. Thus, thes e |
641 * two extensions cannot both be negotiated on the same connection. */ | 726 * two extensions cannot both be negotiated on the same connection. */ |
642 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 727 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
643 return SECFailure; | 728 return SECFailure; |
644 } | 729 } |
645 | 730 |
646 rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 731 /* We should only get this call if we sent the extension, so |
647 if (rv != SECSuccess) | 732 * ss->nextProtoCallback needs to be non-NULL. However, it is possible |
648 » return rv; | 733 * that an application erroneously cleared the callback between the time |
649 | 734 * we sent the ClientHello and now. */ |
650 /* ss->nextProtoCallback cannot normally be NULL if we negotiated the | |
651 * extension. However, It is possible that an application erroneously | |
652 * cleared the callback between the time we sent the ClientHello and now. | |
653 */ | |
654 PORT_Assert(ss->nextProtoCallback != NULL); | |
655 if (!ss->nextProtoCallback) { | 735 if (!ss->nextProtoCallback) { |
656 » /* XXX Use a better error code. This is an application error, not an | 736 » PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK); |
657 » * NSS bug. */ | |
658 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
659 return SECFailure; | 737 return SECFailure; |
660 } | 738 } |
661 | 739 |
662 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, | 740 return ssl3_SelectAppProtocol(ss, ex_type, data); |
663 » » » result.data, &result.len, sizeof resultBuffer); | |
664 if (rv != SECSuccess) | |
665 » return rv; | |
666 /* If the callback wrote more than allowed to |result| it has corrupted our | |
667 * stack. */ | |
668 if (result.len > sizeof resultBuffer) { | |
669 » PORT_SetError(SEC_ERROR_OUTPUT_LEN); | |
670 » return SECFailure; | |
671 } | |
672 | |
673 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
674 | |
675 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | |
676 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); | |
677 } | 741 } |
678 | 742 |
679 static SECStatus | 743 static SECStatus |
680 ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | 744 ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) |
681 { | 745 { |
682 const unsigned char* d = data->data; | 746 const unsigned char* d = data->data; |
683 PRUint16 name_list_len; | 747 PRUint16 name_list_len; |
684 SECItem protocol_name; | 748 SECItem protocol_name; |
685 | 749 |
686 if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) { | 750 if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
807 | 871 |
808 return extension_length; | 872 return extension_length; |
809 | 873 |
810 loser: | 874 loser: |
811 if (alpn_protos) { | 875 if (alpn_protos) { |
812 PORT_Free(alpn_protos); | 876 PORT_Free(alpn_protos); |
813 } | 877 } |
814 return -1; | 878 return -1; |
815 } | 879 } |
816 | 880 |
881 static PRInt32 | |
882 ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) | |
883 { | |
884 PRInt32 extension_length; | |
885 | |
886 /* we're in over our heads if any of these fail */ | |
agl
2014/09/26 17:39:46
This comment isn't useful.
wtc
2014/09/29 17:59:10
Done.
| |
887 PORT_Assert(ss->opt.enableALPN); | |
888 PORT_Assert(ss->ssl3.nextProto.data); | |
889 PORT_Assert(ss->ssl3.nextProto.len > 0); | |
890 PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED); | |
891 PORT_Assert(!ss->firstHsDone); | |
892 | |
893 extension_length = 2 /* extension type */ + 2 /* extension length */ + | |
894 2 /* protocol name list */ + 1 /* name length */ + | |
895 ss->ssl3.nextProto.len; | |
896 | |
897 if (append && maxBytes >= extension_length) { | |
898 SECStatus rv; | |
899 rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); | |
900 if (rv != SECSuccess) { | |
901 return -1; | |
902 } | |
903 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | |
904 if (rv != SECSuccess) { | |
905 return -1; | |
906 } | |
907 rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2); | |
908 if (rv != SECSuccess) { | |
909 return -1; | |
910 } | |
911 rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, | |
912 ss->ssl3.nextProto.len, 1); | |
913 if (rv != SECSuccess) { | |
914 return -1; | |
915 } | |
916 } else if (maxBytes < extension_length) { | |
917 return 0; | |
918 } | |
919 | |
920 return extension_length; | |
921 } | |
922 | |
817 static SECStatus | 923 static SECStatus |
818 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, | 924 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, |
819 SECItem *data) | 925 SECItem *data) |
820 { | 926 { |
821 PORT_Assert(ss->getChannelID != NULL); | 927 PORT_Assert(ss->getChannelID != NULL); |
822 | 928 |
823 if (data->len) { | 929 if (data->len) { |
824 PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); | 930 PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); |
825 return SECFailure; | 931 return SECFailure; |
826 } | 932 } |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2445 | 2551 |
2446 if (!data->len) { | 2552 if (!data->len) { |
2447 /* Empty extension data: RFC 6962 mandates non-empty contents. */ | 2553 /* Empty extension data: RFC 6962 mandates non-empty contents. */ |
2448 return SECFailure; | 2554 return SECFailure; |
2449 } | 2555 } |
2450 *scts = *data; | 2556 *scts = *data; |
2451 /* Keep track of negotiated extensions. */ | 2557 /* Keep track of negotiated extensions. */ |
2452 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 2558 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
2453 return SECSuccess; | 2559 return SECSuccess; |
2454 } | 2560 } |
OLD | NEW |