diff options
author | davidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-04 18:53:54 +0000 |
---|---|---|
committer | davidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-04 18:53:54 +0000 |
commit | 49e128ede845c021d3c32b3c82d603a264957cde (patch) | |
tree | 07c1ba0a2c9f5244d3352edd830525d3613c1467 /net/third_party/nss/patches | |
parent | fd7441e75dec60901fde5e55ca2ef6cde87f4577 (diff) | |
download | chromium_src-49e128ede845c021d3c32b3c82d603a264957cde.zip chromium_src-49e128ede845c021d3c32b3c82d603a264957cde.tar.gz chromium_src-49e128ede845c021d3c32b3c82d603a264957cde.tar.bz2 |
Use SHA-1 in TLS 1.2 client auth if the server requests it.
Consider the signature algorithms requested by the server in addition to those
supported by the client key in ssl3_DestroyBackupHandshakeHashIfNotNeeded.
This also takes the client key's signature algorithm into account.
BUG=325254
TEST=manual testing by bug reporter
Review URL: https://codereview.chromium.org/102663002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238730 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party/nss/patches')
-rwxr-xr-x | net/third_party/nss/patches/applypatches.sh | 2 | ||||
-rw-r--r-- | net/third_party/nss/patches/tls12backuphash2.patch | 127 |
2 files changed, 129 insertions, 0 deletions
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh index ebea84f..ed1a5c6 100755 --- a/net/third_party/nss/patches/applypatches.sh +++ b/net/third_party/nss/patches/applypatches.sh @@ -75,3 +75,5 @@ patch -p4 < $patches_dir/channelid2.patch patch -p5 < $patches_dir/signedcertificatetimestamps.patch patch -p4 < $patches_dir/cipherorder.patch + +patch -p5 < $patches_dir/tls12backuphash2.patch diff --git a/net/third_party/nss/patches/tls12backuphash2.patch b/net/third_party/nss/patches/tls12backuphash2.patch new file mode 100644 index 0000000..85e5308 --- /dev/null +++ b/net/third_party/nss/patches/tls12backuphash2.patch @@ -0,0 +1,127 @@ +diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c +index 06992e0..cf7ef32 100644 +--- a/net/third_party/nss/ssl/ssl3con.c ++++ b/net/third_party/nss/ssl/ssl3con.c +@@ -6973,14 +6973,27 @@ no_memory: /* no-memory error has already been set. */ + + + /* +- * Returns true if the client authentication key is an RSA or DSA key that +- * may be able to sign only SHA-1 hashes. ++ * Returns the TLS signature algorithm for the client authentication key and ++ * whether it is an RSA or DSA key that may be able to sign only SHA-1 hashes. + */ +-static PRBool +-ssl3_ClientKeyPrefersSHA1(sslSocket *ss) ++static SECStatus ++ssl3_ExtractClientKeyInfo(sslSocket *ss, ++ TLSSignatureAlgorithm *sigAlg, ++ PRBool *preferSha1) + { ++ SECStatus rv = SECSuccess; + SECKEYPublicKey *pubk; +- PRBool prefer_sha1 = PR_FALSE; ++ ++ pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); ++ if (pubk == NULL) { ++ rv = SECFailure; ++ goto done; ++ } ++ ++ rv = ssl3_TLSSignatureAlgorithmForKeyType(pubk->keyType, sigAlg); ++ if (rv != SECSuccess) { ++ goto done; ++ } + + #if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32) + /* If the key is in CAPI, assume conservatively that the CAPI service +@@ -6989,7 +7002,8 @@ ssl3_ClientKeyPrefersSHA1(sslSocket *ss) + 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; ++ *preferSha1 = PR_TRUE; ++ goto done; + } + #endif /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */ + +@@ -6999,38 +7013,61 @@ ssl3_ClientKeyPrefersSHA1(sslSocket *ss) + * 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; ++ *preferSha1 = SECKEY_PublicKeyStrength(pubk) <= 128; ++ } else { ++ *preferSha1 = PR_FALSE; + } +- SECKEY_DestroyPublicKey(pubk); +- return prefer_sha1; ++ ++ done: ++ if (pubk) ++ SECKEY_DestroyPublicKey(pubk); ++ return rv; + } + +-/* Destroys the backup handshake hash context if we don't need it. */ ++/* Destroys the backup handshake hash context if we don't need it. Note that ++ * this function selects the hash algorithm for client authentication ++ * signatures; ssl3_SendCertificateVerify uses the presence of the backup hash ++ * to determine whether to use SHA-1 or SHA-256. */ + static void + ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, + const SECItem *algorithms) + { +- PRBool need_backup_hash = PR_FALSE; ++ SECStatus rv; ++ TLSSignatureAlgorithm sigAlg; ++ PRBool preferSha1; ++ PRBool supportsSha1 = PR_FALSE; ++ PRBool supportsSha256 = PR_FALSE; ++ PRBool needBackupHash = 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; ++ ++ /* Determine the key's signature algorithm and whether it prefers SHA-1. */ ++ rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1); ++ if (rv != SECSuccess) { ++ goto done; ++ } ++ ++ /* Determine the server's hash support for that signature algorithm. */ ++ for (i = 0; i < algorithms->len; i += 2) { ++ if (algorithms->data[i+1] == sigAlg) { ++ if (algorithms->data[i] == tls_hash_sha1) { ++ supportsSha1 = PR_TRUE; ++ } else if (algorithms->data[i] == tls_hash_sha256) { ++ supportsSha256 = PR_TRUE; + } + } + } +- if (!need_backup_hash) { ++ ++ /* If either the server does not support SHA-256 or the client key prefers ++ * SHA-1, leave the backup hash. */ ++ if (supportsSha1 && (preferSha1 || !supportsSha256)) { ++ needBackupHash = PR_TRUE; ++ } ++ ++done: ++ if (!needBackupHash) { + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); + ss->ssl3.hs.md5 = NULL; + } |