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. |
| 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 PORT_Assert(ss->opt.enableALPN); |
| 887 PORT_Assert(ss->ssl3.nextProto.data); |
| 888 PORT_Assert(ss->ssl3.nextProto.len > 0); |
| 889 PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED); |
| 890 PORT_Assert(!ss->firstHsDone); |
| 891 |
| 892 extension_length = 2 /* extension type */ + 2 /* extension length */ + |
| 893 2 /* protocol name list */ + 1 /* name length */ + |
| 894 ss->ssl3.nextProto.len; |
| 895 |
| 896 if (append && maxBytes >= extension_length) { |
| 897 SECStatus rv; |
| 898 rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); |
| 899 if (rv != SECSuccess) { |
| 900 return -1; |
| 901 } |
| 902 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); |
| 903 if (rv != SECSuccess) { |
| 904 return -1; |
| 905 } |
| 906 rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2); |
| 907 if (rv != SECSuccess) { |
| 908 return -1; |
| 909 } |
| 910 rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, |
| 911 ss->ssl3.nextProto.len, 1); |
| 912 if (rv != SECSuccess) { |
| 913 return -1; |
| 914 } |
| 915 } else if (maxBytes < extension_length) { |
| 916 return 0; |
| 917 } |
| 918 |
| 919 return extension_length; |
| 920 } |
| 921 |
817 static SECStatus | 922 static SECStatus |
818 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, | 923 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, |
819 SECItem *data) | 924 SECItem *data) |
820 { | 925 { |
821 PORT_Assert(ss->getChannelID != NULL); | 926 PORT_Assert(ss->getChannelID != NULL); |
822 | 927 |
823 if (data->len) { | 928 if (data->len) { |
824 PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); | 929 PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); |
825 return SECFailure; | 930 return SECFailure; |
826 } | 931 } |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2445 | 2550 |
2446 if (!data->len) { | 2551 if (!data->len) { |
2447 /* Empty extension data: RFC 6962 mandates non-empty contents. */ | 2552 /* Empty extension data: RFC 6962 mandates non-empty contents. */ |
2448 return SECFailure; | 2553 return SECFailure; |
2449 } | 2554 } |
2450 *scts = *data; | 2555 *scts = *data; |
2451 /* Keep track of negotiated extensions. */ | 2556 /* Keep track of negotiated extensions. */ |
2452 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 2557 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
2453 return SECSuccess; | 2558 return SECSuccess; |
2454 } | 2559 } |
OLD | NEW |