| Index: net/third_party/nss/ssl/ssl3ext.c
|
| ===================================================================
|
| --- net/third_party/nss/ssl/ssl3ext.c (revision 202696)
|
| +++ net/third_party/nss/ssl/ssl3ext.c (working copy)
|
| @@ -74,6 +74,10 @@
|
| SECItem *data);
|
| static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
|
| PRUint32 maxBytes);
|
| +static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes);
|
| +static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
|
| + SECItem *data);
|
|
|
| /*
|
| * Write bytes. Using this function means the SECItem structure
|
| @@ -236,6 +240,7 @@
|
| { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
|
| { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
|
| { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
|
| + { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
|
| { -1, NULL }
|
| };
|
|
|
| @@ -276,7 +281,8 @@
|
| { 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_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
|
| + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
|
| /* any extra entries will appear as { 0, NULL } */
|
| };
|
|
|
| @@ -2039,3 +2045,134 @@
|
| return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
|
| ssl3_SendUseSRTPXtn);
|
| }
|
| +
|
| +/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
|
| + * from a client.
|
| + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
|
| +static SECStatus
|
| +ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| +{
|
| + SECStatus rv;
|
| + SECItem algorithms;
|
| + const unsigned char *b;
|
| + 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) {
|
| + return SECSuccess;
|
| + }
|
| +
|
| + /* Keep track of negotiated extensions. */
|
| + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
| +
|
| + rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data,
|
| + &data->len);
|
| + if (rv != SECSuccess) {
|
| + return SECFailure;
|
| + }
|
| + /* Trailing data or odd-length parameters is invalid. */
|
| + if (data->len != 0 || (algorithms.len & 1) != 0) {
|
| + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
| + return SECFailure;
|
| + }
|
| +
|
| + numAlgorithms = algorithms.len/2;
|
| +
|
| + if (numAlgorithms == 0) {
|
| + return SECSuccess;
|
| + }
|
| + /* We don't care to process excessive numbers of algorithms. */
|
| + if (numAlgorithms > 512) {
|
| + numAlgorithms = 512;
|
| + }
|
| +
|
| + ss->ssl3.hs.clientSigAndHash =
|
| + PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
|
| + if (!ss->ssl3.hs.clientSigAndHash) {
|
| + return SECFailure;
|
| + }
|
| + ss->ssl3.hs.numClientSigAndHash = 0;
|
| +
|
| + b = algorithms.data;
|
| + for (i = 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;
|
| + }
|
| + /* tls_sig support will be checked later in
|
| + * ssl3_PickSignatureHashAlgorithm. */
|
| + ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash;
|
| + ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig;
|
| + ss->ssl3.hs.numClientSigAndHash++;
|
| + }
|
| +
|
| + if (!ss->ssl3.hs.numClientSigAndHash) {
|
| + /* We didn't understand any of the client's requested signature
|
| + * formats. We'll use the defaults. */
|
| + PORT_Free(ss->ssl3.hs.clientSigAndHash);
|
| + ss->ssl3.hs.clientSigAndHash = NULL;
|
| + }
|
| +
|
| + return SECSuccess;
|
| +}
|
| +
|
| +/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
|
| + * 1.2 ClientHellos. */
|
| +static PRInt32
|
| +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_sha1, tls_sig_rsa,
|
| +#ifdef NSS_ENABLE_ECC
|
| + tls_hash_sha256, tls_sig_ecdsa,
|
| + tls_hash_sha384, 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;
|
| +
|
| + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
|
| + return 0;
|
| + }
|
| +
|
| + extension_length =
|
| + 2 /* extension type */ +
|
| + 2 /* extension length */ +
|
| + 2 /* supported_signature_algorithms length */ +
|
| + sizeof(signatureAlgorithms);
|
| +
|
| + if (append && maxBytes >= extension_length) {
|
| + SECStatus rv;
|
| + rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + 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;
|
| + 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;
|
| +}
|
|
|