| Index: net/third_party/nss/patches/alpn.patch
|
| diff --git a/net/third_party/nss/patches/alpn.patch b/net/third_party/nss/patches/alpn.patch
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d9016bed1d9839cfe059119e3a36bdff2bff7eda
|
| --- /dev/null
|
| +++ b/net/third_party/nss/patches/alpn.patch
|
| @@ -0,0 +1,231 @@
|
| +diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
|
| +index 8e9ba24..077874e 100644
|
| +--- a/net/third_party/nss/ssl/ssl.h
|
| ++++ b/net/third_party/nss/ssl/ssl.h
|
| +@@ -204,6 +204,11 @@ SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd,
|
| + * protocol in server-preference order. If no matching protocol is found it
|
| + * selects the first supported protocol.
|
| + *
|
| ++ * Using this function also allows the client to transparently support ALPN.
|
| ++ * The same set of protocols will be advertised via ALPN and, if the server
|
| ++ * uses ALPN to select a protocol, SSL_GetNextProto will return
|
| ++ * SSL_NEXT_PROTO_SELECTED as the state.
|
| ++ *
|
| + * The supported protocols are specified in |data| in wire-format (8-bit
|
| + * length-prefixed). For example: "\010http/1.1\006spdy/2". */
|
| + SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
|
| +@@ -213,7 +218,8 @@ SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
|
| + typedef enum SSLNextProtoState {
|
| + SSL_NEXT_PROTO_NO_SUPPORT = 0, /* No peer support */
|
| + SSL_NEXT_PROTO_NEGOTIATED = 1, /* Mutual agreement */
|
| +- SSL_NEXT_PROTO_NO_OVERLAP = 2 /* No protocol overlap found */
|
| ++ SSL_NEXT_PROTO_NO_OVERLAP = 2, /* No protocol overlap found */
|
| ++ SSL_NEXT_PROTO_SELECTED = 3, /* Server selected proto (ALPN) */
|
| + } SSLNextProtoState;
|
| +
|
| + /* SSL_GetNextProto can be used in the HandshakeCallback or any time after
|
| +diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
|
| +index 00c83db..4916dfc 100644
|
| +--- a/net/third_party/nss/ssl/ssl3con.c
|
| ++++ b/net/third_party/nss/ssl/ssl3con.c
|
| +@@ -9907,8 +9907,10 @@ ssl3_SendNextProto(sslSocket *ss)
|
| + int padding_len;
|
| + static const unsigned char padding[32] = {0};
|
| +
|
| +- if (ss->ssl3.nextProto.len == 0)
|
| ++ if (ss->ssl3.nextProto.len == 0 ||
|
| ++ ss->ssl3.nextProtoState == SSL_NEXT_PROTO_SELECTED) {
|
| + return SECSuccess;
|
| ++ }
|
| +
|
| + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
| + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
| +diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
|
| +index c0ce548..a059ccb 100644
|
| +--- a/net/third_party/nss/ssl/ssl3ext.c
|
| ++++ b/net/third_party/nss/ssl/ssl3ext.c
|
| +@@ -53,8 +53,12 @@ static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
|
| + PRUint16 ex_type, SECItem *data);
|
| + static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
|
| + PRUint16 ex_type, SECItem *data);
|
| ++static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
|
| ++ PRUint16 ex_type, SECItem *data);
|
| + static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
|
| + PRUint16 ex_type, SECItem *data);
|
| ++static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
|
| ++ PRUint32 maxBytes);
|
| + static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes);
|
| + static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
|
| +@@ -247,14 +251,15 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
| + /* These two tables are used by the client, to handle server hello
|
| + * extensions. */
|
| + static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
|
| +- { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
| ++ { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
| + /* TODO: add a handler for ssl_ec_point_formats_xtn */
|
| +- { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
|
| +- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
| +- { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
|
| +- { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
|
| +- { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
|
| +- { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
|
| ++ { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
|
| ++ { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
| ++ { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
|
| ++ { ssl_application_layer_protocol, &ssl3_ClientHandleAppProtoXtn },
|
| ++ { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
|
| ++ { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
|
| ++ { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
|
| + { -1, NULL }
|
| + };
|
| +
|
| +@@ -271,17 +276,18 @@ static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
|
| + */
|
| + static const
|
| + ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
|
| +- { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
|
| +- { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
|
| ++ { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
|
| ++ { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
|
| + #ifdef NSS_ENABLE_ECC
|
| +- { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
| +- { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
| ++ { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
| ++ { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
| + #endif
|
| +- { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
|
| +- { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
|
| +- { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
|
| +- { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
|
| +- { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
|
| ++ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
|
| ++ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
|
| ++ { ssl_application_layer_protocol, &ssl3_ClientSendAppProtoXtn },
|
| ++ { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
|
| ++ { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
|
| ++ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
|
| + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
|
| + /* any extra entries will appear as { 0, NULL } */
|
| + };
|
| +@@ -606,6 +612,11 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
| +
|
| + PORT_Assert(!ss->firstHsDone);
|
| +
|
| ++ if (ssl3_ExtensionNegotiated(ss, ssl_application_layer_protocol)) {
|
| ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| ++ return SECFailure;
|
| ++ }
|
| ++
|
| + rv = ssl3_ValidateNextProtoNego(data->data, data->len);
|
| + if (rv != SECSuccess)
|
| + return rv;
|
| +@@ -639,6 +650,44 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
| + return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
|
| + }
|
| +
|
| ++static SECStatus
|
| ++ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| ++{
|
| ++ const unsigned char* d = data->data;
|
| ++ PRUint16 name_list_len;
|
| ++ SECItem protocol_name;
|
| ++
|
| ++ if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
|
| ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| ++ return SECFailure;
|
| ++ }
|
| ++
|
| ++ /* The extension data from the server has the following format:
|
| ++ * uint16 name_list_len;
|
| ++ * uint8 len;
|
| ++ * uint8 protocol_name[len]; */
|
| ++ if (data->len < 4 || data->len > 2 + 1 + 255) {
|
| ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
|
| ++ return SECFailure;
|
| ++ }
|
| ++
|
| ++ name_list_len = ((PRUint16) d[0]) << 8 |
|
| ++ ((PRUint16) d[1]);
|
| ++ if (name_list_len != data->len - 2 ||
|
| ++ d[2] != data->len - 3) {
|
| ++ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
|
| ++ return SECFailure;
|
| ++ }
|
| ++
|
| ++ protocol_name.data = data->data + 3;
|
| ++ protocol_name.len = data->len - 3;
|
| ++
|
| ++ SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
|
| ++ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
|
| ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
| ++ return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
|
| ++}
|
| ++
|
| + static PRInt32
|
| + ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
|
| + PRUint32 maxBytes)
|
| +@@ -672,6 +721,44 @@ loser:
|
| + return -1;
|
| + }
|
| +
|
| ++static PRInt32
|
| ++ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| ++{
|
| ++ PRInt32 extension_length;
|
| ++
|
| ++ /* Renegotiations do not send this extension. */
|
| ++ if (!ss->opt.nextProtoNego.data || ss->firstHsDone) {
|
| ++ return 0;
|
| ++ }
|
| ++
|
| ++ extension_length = 2 /* extension type */ + 2 /* extension length */ +
|
| ++ 2 /* protocol name list length */ +
|
| ++ ss->opt.nextProtoNego.len;
|
| ++
|
| ++ if (append && maxBytes >= extension_length) {
|
| ++ SECStatus rv;
|
| ++ rv = ssl3_AppendHandshakeNumber(ss, ssl_application_layer_protocol, 2);
|
| ++ if (rv != SECSuccess)
|
| ++ goto loser;
|
| ++ rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
|
| ++ if (rv != SECSuccess)
|
| ++ goto loser;
|
| ++ rv = ssl3_AppendHandshakeVariable(ss, ss->opt.nextProtoNego.data,
|
| ++ ss->opt.nextProtoNego.len, 2);
|
| ++ if (rv != SECSuccess)
|
| ++ goto loser;
|
| ++ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| ++ ssl_application_layer_protocol;
|
| ++ } else if (maxBytes < extension_length) {
|
| ++ return 0;
|
| ++ }
|
| ++
|
| ++ return extension_length;
|
| ++
|
| ++loser:
|
| ++ return -1;
|
| ++}
|
| ++
|
| + static SECStatus
|
| + ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type,
|
| + SECItem *data)
|
| +diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
|
| +index 109640c..96ec04e 100644
|
| +--- a/net/third_party/nss/ssl/sslt.h
|
| ++++ b/net/third_party/nss/ssl/sslt.h
|
| +@@ -196,12 +196,13 @@ typedef enum {
|
| + #endif
|
| + ssl_signature_algorithms_xtn = 13,
|
| + ssl_use_srtp_xtn = 14,
|
| ++ ssl_application_layer_protocol = 16,
|
| + ssl_session_ticket_xtn = 35,
|
| + ssl_next_proto_nego_xtn = 13172,
|
| + ssl_channel_id_xtn = 30031,
|
| + ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
|
| + } SSLExtensionType;
|
| +
|
| +-#define SSL_MAX_EXTENSIONS 10
|
| ++#define SSL_MAX_EXTENSIONS 11
|
| +
|
| + #endif /* __sslt_h_ */
|
|
|