summaryrefslogtreecommitdiffstats
path: root/net/third_party/nss/patches
diff options
context:
space:
mode:
authordavidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 18:53:54 +0000
committerdavidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 18:53:54 +0000
commit49e128ede845c021d3c32b3c82d603a264957cde (patch)
tree07c1ba0a2c9f5244d3352edd830525d3613c1467 /net/third_party/nss/patches
parentfd7441e75dec60901fde5e55ca2ef6cde87f4577 (diff)
downloadchromium_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-xnet/third_party/nss/patches/applypatches.sh2
-rw-r--r--net/third_party/nss/patches/tls12backuphash2.patch127
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;
+ }