Index: net/third_party/nss/ssl/ssl3ext.c |
=================================================================== |
--- net/third_party/nss/ssl/ssl3ext.c (revision 245705) |
+++ net/third_party/nss/ssl/ssl3ext.c (working copy) |
@@ -57,7 +57,7 @@ |
static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, |
PRUint16 ex_type, SECItem *data); |
static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, |
- PRUint32 maxBytes); |
+ PRUint32 maxBytes); |
static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, |
PRUint32 maxBytes); |
static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, |
@@ -283,19 +283,19 @@ |
*/ |
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_app_layer_protocol_xtn, &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 }, |
+ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
+ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, |
+ { ssl_app_layer_protocol_xtn, &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 }, |
{ ssl_signed_certificate_timestamp_xtn, |
&ssl3_ClientSendSignedCertTimestampXtn } |
/* any extra entries will appear as { 0, NULL } */ |
@@ -631,6 +631,11 @@ |
PORT_Assert(!ss->firstHsDone); |
if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) { |
wtc
2014/02/12 15:26:24
As an optimization, check ss->opt.enableALPN first
|
+ /* If the server negotiated ALPN then it has already told us what protocol |
+ * to use, so it doesn't make sense for us to try to negotiate a different |
+ * one by sending the NPN handshake message. However, if we've negotiated |
+ * NPN then we're required to send the NPN handshake message. Thus, these |
+ * two extensions cannot both be negotiated on the same connection. */ |
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
wtc
2014/02/12 15:26:24
Use a different error code. This is not an NSS bug
|
return SECFailure; |
} |
@@ -691,8 +696,7 @@ |
name_list_len = ((PRUint16) d[0]) << 8 | |
((PRUint16) d[1]); |
- if (name_list_len != data->len - 2 || |
- d[2] != data->len - 3) { |
+ if (name_list_len != data->len - 2 || d[2] != data->len - 3) { |
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
return SECFailure; |
} |
@@ -713,7 +717,7 @@ |
PRInt32 extension_length; |
/* Renegotiations do not send this extension. */ |
- if (!ss->nextProtoCallback || ss->firstHsDone) { |
+ if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) { |
return 0; |
} |
@@ -746,13 +750,13 @@ |
unsigned char *alpn_protos = NULL; |
/* Renegotiations do not send this extension. */ |
- if (!ss->opt.nextProtoNego.data || ss->firstHsDone) { |
+ if (!ss->opt.enableALPN || !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; |
+ 2 /* protocol name list length */ + |
+ ss->opt.nextProtoNego.len; |
if (append && maxBytes >= extension_length) { |
/* NPN requires that the client's fallback protocol is first in the |
@@ -779,16 +783,19 @@ |
} |
rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); |
- if (rv != SECSuccess) |
+ if (rv != SECSuccess) { |
goto loser; |
+ } |
rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); |
- if (rv != SECSuccess) |
+ if (rv != SECSuccess) { |
goto loser; |
+ } |
rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2); |
PORT_Free(alpn_protos); |
alpn_protos = NULL; |
- if (rv != SECSuccess) |
+ if (rv != SECSuccess) { |
goto loser; |
+ } |
ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
ssl_app_layer_protocol_xtn; |
} else if (maxBytes < extension_length) { |
@@ -798,8 +805,9 @@ |
return extension_length; |
loser: |
- if (alpn_protos) |
+ if (alpn_protos) { |
PORT_Free(alpn_protos); |
+ } |
return -1; |
} |
@@ -2342,13 +2350,13 @@ |
return 0; |
} |
- extensionLength = 512 - recordLength; |
- /* Extensions take at least four bytes to encode. */ |
- if (extensionLength < 4) { |
- extensionLength = 4; |
- } |
+ extensionLength = 512 - recordLength; |
+ /* Extensions take at least four bytes to encode. */ |
+ if (extensionLength < 4) { |
+ extensionLength = 4; |
+ } |
- return extensionLength; |
+ return extensionLength; |
} |
/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a |
@@ -2359,7 +2367,7 @@ |
PRUint32 maxBytes) |
{ |
unsigned int paddingLen = extensionLen - 4; |
- unsigned char padding[512]; |
+ static unsigned char padding[512]; |
if (extensionLen == 0) { |
return 0; |
@@ -2376,7 +2384,6 @@ |
return -1; |
if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2)) |
return -1; |
- memset(padding, 0, paddingLen); |
if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen)) |
return -1; |