| OLD | NEW |
| (Empty) |
| 1 diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con
.c | |
| 2 index 06992e0..cf7ef32 100644 | |
| 3 --- a/net/third_party/nss/ssl/ssl3con.c | |
| 4 +++ b/net/third_party/nss/ssl/ssl3con.c | |
| 5 @@ -6973,14 +6973,27 @@ no_memory: /* no-memory error has already been set.
*/ | |
| 6 | |
| 7 | |
| 8 /* | |
| 9 - * Returns true if the client authentication key is an RSA or DSA key that | |
| 10 - * may be able to sign only SHA-1 hashes. | |
| 11 + * Returns the TLS signature algorithm for the client authentication key and | |
| 12 + * whether it is an RSA or DSA key that may be able to sign only SHA-1 hashes. | |
| 13 */ | |
| 14 -static PRBool | |
| 15 -ssl3_ClientKeyPrefersSHA1(sslSocket *ss) | |
| 16 +static SECStatus | |
| 17 +ssl3_ExtractClientKeyInfo(sslSocket *ss, | |
| 18 + TLSSignatureAlgorithm *sigAlg, | |
| 19 + PRBool *preferSha1) | |
| 20 { | |
| 21 + SECStatus rv = SECSuccess; | |
| 22 SECKEYPublicKey *pubk; | |
| 23 - PRBool prefer_sha1 = PR_FALSE; | |
| 24 + | |
| 25 + pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); | |
| 26 + if (pubk == NULL) { | |
| 27 + rv = SECFailure; | |
| 28 + goto done; | |
| 29 + } | |
| 30 + | |
| 31 + rv = ssl3_TLSSignatureAlgorithmForKeyType(pubk->keyType, sigAlg); | |
| 32 + if (rv != SECSuccess) { | |
| 33 + goto done; | |
| 34 + } | |
| 35 | |
| 36 #if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32) | |
| 37 /* If the key is in CAPI, assume conservatively that the CAPI service | |
| 38 @@ -6989,7 +7002,8 @@ ssl3_ClientKeyPrefersSHA1(sslSocket *ss) | |
| 39 if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) { | |
| 40 /* CAPI only supports RSA and DSA signatures, so we don't need to | |
| 41 * check the key type. */ | |
| 42 - return PR_TRUE; | |
| 43 + *preferSha1 = PR_TRUE; | |
| 44 + goto done; | |
| 45 } | |
| 46 #endif /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */ | |
| 47 | |
| 48 @@ -6999,38 +7013,61 @@ ssl3_ClientKeyPrefersSHA1(sslSocket *ss) | |
| 49 * older, DSA key size is at most 1024 bits and the hash function must | |
| 50 * be SHA-1. | |
| 51 */ | |
| 52 - pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); | |
| 53 - if (pubk == NULL) { | |
| 54 - return PR_FALSE; | |
| 55 - } | |
| 56 if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) { | |
| 57 - prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128; | |
| 58 + *preferSha1 = SECKEY_PublicKeyStrength(pubk) <= 128; | |
| 59 + } else { | |
| 60 + *preferSha1 = PR_FALSE; | |
| 61 } | |
| 62 - SECKEY_DestroyPublicKey(pubk); | |
| 63 - return prefer_sha1; | |
| 64 + | |
| 65 + done: | |
| 66 + if (pubk) | |
| 67 + SECKEY_DestroyPublicKey(pubk); | |
| 68 + return rv; | |
| 69 } | |
| 70 | |
| 71 -/* Destroys the backup handshake hash context if we don't need it. */ | |
| 72 +/* Destroys the backup handshake hash context if we don't need it. Note that | |
| 73 + * this function selects the hash algorithm for client authentication | |
| 74 + * signatures; ssl3_SendCertificateVerify uses the presence of the backup hash | |
| 75 + * to determine whether to use SHA-1 or SHA-256. */ | |
| 76 static void | |
| 77 ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, | |
| 78 const SECItem *algorithms) | |
| 79 { | |
| 80 - PRBool need_backup_hash = PR_FALSE; | |
| 81 + SECStatus rv; | |
| 82 + TLSSignatureAlgorithm sigAlg; | |
| 83 + PRBool preferSha1; | |
| 84 + PRBool supportsSha1 = PR_FALSE; | |
| 85 + PRBool supportsSha256 = PR_FALSE; | |
| 86 + PRBool needBackupHash = PR_FALSE; | |
| 87 unsigned int i; | |
| 88 | |
| 89 PORT_Assert(ss->ssl3.hs.md5); | |
| 90 - if (ssl3_ClientKeyPrefersSHA1(ss)) { | |
| 91 - /* Use SHA-1 if the server supports it. */ | |
| 92 - for (i = 0; i < algorithms->len; i += 2) { | |
| 93 - if (algorithms->data[i] == tls_hash_sha1 && | |
| 94 - (algorithms->data[i+1] == tls_sig_rsa || | |
| 95 - algorithms->data[i+1] == tls_sig_dsa)) { | |
| 96 - need_backup_hash = PR_TRUE; | |
| 97 - break; | |
| 98 + | |
| 99 + /* Determine the key's signature algorithm and whether it prefers SHA-1. */ | |
| 100 + rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1); | |
| 101 + if (rv != SECSuccess) { | |
| 102 + goto done; | |
| 103 + } | |
| 104 + | |
| 105 + /* Determine the server's hash support for that signature algorithm. */ | |
| 106 + for (i = 0; i < algorithms->len; i += 2) { | |
| 107 + if (algorithms->data[i+1] == sigAlg) { | |
| 108 + if (algorithms->data[i] == tls_hash_sha1) { | |
| 109 + supportsSha1 = PR_TRUE; | |
| 110 + } else if (algorithms->data[i] == tls_hash_sha256) { | |
| 111 + supportsSha256 = PR_TRUE; | |
| 112 } | |
| 113 } | |
| 114 } | |
| 115 - if (!need_backup_hash) { | |
| 116 + | |
| 117 + /* If either the server does not support SHA-256 or the client key prefers | |
| 118 + * SHA-1, leave the backup hash. */ | |
| 119 + if (supportsSha1 && (preferSha1 || !supportsSha256)) { | |
| 120 + needBackupHash = PR_TRUE; | |
| 121 + } | |
| 122 + | |
| 123 +done: | |
| 124 + if (!needBackupHash) { | |
| 125 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); | |
| 126 ss->ssl3.hs.md5 = NULL; | |
| 127 } | |
| OLD | NEW |