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

Side by Side Diff: net/third_party/nss/ssl/ssl3ext.c

Issue 595823003: Merge the server-side support of ALPN from the NSS upstream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove a comment that wasn't useful. Created 6 years, 2 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
« no previous file with comments | « net/third_party/nss/ssl/SSLerrs.h ('k') | net/third_party/nss/ssl/ssl3prot.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 * 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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « net/third_party/nss/ssl/SSLerrs.h ('k') | net/third_party/nss/ssl/ssl3prot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698