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

Unified Diff: net/third_party/nss/ssl/ssl3ext.c

Issue 1511123006: Uprev NSS (in libssl) to NSS 3.21 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated deps Created 5 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/ssl/ssl3ecc.c ('k') | net/third_party/nss/ssl/ssl3gthr.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/ssl/ssl3ext.c
diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
index 9214a2e6b3bdc2e923d0beba0245b6ba71bf5838..eb3fb70f2805c444317ee87ee55760b36fa31660 100644
--- a/net/third_party/nss/ssl/ssl3ext.c
+++ b/net/third_party/nss/ssl/ssl3ext.c
@@ -101,6 +101,12 @@ static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data);
+static PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes);
+static SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss,
+ PRUint16 ex_type,
+ SECItem *data);
+
/*
* Write bytes. Using this function means the SECItem structure
@@ -266,6 +272,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
{ -1, NULL }
};
@@ -281,6 +288,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
{ ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
{ ssl_signed_certificate_timestamp_xtn,
&ssl3_ClientHandleSignedCertTimestampXtn },
{ -1, NULL }
@@ -319,6 +327,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
* extension. */
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
/* any extra entries will appear as { 0, NULL } */
};
@@ -331,7 +340,7 @@ ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
static PRBool
arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
{
- int i;
+ unsigned int i;
for (i = 0; i < len; i++) {
if (ex_type == array[i])
return PR_TRUE;
@@ -433,12 +442,12 @@ ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
/* length of server_name_list */
listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (listLenBytes < 0 || listLenBytes != data->len) {
- (void)ssl3_DecodeError(ss);
+ if (listLenBytes < 0) {
return SECFailure;
}
- if (listLenBytes == 0) {
- return SECSuccess; /* ignore an empty extension */
+ if (listLenBytes == 0 || listLenBytes != data->len) {
+ (void)ssl3_DecodeError(ss);
+ return SECFailure;
}
ldata = *data;
/* Calculate the size of the array.*/
@@ -463,15 +472,12 @@ ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
listCount += 1;
}
- if (!listCount) {
- return SECFailure; /* nothing we can act on */
- }
names = PORT_ZNewArray(SECItem, listCount);
if (!names) {
return SECFailure;
}
for (i = 0;i < listCount;i++) {
- int j;
+ unsigned int j;
PRInt32 type;
SECStatus rv;
PRBool nametypePresent = PR_FALSE;
@@ -559,7 +565,11 @@ ssl3_SendSessionTicketXtn(
}
}
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
SECStatus rv;
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
@@ -582,9 +592,6 @@ ssl3_SendSessionTicketXtn(
xtnData->advertised[xtnData->numAdvertised++] =
ssl_session_ticket_xtn;
}
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
@@ -645,12 +652,17 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
rv = ssl3_ValidateNextProtoNego(data->data, data->len);
if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return rv;
}
PORT_Assert(ss->nextProtoCallback);
+ /* For ALPN, the cipher suite isn't selected yet. Note that extensions
+ * sometimes affect what cipher suite is selected, e.g., for ECC. */
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo &
+ ssl_preinfo_all & ~ssl_preinfo_cipher_suite) ==
+ (ssl_preinfo_all & ~ssl_preinfo_cipher_suite));
rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
result.data, &result.len, sizeof(resultBuffer));
if (rv != SECSuccess) {
@@ -673,8 +685,8 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
/* The callback might say OK, but then it picks a default value - one
* that was not listed. That's OK for NPN, but not ALPN. */
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
(void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
return SECFailure;
}
@@ -693,8 +705,8 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
* despite it being permitted by the spec. */
if (ss->firstHsDone || data->len == 0) {
/* Clients MUST send a non-empty ALPN extension. */
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -721,8 +733,8 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
rv = ssl3_RegisterServerHelloExtensionSender(
ss, ex_type, ssl3_ServerSendAppProtoXtn);
if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return rv;
}
}
@@ -742,8 +754,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
* 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(SSL_ERROR_BAD_SERVER);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_BAD_SERVER);
return SECFailure;
}
@@ -753,8 +765,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
* we sent the ClientHello and now. */
if (!ss->nextProtoCallback) {
PORT_Assert(0);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
return SECFailure;
}
@@ -778,16 +790,16 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
* uint8 len; // where len >= 1
* uint8 protocol_name[len]; */
if (data->len < 4 || data->len > 2 + 1 + 255) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
/* The list has to be the entire extension. */
if (list_len != data->len) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -795,8 +807,8 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
&data->data, &data->len);
/* The list must have exactly one value. */
if (rv != SECSuccess || data->len != 0) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -819,7 +831,10 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
extension_length = 4;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
if (rv != SECSuccess)
@@ -829,8 +844,6 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_next_proto_nego_xtn;
- } else if (maxBytes < extension_length) {
- return 0;
}
return extension_length;
@@ -854,7 +867,10 @@ ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
2 /* protocol name list length */ +
ss->opt.nextProtoNego.len;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
/* NPN requires that the client's fallback protocol is first in the
* list. However, ALPN sends protocols in preference order. So we
* allocate a buffer and move the first protocol to the end of the
@@ -894,8 +910,6 @@ ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
}
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_app_layer_protocol_xtn;
- } else if (maxBytes < extension_length) {
- return 0;
}
return extension_length;
@@ -923,7 +937,10 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
2 /* protocol name list */ + 1 /* name length */ +
ss->ssl3.nextProto.len;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
if (rv != SECSuccess) {
@@ -942,8 +959,6 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
if (rv != SECSuccess) {
return -1;
}
- } else if (maxBytes < extension_length) {
- return 0;
}
return extension_length;
@@ -1045,7 +1060,10 @@ ssl3_ServerSendStatusRequestXtn(
return 0;
extension_length = 2 + 2;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
if (rv != SECSuccess)
@@ -1078,7 +1096,11 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
*/
extension_length = 9;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
SECStatus rv;
TLSExtensionData *xtnData;
@@ -1106,9 +1128,6 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
xtnData = &ss->xtnData;
xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
}
@@ -1120,7 +1139,7 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
SECStatus
ssl3_SendNewSessionTicket(sslSocket *ss)
{
- int i;
+ PRUint32 i;
SECStatus rv;
NewSessionTicket ticket;
SECItem plaintext;
@@ -1152,7 +1171,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
PK11Context *aes_ctx_pkcs11;
CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
- PK11Context *hmac_ctx_pkcs11;
+ PK11Context *hmac_ctx_pkcs11 = NULL;
unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
unsigned int computed_mac_length;
unsigned char iv[AES_BLOCK_SIZE];
@@ -1200,7 +1219,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
sslSessionID sid;
PORT_Memset(&sid, 0, sizeof(sslSessionID));
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
+ if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
+ ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
effectiveExchKeyType = kt_rsa;
} else {
effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
@@ -1243,6 +1263,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
+ cert_length /* cert */
+ 1 /* server name type */
+ srvNameLen /* name len + length field */
+ + 1 /* extendedMasterSecretUsed */
+ sizeof(ticket.ticket_lifetime_hint);
padding_length = AES_BLOCK_SIZE -
(ciphertext_length % AES_BLOCK_SIZE);
@@ -1341,6 +1362,11 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
if (rv != SECSuccess) goto loser;
}
+ /* extendedMasterSecretUsed */
+ rv = ssl3_AppendNumberToItem(
+ &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1);
+ if (rv != SECSuccess) goto loser;
+
PORT_Assert(plaintext.len == padding_length);
for (i = 0; i < padding_length; i++)
plaintext.data[i] = (unsigned char)padding_length;
@@ -1410,14 +1436,18 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
goto loser;
rv = PK11_DigestBegin(hmac_ctx_pkcs11);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
SESS_TICKET_KEY_NAME_LEN);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
&computed_mac_length, sizeof(computed_mac));
- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
if (rv != SECSuccess) goto loser;
}
@@ -1446,6 +1476,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
if (rv != SECSuccess) goto loser;
loser:
+ if (hmac_ctx_pkcs11)
+ PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
if (plaintext_item.data)
SECITEM_FreeItem(&plaintext_item, PR_FALSE);
if (ciphertext.data)
@@ -1495,7 +1527,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
if (data->len == 0) {
ss->xtnData.emptySessionTicket = PR_TRUE;
} else {
- int i;
+ PRUint32 i;
SECItem extension_data;
EncryptedSessionTicket enc_session_ticket;
unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
@@ -1698,9 +1730,10 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
goto loser;
}
- /* Read ticket_version (which is ignored for now.) */
+ /* Read ticket_version and reject if the version is wrong */
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
+ if (temp != TLS_EX_SESS_TICKET_VERSION) goto no_ticket;
+
parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
/* Read SSLVersion. */
@@ -1801,6 +1834,13 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
parsed_session_ticket->srvName.type = nameType;
}
+ /* Read extendedMasterSecretUsed */
+ temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
+ parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp;
+
/* Done parsing. Check that all bytes have been consumed. */
if (buffer_len != padding_length)
goto no_ticket;
@@ -1847,6 +1887,8 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
parsed_session_ticket->ms_is_wrapped;
sid->u.ssl3.masterValid = PR_TRUE;
sid->u.ssl3.keys.resumable = PR_TRUE;
+ sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->
+ extendedMasterSecretUsed;
/* Copy over client cert from session ticket if there is one. */
if (parsed_session_ticket->peer_cert.data != NULL) {
@@ -2085,7 +2127,10 @@ ssl3_SendRenegotiationInfoXtn(
(ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
: ss->ssl3.hs.finishedBytes);
needed = 5 + len;
- if (append && maxBytes >= needed) {
+ if (maxBytes < (PRUint32)needed) {
+ return 0;
+ }
+ if (append) {
SECStatus rv;
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
@@ -2138,8 +2183,8 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
}
if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
data->data + 1, len)) {
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
return SECFailure;
}
/* remember that we got this extension and it was correct. */
@@ -2263,8 +2308,8 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
if (!found) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure;
}
@@ -2277,8 +2322,8 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
/* We didn't offer an MKI, so this must be 0 length */
if (litem.len != 0) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure;
}
@@ -2374,7 +2419,7 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
SECStatus rv;
SECItem algorithms;
const unsigned char *b;
- unsigned int numAlgorithms, i, j;
+ unsigned int numAlgorithms, i;
/* Ignore this extension if we aren't doing TLS 1.2 or greater. */
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
@@ -2388,8 +2433,8 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
/* Trailing data, empty value, or odd-length value is invalid. */
if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
}
@@ -2401,30 +2446,24 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
ss->ssl3.hs.clientSigAndHash =
- PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
+ PORT_NewArray(SSLSignatureAndHashAlg, numAlgorithms);
if (!ss->ssl3.hs.clientSigAndHash) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
}
ss->ssl3.hs.numClientSigAndHash = 0;
b = algorithms.data;
- for (i = j = 0; i < numAlgorithms; i++) {
- unsigned char tls_hash = *(b++);
- unsigned char tls_sig = *(b++);
- SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash);
-
- if (hash == SEC_OID_UNKNOWN) {
- /* We ignore formats that we don't understand. */
- continue;
+ ss->ssl3.hs.numClientSigAndHash = 0;
+ for (i = 0; i < numAlgorithms; i++) {
+ SSLSignatureAndHashAlg *sigAndHash =
+ &ss->ssl3.hs.clientSigAndHash[ss->ssl3.hs.numClientSigAndHash];
+ sigAndHash->hashAlg = (SSLHashType)*(b++);
+ sigAndHash->sigAlg = (SSLSignType)*(b++);
+ if (ssl3_IsSupportedSignatureAlgorithm(sigAndHash)) {
+ ++ss->ssl3.hs.numClientSigAndHash;
}
- /* tls_sig support will be checked later in
- * ssl3_PickSignatureHashAlgorithm. */
- ss->ssl3.hs.clientSigAndHash[j].hashAlg = hash;
- ss->ssl3.hs.clientSigAndHash[j].sigAlg = tls_sig;
- ++j;
- ++ss->ssl3.hs.numClientSigAndHash;
}
if (!ss->ssl3.hs.numClientSigAndHash) {
@@ -2442,60 +2481,60 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
* 1.2 ClientHellos. */
static PRInt32
-ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
+ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
{
- static const unsigned char signatureAlgorithms[] = {
- /* This block is the contents of our signature_algorithms extension, in
- * wire format. See
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
- tls_hash_sha256, tls_sig_rsa,
- tls_hash_sha384, tls_sig_rsa,
- tls_hash_sha512, tls_sig_rsa,
- tls_hash_sha1, tls_sig_rsa,
-#ifndef NSS_DISABLE_ECC
- tls_hash_sha256, tls_sig_ecdsa,
- tls_hash_sha384, tls_sig_ecdsa,
- tls_hash_sha512, tls_sig_ecdsa,
- tls_hash_sha1, tls_sig_ecdsa,
-#endif
- tls_hash_sha256, tls_sig_dsa,
- tls_hash_sha1, tls_sig_dsa,
- };
PRInt32 extension_length;
+ unsigned int i;
+ PRInt32 pos=0;
+ PRUint32 policy;
+ PRUint8 buf[MAX_SIGNATURE_ALGORITHMS * 2];
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
return 0;
}
+ for (i=0; i < ss->ssl3.signatureAlgorithmCount; i++) {
+ SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(
+ ss->ssl3.signatureAlgorithms[i].hashAlg);
+ if ((NSS_GetAlgorithmPolicy(hashOID, & policy) != SECSuccess) ||
+ (policy & NSS_USE_ALG_IN_SSL_KX)) {
+ buf[pos++] = ss->ssl3.signatureAlgorithms[i].hashAlg;
+ buf[pos++] = ss->ssl3.signatureAlgorithms[i].sigAlg;
+ }
+ }
+
extension_length =
2 /* extension type */ +
2 /* extension length */ +
2 /* supported_signature_algorithms length */ +
- sizeof(signatureAlgorithms);
+ pos;
+
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
- if (append && maxBytes >= extension_length) {
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
- if (rv != SECSuccess)
- goto loser;
+ if (rv != SECSuccess) {
+ return -1;
+ }
rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- goto loser;
- rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
- sizeof(signatureAlgorithms), 2);
- if (rv != SECSuccess)
- goto loser;
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, buf, extension_length - 6, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_signature_algorithms_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
-
-loser:
- return -1;
}
unsigned int
@@ -2565,7 +2604,11 @@ ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
}
extension_length = 6; /* Type + length + number */
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_draft_version_xtn, 2);
if (rv != SECSuccess)
@@ -2578,9 +2621,6 @@ ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_tls13_draft_version_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
@@ -2633,6 +2673,51 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
return SECSuccess;
}
+static PRInt32
+ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+
+ if (!ss->opt.enableExtendedMS) {
+ return 0;
+ }
+
+#ifndef NO_PKCS11_BYPASS
+ /* Extended MS can only be used w/o bypass mode */
+ if (ss->opt.bypassPKCS11) {
+ PORT_Assert(0);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return -1;
+ }
+#endif
+
+ /* Always send the extension in this function, since the
+ * client always sends it and this function is only called on
+ * the server if we negotiated the extension. */
+ extension_length = 4; /* Type + length (0) */
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
+ ssl_extended_master_secret_xtn;
+ }
+
+ return extension_length;
+loser:
+ return -1;
+}
+
/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
* extension for TLS ClientHellos. */
static PRInt32
@@ -2646,7 +2731,12 @@ ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
if (!ss->opt.enableSignedCertTimestamps)
return 0;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
SECStatus rv;
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss,
@@ -2660,9 +2750,6 @@ ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_signed_certificate_timestamp_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
@@ -2671,6 +2758,46 @@ loser:
}
static SECStatus
+ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
+ SECItem *data)
+{
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
+ return SECSuccess;
+ }
+
+ if (!ss->opt.enableExtendedMS) {
+ return SECSuccess;
+ }
+
+#ifndef NO_PKCS11_BYPASS
+ /* Extended MS can only be used w/o bypass mode */
+ if (ss->opt.bypassPKCS11) {
+ PORT_Assert(0);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return SECFailure;
+ }
+#endif
+
+ if (data->len != 0) {
+ SSL_TRC(30, ("%d: SSL3[%d]: Bogus extended master secret extension",
+ SSL_GETPID(), ss->fd));
+ return SECFailure;
+ }
+
+ SSL_DBG(("%d: SSL[%d]: Negotiated extended master secret extension.",
+ SSL_GETPID(), ss->fd));
+
+ /* Keep track of negotiated extensions. */
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+
+ if (ss->sec.isServer) {
+ return ssl3_RegisterServerHelloExtensionSender(
+ ss, ex_type, ssl3_SendExtendedMasterSecretXtn);
+ }
+ return SECSuccess;
+}
+
+static SECStatus
ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data)
{
« no previous file with comments | « net/third_party/nss/ssl/ssl3ecc.c ('k') | net/third_party/nss/ssl/ssl3gthr.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698