| Index: net/third_party/nss/patches/tls12backuphash.patch
|
| ===================================================================
|
| --- net/third_party/nss/patches/tls12backuphash.patch (revision 242942)
|
| +++ net/third_party/nss/patches/tls12backuphash.patch (working copy)
|
| @@ -1,220 +0,0 @@
|
| -Index: net/third_party/nss/ssl/ssl3con.c
|
| -===================================================================
|
| ---- net/third_party/nss/ssl/ssl3con.c (revision 220594)
|
| -+++ net/third_party/nss/ssl/ssl3con.c (working copy)
|
| -@@ -3933,6 +3933,20 @@
|
| - ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
|
| - return SECFailure;
|
| - }
|
| -+
|
| -+ /* A backup SHA-1 hash for a potential client auth signature. */
|
| -+ if (!ss->sec.isServer) {
|
| -+ ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1);
|
| -+ if (ss->ssl3.hs.md5 == NULL) {
|
| -+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
|
| -+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| -+ return SECFailure;
|
| -+ }
|
| -+ }
|
| - } else {
|
| - /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
|
| - * created successfully. */
|
| -@@ -4043,6 +4057,13 @@
|
| - ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
|
| - return rv;
|
| - }
|
| -+ if (ss->ssl3.hs.md5) {
|
| -+ rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
|
| -+ if (rv != SECSuccess) {
|
| -+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| -+ return rv;
|
| -+ }
|
| -+ }
|
| - } else {
|
| - rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
|
| - if (rv != SECSuccess) {
|
| -@@ -4791,6 +4812,30 @@
|
| - return rv;
|
| - }
|
| -
|
| -+static SECStatus
|
| -+ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
|
| -+ SSL3Hashes * hashes) /* output goes here. */
|
| -+{
|
| -+ SECStatus rv = SECSuccess;
|
| -+
|
| -+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
|
| -+ PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
|
| -+
|
| -+ rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len,
|
| -+ sizeof(hashes->u.raw));
|
| -+ if (rv != SECSuccess) {
|
| -+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| -+ rv = SECFailure;
|
| -+ goto loser;
|
| -+ }
|
| -+ hashes->hashAlg = SEC_OID_SHA1;
|
| -+
|
| -+loser:
|
| -+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
|
| -+ ss->ssl3.hs.md5 = NULL;
|
| -+ return rv;
|
| -+}
|
| -+
|
| - /*
|
| - * SSL 2 based implementations pass in the initial outbound buffer
|
| - * so that the handshake hash can contain the included information.
|
| -@@ -6044,7 +6089,17 @@
|
| - SSL_GETPID(), ss->fd));
|
| -
|
| - ssl_GetSpecReadLock(ss);
|
| -- rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
|
| -+ /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash
|
| -+ * function (SHA-256). If the server or the client does not support SHA-256
|
| -+ * as a signature hash, we can either maintain a backup SHA-1 handshake
|
| -+ * hash or buffer all handshake messages.
|
| -+ */
|
| -+ if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
|
| -+ rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
|
| -+ PORT_Assert(ss->ssl3.hs.md5 == NULL);
|
| -+ } else {
|
| -+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
|
| -+ }
|
| - ssl_ReleaseSpecReadLock(ss);
|
| - if (rv != SECSuccess) {
|
| - goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
|
| -@@ -6098,11 +6153,6 @@
|
| - if (rv != SECSuccess) {
|
| - goto done;
|
| - }
|
| -- /* We always sign using the handshake hash function. It's possible that
|
| -- * a server could support SHA-256 as the handshake hash but not as a
|
| -- * signature hash. In that case we wouldn't be able to do client
|
| -- * certificates with it. The alternative is to buffer all handshake
|
| -- * messages. */
|
| - sigAndHash.hashAlg = hashes.hashAlg;
|
| -
|
| - rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
|
| -@@ -6802,6 +6852,70 @@
|
| - }
|
| -
|
| -
|
| -+/*
|
| -+ * Returns true if the client authentication key is an RSA or DSA key that
|
| -+ * may be able to sign only SHA-1 hashes.
|
| -+ */
|
| -+static PRBool
|
| -+ssl3_ClientKeyPrefersSHA1(sslSocket *ss)
|
| -+{
|
| -+ SECKEYPublicKey *pubk;
|
| -+ PRBool prefer_sha1 = PR_FALSE;
|
| -+
|
| -+#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32)
|
| -+ /* If the key is in CAPI, assume conservatively that the CAPI service
|
| -+ * provider may be unable to sign SHA-256 hashes.
|
| -+ */
|
| -+ if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) {
|
| -+ /* CAPI only supports RSA and DSA signatures, so we don't need to
|
| -+ * check the key type. */
|
| -+ return PR_TRUE;
|
| -+ }
|
| -+#endif /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */
|
| -+
|
| -+ /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
|
| -+ * it may be unable to sign SHA-256 hashes. This is the case for older
|
| -+ * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
|
| -+ * older, DSA key size is at most 1024 bits and the hash function must
|
| -+ * be SHA-1.
|
| -+ */
|
| -+ pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
|
| -+ if (pubk == NULL) {
|
| -+ return PR_FALSE;
|
| -+ }
|
| -+ if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) {
|
| -+ prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128;
|
| -+ }
|
| -+ SECKEY_DestroyPublicKey(pubk);
|
| -+ return prefer_sha1;
|
| -+}
|
| -+
|
| -+/* Destroys the backup handshake hash context if we don't need it. */
|
| -+static void
|
| -+ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
|
| -+ const SECItem *algorithms)
|
| -+{
|
| -+ PRBool need_backup_hash = PR_FALSE;
|
| -+ unsigned int i;
|
| -+
|
| -+ PORT_Assert(ss->ssl3.hs.md5);
|
| -+ if (ssl3_ClientKeyPrefersSHA1(ss)) {
|
| -+ /* Use SHA-1 if the server supports it. */
|
| -+ for (i = 0; i < algorithms->len; i += 2) {
|
| -+ if (algorithms->data[i] == tls_hash_sha1 &&
|
| -+ (algorithms->data[i+1] == tls_sig_rsa ||
|
| -+ algorithms->data[i+1] == tls_sig_dsa)) {
|
| -+ need_backup_hash = PR_TRUE;
|
| -+ break;
|
| -+ }
|
| -+ }
|
| -+ }
|
| -+ if (!need_backup_hash) {
|
| -+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
|
| -+ ss->ssl3.hs.md5 = NULL;
|
| -+ }
|
| -+}
|
| -+
|
| - typedef struct dnameNode {
|
| - struct dnameNode *next;
|
| - SECItem name;
|
| -@@ -6994,6 +7108,9 @@
|
| - }
|
| - goto send_no_certificate;
|
| - }
|
| -+ if (isTLS12) {
|
| -+ ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
|
| -+ }
|
| - break; /* not an error */
|
| - }
|
| - #endif /* NSS_PLATFORM_CLIENT_AUTH */
|
| -@@ -7029,6 +7146,9 @@
|
| - }
|
| - goto send_no_certificate;
|
| - }
|
| -+ if (isTLS12) {
|
| -+ ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
|
| -+ }
|
| - break; /* not an error */
|
| -
|
| - case SECFailure:
|
| -@@ -7227,6 +7347,13 @@
|
| - (ss->ssl3.platformClientKey ||
|
| - ss->ssl3.clientPrivateKey != NULL);
|
| -
|
| -+ if (!sendClientCert &&
|
| -+ ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
|
| -+ /* Don't need the backup handshake hash. */
|
| -+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
|
| -+ ss->ssl3.hs.md5 = NULL;
|
| -+ }
|
| -+
|
| - /* We must wait for the server's certificate to be authenticated before
|
| - * sending the client certificate in order to disclosing the client
|
| - * certificate to an attacker that does not have a valid cert for the
|
| -Index: net/third_party/nss/ssl/sslimpl.h
|
| -===================================================================
|
| ---- net/third_party/nss/ssl/sslimpl.h (revision 220594)
|
| -+++ net/third_party/nss/ssl/sslimpl.h (working copy)
|
| -@@ -838,6 +838,9 @@
|
| - * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and
|
| - * |sha| for SHA-1.
|
| - * TLS 1.2 and later use only |sha|, for SHA-256. */
|
| -+ /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup
|
| -+ * handshake hash for generating client auth signatures. Confusingly, the
|
| -+ * backup hash function is SHA-1. */
|
| - PK11Context * md5;
|
| - PK11Context * sha;
|
| -
|
|
|