| Index: net/third_party/nss/patches/tls12backuphash.patch | 
| =================================================================== | 
| --- net/third_party/nss/patches/tls12backuphash.patch	(revision 223079) | 
| +++ net/third_party/nss/patches/tls12backuphash.patch	(working copy) | 
| @@ -99,64 +99,98 @@ | 
| sigAndHash.hashAlg = hashes.hashAlg; | 
|  | 
| rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); | 
| -@@ -6994,6 +7044,56 @@ | 
| +@@ -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 && ss->ssl3.hs.md5) { | 
| -+		PRBool need_backup_hash = PR_FALSE; | 
| -+		PRBool prefer_sha1 = PR_FALSE; | 
| -+#ifdef _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. */ | 
| -+		    prefer_sha1 = PR_TRUE; | 
| -+		} | 
| -+#endif  /* _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. | 
| -+		 */ | 
| -+		if (!prefer_sha1) { | 
| -+		    SECKEYPublicKey *pubk = | 
| -+			CERT_ExtractPublicKey(ss->ssl3.clientCertificate); | 
| -+		    if (pubk == NULL) { | 
| -+			errCode = SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE; | 
| -+ 			goto loser; | 
| -+		    } | 
| -+		    if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) { | 
| -+			prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128; | 
| -+		    } | 
| -+		    SECKEY_DestroyPublicKey(pubk); | 
| -+		} | 
| -+		/* Use SHA-1 if the server supports it. */ | 
| -+		if (prefer_sha1) { | 
| -+		    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; | 
| -+		} | 
| ++	    if (isTLS12) { | 
| ++		ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms); | 
| +	    } | 
| break;  /* not an error */ | 
| } | 
| #endif   /* NSS_PLATFORM_CLIENT_AUTH */ | 
| -@@ -7227,6 +7327,13 @@ | 
| +@@ -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); | 
|  | 
|  |