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 |