OLD | NEW |
1 Index: net/third_party/nss/ssl/ssl3con.c | 1 Index: net/third_party/nss/ssl/ssl3con.c |
2 =================================================================== | 2 =================================================================== |
3 --- net/third_party/nss/ssl/ssl3con.c (revision 220594) | 3 --- net/third_party/nss/ssl/ssl3con.c (revision 220594) |
4 +++ net/third_party/nss/ssl/ssl3con.c (working copy) | 4 +++ net/third_party/nss/ssl/ssl3con.c (working copy) |
5 @@ -3933,6 +3933,20 @@ | 5 @@ -3933,6 +3933,20 @@ |
6 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); | 6 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
7 return SECFailure; | 7 return SECFailure; |
8 } | 8 } |
9 + | 9 + |
10 + /* A backup SHA-1 hash for a potential client auth signature. */ | 10 + /* A backup SHA-1 hash for a potential client auth signature. */ |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 goto done; | 92 goto done; |
93 } | 93 } |
94 - /* We always sign using the handshake hash function. It's possible that | 94 - /* We always sign using the handshake hash function. It's possible that |
95 - * a server could support SHA-256 as the handshake hash but not as a | 95 - * a server could support SHA-256 as the handshake hash but not as a |
96 - * signature hash. In that case we wouldn't be able to do client | 96 - * signature hash. In that case we wouldn't be able to do client |
97 - * certificates with it. The alternative is to buffer all handshake | 97 - * certificates with it. The alternative is to buffer all handshake |
98 - * messages. */ | 98 - * messages. */ |
99 sigAndHash.hashAlg = hashes.hashAlg; | 99 sigAndHash.hashAlg = hashes.hashAlg; |
100 | 100 |
101 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); | 101 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
102 @@ -6994,6 +7044,56 @@ | 102 @@ -6802,6 +6852,70 @@ |
| 103 } |
| 104 |
| 105 |
| 106 +/* |
| 107 + * Returns true if the client authentication key is an RSA or DSA key that |
| 108 + * may be able to sign only SHA-1 hashes. |
| 109 + */ |
| 110 +static PRBool |
| 111 +ssl3_ClientKeyPrefersSHA1(sslSocket *ss) |
| 112 +{ |
| 113 + SECKEYPublicKey *pubk; |
| 114 + PRBool prefer_sha1 = PR_FALSE; |
| 115 + |
| 116 +#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32) |
| 117 + /* If the key is in CAPI, assume conservatively that the CAPI service |
| 118 + * provider may be unable to sign SHA-256 hashes. |
| 119 + */ |
| 120 + if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) { |
| 121 +» /* CAPI only supports RSA and DSA signatures, so we don't need to |
| 122 +» * check the key type. */ |
| 123 +» return PR_TRUE; |
| 124 + } |
| 125 +#endif /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */ |
| 126 + |
| 127 + /* If the key is a 1024-bit RSA or DSA key, assume conservatively that |
| 128 + * it may be unable to sign SHA-256 hashes. This is the case for older |
| 129 + * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and |
| 130 + * older, DSA key size is at most 1024 bits and the hash function must |
| 131 + * be SHA-1. |
| 132 + */ |
| 133 + pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); |
| 134 + if (pubk == NULL) { |
| 135 +» return PR_FALSE; |
| 136 + } |
| 137 + if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) { |
| 138 +» prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128; |
| 139 + } |
| 140 + SECKEY_DestroyPublicKey(pubk); |
| 141 + return prefer_sha1; |
| 142 +} |
| 143 + |
| 144 +/* Destroys the backup handshake hash context if we don't need it. */ |
| 145 +static void |
| 146 +ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, |
| 147 +» » » » » const SECItem *algorithms) |
| 148 +{ |
| 149 + PRBool need_backup_hash = PR_FALSE; |
| 150 + unsigned int i; |
| 151 + |
| 152 + PORT_Assert(ss->ssl3.hs.md5); |
| 153 + if (ssl3_ClientKeyPrefersSHA1(ss)) { |
| 154 +» /* Use SHA-1 if the server supports it. */ |
| 155 +» for (i = 0; i < algorithms->len; i += 2) { |
| 156 +» if (algorithms->data[i] == tls_hash_sha1 && |
| 157 +» » (algorithms->data[i+1] == tls_sig_rsa || |
| 158 +» » algorithms->data[i+1] == tls_sig_dsa)) { |
| 159 +» » need_backup_hash = PR_TRUE; |
| 160 +» » break; |
| 161 +» } |
| 162 +» } |
| 163 + } |
| 164 + if (!need_backup_hash) { |
| 165 +» PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); |
| 166 +» ss->ssl3.hs.md5 = NULL; |
| 167 + } |
| 168 +} |
| 169 + |
| 170 typedef struct dnameNode { |
| 171 struct dnameNode *next; |
| 172 SECItem name; |
| 173 @@ -6994,6 +7108,9 @@ |
103 } | 174 } |
104 goto send_no_certificate; | 175 goto send_no_certificate; |
105 } | 176 } |
106 + | 177 +» if (isTLS12) { |
107 +» if (isTLS12 && ss->ssl3.hs.md5) { | 178 +» » ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms); |
108 +» » PRBool need_backup_hash = PR_FALSE; | |
109 +» » PRBool prefer_sha1 = PR_FALSE; | |
110 +#ifdef _WIN32 | |
111 +» » /* If the key is in CAPI, assume conservatively that the CAPI | |
112 +» » * service provider may be unable to sign SHA-256 hashes. | |
113 +» » */ | |
114 +» » if (ss->ssl3.platformClientKey->dwKeySpec != | |
115 +» » CERT_NCRYPT_KEY_SPEC) { | |
116 +» » /* CAPI only supports RSA and DSA signatures, so we don't | |
117 +» » * need to check the key type. */ | |
118 +» » prefer_sha1 = PR_TRUE; | |
119 +» » } | |
120 +#endif /* _WIN32 */ | |
121 +» » /* If the key is a 1024-bit RSA or DSA key, assume | |
122 +» » * conservatively that it may be unable to sign SHA-256 | |
123 +» » * hashes. This is the case for older Estonian ID cards that | |
124 +» » * have 1024-bit RSA keys. In FIPS 186-2 and older, DSA key | |
125 +» » * size is at most 1024 bits and the hash function must be | |
126 +» » * SHA-1. | |
127 +» » */ | |
128 +» » if (!prefer_sha1) { | |
129 +» » SECKEYPublicKey *pubk = | |
130 +» » » CERT_ExtractPublicKey(ss->ssl3.clientCertificate); | |
131 +» » if (pubk == NULL) { | |
132 +» » » errCode = SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE; | |
133 + » » » goto loser; | |
134 +» » } | |
135 +» » if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) { | |
136 +» » » prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128; | |
137 +» » } | |
138 +» » SECKEY_DestroyPublicKey(pubk); | |
139 +» » } | |
140 +» » /* Use SHA-1 if the server supports it. */ | |
141 +» » if (prefer_sha1) { | |
142 +» » for (i = 0; i < algorithms.len; i += 2) { | |
143 +» » » if (algorithms.data[i] == tls_hash_sha1 && | |
144 +» » » (algorithms.data[i+1] == tls_sig_rsa || | |
145 +» » » algorithms.data[i+1] == tls_sig_dsa)) { | |
146 +» » » need_backup_hash = PR_TRUE; | |
147 +» » » break; | |
148 +» » » } | |
149 +» » } | |
150 +» » } | |
151 +» » if (!need_backup_hash) { | |
152 +» » PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); | |
153 +» » ss->ssl3.hs.md5 = NULL; | |
154 +» » } | |
155 + } | 179 + } |
156 break; /* not an error */ | 180 break; /* not an error */ |
157 } | 181 } |
158 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 182 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
159 @@ -7227,6 +7327,13 @@ | 183 @@ -7029,6 +7146,9 @@ |
| 184 » } |
| 185 » goto send_no_certificate; |
| 186 » } |
| 187 +» if (isTLS12) { |
| 188 +» ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms); |
| 189 +» } |
| 190 » break;» /* not an error */ |
| 191 |
| 192 case SECFailure: |
| 193 @@ -7227,6 +7347,13 @@ |
160 (ss->ssl3.platformClientKey || | 194 (ss->ssl3.platformClientKey || |
161 ss->ssl3.clientPrivateKey != NULL); | 195 ss->ssl3.clientPrivateKey != NULL); |
162 | 196 |
163 + if (!sendClientCert && | 197 + if (!sendClientCert && |
164 + ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { | 198 + ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) { |
165 + /* Don't need the backup handshake hash. */ | 199 + /* Don't need the backup handshake hash. */ |
166 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); | 200 + PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE); |
167 + ss->ssl3.hs.md5 = NULL; | 201 + ss->ssl3.hs.md5 = NULL; |
168 + } | 202 + } |
169 + | 203 + |
170 /* We must wait for the server's certificate to be authenticated before | 204 /* We must wait for the server's certificate to be authenticated before |
171 * sending the client certificate in order to disclosing the client | 205 * sending the client certificate in order to disclosing the client |
172 * certificate to an attacker that does not have a valid cert for the | 206 * certificate to an attacker that does not have a valid cert for the |
173 Index: net/third_party/nss/ssl/sslimpl.h | 207 Index: net/third_party/nss/ssl/sslimpl.h |
174 =================================================================== | 208 =================================================================== |
175 --- net/third_party/nss/ssl/sslimpl.h (revision 220594) | 209 --- net/third_party/nss/ssl/sslimpl.h (revision 220594) |
176 +++ net/third_party/nss/ssl/sslimpl.h (working copy) | 210 +++ net/third_party/nss/ssl/sslimpl.h (working copy) |
177 @@ -838,6 +838,9 @@ | 211 @@ -838,6 +838,9 @@ |
178 * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and | 212 * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and |
179 * |sha| for SHA-1. | 213 * |sha| for SHA-1. |
180 * TLS 1.2 and later use only |sha|, for SHA-256. */ | 214 * TLS 1.2 and later use only |sha|, for SHA-256. */ |
181 + /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup | 215 + /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup |
182 + * handshake hash for generating client auth signatures. Confusingly, the | 216 + * handshake hash for generating client auth signatures. Confusingly, the |
183 + * backup hash function is SHA-1. */ | 217 + * backup hash function is SHA-1. */ |
184 PK11Context * md5; | 218 PK11Context * md5; |
185 PK11Context * sha; | 219 PK11Context * sha; |
186 | 220 |
OLD | NEW |