OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/cert_verify_proc.h" | 5 #include "net/cert/cert_verify_proc.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/sha1.h" | 8 #include "base/sha1.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #elif defined(OS_ANDROID) | 25 #elif defined(OS_ANDROID) |
26 #include "net/cert/cert_verify_proc_android.h" | 26 #include "net/cert/cert_verify_proc_android.h" |
27 #elif defined(OS_MACOSX) | 27 #elif defined(OS_MACOSX) |
28 #include "net/cert/cert_verify_proc_mac.h" | 28 #include "net/cert/cert_verify_proc_mac.h" |
29 #elif defined(OS_WIN) | 29 #elif defined(OS_WIN) |
30 #include "net/cert/cert_verify_proc_win.h" | 30 #include "net/cert/cert_verify_proc_win.h" |
31 #else | 31 #else |
32 #error Implement certificate verification. | 32 #error Implement certificate verification. |
33 #endif | 33 #endif |
34 | 34 |
35 | |
36 namespace net { | 35 namespace net { |
37 | 36 |
38 namespace { | 37 namespace { |
39 | 38 |
40 // Constants used to build histogram names | 39 // Constants used to build histogram names |
41 const char kLeafCert[] = "Leaf"; | 40 const char kLeafCert[] = "Leaf"; |
42 const char kIntermediateCert[] = "Intermediate"; | 41 const char kIntermediateCert[] = "Intermediate"; |
43 const char kRootCert[] = "Root"; | 42 const char kRootCert[] = "Root"; |
44 // Matches the order of X509Certificate::PublicKeyType | 43 // Matches the order of X509Certificate::PublicKeyType |
45 const char* const kCertTypeStrings[] = { | 44 const char* const kCertTypeStrings[] = {"Unknown", "RSA", "DSA", |
46 "Unknown", | 45 "ECDSA", "DH", "ECDH"}; |
47 "RSA", | |
48 "DSA", | |
49 "ECDSA", | |
50 "DH", | |
51 "ECDH" | |
52 }; | |
53 // Histogram buckets for RSA/DSA/DH key sizes. | 46 // Histogram buckets for RSA/DSA/DH key sizes. |
54 const int kRsaDsaKeySizes[] = {512, 768, 1024, 1536, 2048, 3072, 4096, 8192, | 47 const int kRsaDsaKeySizes[] = {512, 768, 1024, 1536, 2048, |
55 16384}; | 48 3072, 4096, 8192, 16384}; |
56 // Histogram buckets for ECDSA/ECDH key sizes. The list is based upon the FIPS | 49 // Histogram buckets for ECDSA/ECDH key sizes. The list is based upon the FIPS |
57 // 186-4 approved curves. | 50 // 186-4 approved curves. |
58 const int kEccKeySizes[] = {163, 192, 224, 233, 256, 283, 384, 409, 521, 571}; | 51 const int kEccKeySizes[] = {163, 192, 224, 233, 256, 283, 384, 409, 521, 571}; |
59 | 52 |
60 const char* CertTypeToString(int cert_type) { | 53 const char* CertTypeToString(int cert_type) { |
61 if (cert_type < 0 || | 54 if (cert_type < 0 || |
62 static_cast<size_t>(cert_type) >= arraysize(kCertTypeStrings)) { | 55 static_cast<size_t>(cert_type) >= arraysize(kCertTypeStrings)) { |
63 return "Unsupported"; | 56 return "Unsupported"; |
64 } | 57 } |
65 return kCertTypeStrings[cert_type]; | 58 return kCertTypeStrings[cert_type]; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 123 |
131 size_t size_bits = 0; | 124 size_t size_bits = 0; |
132 X509Certificate::PublicKeyType type = X509Certificate::kPublicKeyTypeUnknown; | 125 X509Certificate::PublicKeyType type = X509Certificate::kPublicKeyTypeUnknown; |
133 bool weak_key = false; | 126 bool weak_key = false; |
134 bool baseline_keysize_applies = | 127 bool baseline_keysize_applies = |
135 cert->valid_start() >= kBaselineEffectiveDate && | 128 cert->valid_start() >= kBaselineEffectiveDate && |
136 cert->valid_expiry() >= kBaselineKeysizeEffectiveDate; | 129 cert->valid_expiry() >= kBaselineKeysizeEffectiveDate; |
137 | 130 |
138 X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &size_bits, &type); | 131 X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &size_bits, &type); |
139 if (should_histogram) { | 132 if (should_histogram) { |
140 RecordPublicKeyHistogram(kLeafCert, baseline_keysize_applies, size_bits, | 133 RecordPublicKeyHistogram( |
141 type); | 134 kLeafCert, baseline_keysize_applies, size_bits, type); |
142 } | 135 } |
143 if (IsWeakKey(type, size_bits)) | 136 if (IsWeakKey(type, size_bits)) |
144 weak_key = true; | 137 weak_key = true; |
145 | 138 |
146 const X509Certificate::OSCertHandles& intermediates = | 139 const X509Certificate::OSCertHandles& intermediates = |
147 cert->GetIntermediateCertificates(); | 140 cert->GetIntermediateCertificates(); |
148 for (size_t i = 0; i < intermediates.size(); ++i) { | 141 for (size_t i = 0; i < intermediates.size(); ++i) { |
149 X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type); | 142 X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type); |
150 if (should_histogram) { | 143 if (should_histogram) { |
151 RecordPublicKeyHistogram( | 144 RecordPublicKeyHistogram( |
(...skipping 21 matching lines...) Expand all Loading... |
173 return new CertVerifyProcAndroid(); | 166 return new CertVerifyProcAndroid(); |
174 #elif defined(OS_MACOSX) | 167 #elif defined(OS_MACOSX) |
175 return new CertVerifyProcMac(); | 168 return new CertVerifyProcMac(); |
176 #elif defined(OS_WIN) | 169 #elif defined(OS_WIN) |
177 return new CertVerifyProcWin(); | 170 return new CertVerifyProcWin(); |
178 #else | 171 #else |
179 return NULL; | 172 return NULL; |
180 #endif | 173 #endif |
181 } | 174 } |
182 | 175 |
183 CertVerifyProc::CertVerifyProc() {} | 176 CertVerifyProc::CertVerifyProc() { |
| 177 } |
184 | 178 |
185 CertVerifyProc::~CertVerifyProc() {} | 179 CertVerifyProc::~CertVerifyProc() { |
| 180 } |
186 | 181 |
187 int CertVerifyProc::Verify(X509Certificate* cert, | 182 int CertVerifyProc::Verify(X509Certificate* cert, |
188 const std::string& hostname, | 183 const std::string& hostname, |
189 int flags, | 184 int flags, |
190 CRLSet* crl_set, | 185 CRLSet* crl_set, |
191 const CertificateList& additional_trust_anchors, | 186 const CertificateList& additional_trust_anchors, |
192 CertVerifyResult* verify_result) { | 187 CertVerifyResult* verify_result) { |
193 verify_result->Reset(); | 188 verify_result->Reset(); |
194 verify_result->verified_cert = cert; | 189 verify_result->verified_cert = cert; |
195 | 190 |
196 if (IsBlacklisted(cert)) { | 191 if (IsBlacklisted(cert)) { |
197 verify_result->cert_status |= CERT_STATUS_REVOKED; | 192 verify_result->cert_status |= CERT_STATUS_REVOKED; |
198 return ERR_CERT_REVOKED; | 193 return ERR_CERT_REVOKED; |
199 } | 194 } |
200 | 195 |
201 // We do online revocation checking for EV certificates that aren't covered | 196 // We do online revocation checking for EV certificates that aren't covered |
202 // by a fresh CRLSet. | 197 // by a fresh CRLSet. |
203 // TODO(rsleevi): http://crbug.com/142974 - Allow preferences to fully | 198 // TODO(rsleevi): http://crbug.com/142974 - Allow preferences to fully |
204 // disable revocation checking. | 199 // disable revocation checking. |
205 if (flags & CertVerifier::VERIFY_EV_CERT) | 200 if (flags & CertVerifier::VERIFY_EV_CERT) |
206 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY; | 201 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY; |
207 | 202 |
208 int rv = VerifyInternal(cert, hostname, flags, crl_set, | 203 int rv = VerifyInternal( |
209 additional_trust_anchors, verify_result); | 204 cert, hostname, flags, crl_set, additional_trust_anchors, verify_result); |
210 | 205 |
211 UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallback", | 206 UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallback", |
212 verify_result->common_name_fallback_used); | 207 verify_result->common_name_fallback_used); |
213 if (!verify_result->is_issued_by_known_root) { | 208 if (!verify_result->is_issued_by_known_root) { |
214 UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallbackPrivateCA", | 209 UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallbackPrivateCA", |
215 verify_result->common_name_fallback_used); | 210 verify_result->common_name_fallback_used); |
216 } | 211 } |
217 | 212 |
218 // This check is done after VerifyInternal so that VerifyInternal can fill | 213 // This check is done after VerifyInternal so that VerifyInternal can fill |
219 // in the list of public key hashes. | 214 // in the list of public key hashes. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 // now treat it as a warning and do not map it to an error return value. | 267 // now treat it as a warning and do not map it to an error return value. |
273 } | 268 } |
274 | 269 |
275 return rv; | 270 return rv; |
276 } | 271 } |
277 | 272 |
278 // static | 273 // static |
279 bool CertVerifyProc::IsBlacklisted(X509Certificate* cert) { | 274 bool CertVerifyProc::IsBlacklisted(X509Certificate* cert) { |
280 static const unsigned kComodoSerialBytes = 16; | 275 static const unsigned kComodoSerialBytes = 16; |
281 static const uint8 kComodoSerials[][kComodoSerialBytes] = { | 276 static const uint8 kComodoSerials[][kComodoSerialBytes] = { |
282 // Not a real certificate. For testing only. | 277 // Not a real certificate. For testing only. |
283 {0x07,0x7a,0x59,0xbc,0xd5,0x34,0x59,0x60,0x1c,0xa6,0x90,0x72,0x67,0xa6,0xdd,
0x1c}, | 278 {0x07, 0x7a, 0x59, 0xbc, 0xd5, 0x34, 0x59, 0x60, 0x1c, 0xa6, 0x90, 0x72, |
| 279 0x67, 0xa6, 0xdd, 0x1c}, |
284 | 280 |
285 // The next nine certificates all expire on Fri Mar 14 23:59:59 2014. | 281 // The next nine certificates all expire on Fri Mar 14 23:59:59 2014. |
286 // Some serial numbers actually have a leading 0x00 byte required to | 282 // Some serial numbers actually have a leading 0x00 byte required to |
287 // encode a positive integer in DER if the most significant bit is 0. | 283 // encode a positive integer in DER if the most significant bit is 0. |
288 // We omit the leading 0x00 bytes to make all serial numbers 16 bytes. | 284 // We omit the leading 0x00 bytes to make all serial numbers 16 bytes. |
289 | 285 |
290 // Subject: CN=mail.google.com | 286 // Subject: CN=mail.google.com |
291 // subjectAltName dNSName: mail.google.com, www.mail.google.com | 287 // subjectAltName dNSName: mail.google.com, www.mail.google.com |
292 {0x04,0x7e,0xcb,0xe9,0xfc,0xa5,0x5f,0x7b,0xd0,0x9e,0xae,0x36,0xe1,0x0c,0xae,
0x1e}, | 288 {0x04, 0x7e, 0xcb, 0xe9, 0xfc, 0xa5, 0x5f, 0x7b, 0xd0, 0x9e, 0xae, 0x36, |
293 // Subject: CN=global trustee | 289 0xe1, 0x0c, 0xae, 0x1e}, |
294 // subjectAltName dNSName: global trustee | 290 // Subject: CN=global trustee |
295 // Note: not a CA certificate. | 291 // subjectAltName dNSName: global trustee |
296 {0xd8,0xf3,0x5f,0x4e,0xb7,0x87,0x2b,0x2d,0xab,0x06,0x92,0xe3,0x15,0x38,0x2f,
0xb0}, | 292 // Note: not a CA certificate. |
297 // Subject: CN=login.live.com | 293 {0xd8, 0xf3, 0x5f, 0x4e, 0xb7, 0x87, 0x2b, 0x2d, 0xab, 0x06, 0x92, 0xe3, |
298 // subjectAltName dNSName: login.live.com, www.login.live.com | 294 0x15, 0x38, 0x2f, 0xb0}, |
299 {0xb0,0xb7,0x13,0x3e,0xd0,0x96,0xf9,0xb5,0x6f,0xae,0x91,0xc8,0x74,0xbd,0x3a,
0xc0}, | 295 // Subject: CN=login.live.com |
300 // Subject: CN=addons.mozilla.org | 296 // subjectAltName dNSName: login.live.com, www.login.live.com |
301 // subjectAltName dNSName: addons.mozilla.org, www.addons.mozilla.org | 297 {0xb0, 0xb7, 0x13, 0x3e, 0xd0, 0x96, 0xf9, 0xb5, 0x6f, 0xae, 0x91, 0xc8, |
302 {0x92,0x39,0xd5,0x34,0x8f,0x40,0xd1,0x69,0x5a,0x74,0x54,0x70,0xe1,0xf2,0x3f,
0x43}, | 298 0x74, 0xbd, 0x3a, 0xc0}, |
303 // Subject: CN=login.skype.com | 299 // Subject: CN=addons.mozilla.org |
304 // subjectAltName dNSName: login.skype.com, www.login.skype.com | 300 // subjectAltName dNSName: addons.mozilla.org, www.addons.mozilla.org |
305 {0xe9,0x02,0x8b,0x95,0x78,0xe4,0x15,0xdc,0x1a,0x71,0x0a,0x2b,0x88,0x15,0x44,
0x47}, | 301 {0x92, 0x39, 0xd5, 0x34, 0x8f, 0x40, 0xd1, 0x69, 0x5a, 0x74, 0x54, 0x70, |
306 // Subject: CN=login.yahoo.com | 302 0xe1, 0xf2, 0x3f, 0x43}, |
307 // subjectAltName dNSName: login.yahoo.com, www.login.yahoo.com | 303 // Subject: CN=login.skype.com |
308 {0xd7,0x55,0x8f,0xda,0xf5,0xf1,0x10,0x5b,0xb2,0x13,0x28,0x2b,0x70,0x77,0x29,
0xa3}, | 304 // subjectAltName dNSName: login.skype.com, www.login.skype.com |
309 // Subject: CN=www.google.com | 305 {0xe9, 0x02, 0x8b, 0x95, 0x78, 0xe4, 0x15, 0xdc, 0x1a, 0x71, 0x0a, 0x2b, |
310 // subjectAltName dNSName: www.google.com, google.com | 306 0x88, 0x15, 0x44, 0x47}, |
311 {0xf5,0xc8,0x6a,0xf3,0x61,0x62,0xf1,0x3a,0x64,0xf5,0x4f,0x6d,0xc9,0x58,0x7c,
0x06}, | 307 // Subject: CN=login.yahoo.com |
312 // Subject: CN=login.yahoo.com | 308 // subjectAltName dNSName: login.yahoo.com, www.login.yahoo.com |
313 // subjectAltName dNSName: login.yahoo.com | 309 {0xd7, 0x55, 0x8f, 0xda, 0xf5, 0xf1, 0x10, 0x5b, 0xb2, 0x13, 0x28, 0x2b, |
314 {0x39,0x2a,0x43,0x4f,0x0e,0x07,0xdf,0x1f,0x8a,0xa3,0x05,0xde,0x34,0xe0,0xc2,
0x29}, | 310 0x70, 0x77, 0x29, 0xa3}, |
315 // Subject: CN=login.yahoo.com | 311 // Subject: CN=www.google.com |
316 // subjectAltName dNSName: login.yahoo.com | 312 // subjectAltName dNSName: www.google.com, google.com |
317 {0x3e,0x75,0xce,0xd4,0x6b,0x69,0x30,0x21,0x21,0x88,0x30,0xae,0x86,0xa8,0x2a,
0x71}, | 313 {0xf5, 0xc8, 0x6a, 0xf3, 0x61, 0x62, 0xf1, 0x3a, 0x64, 0xf5, 0x4f, 0x6d, |
| 314 0xc9, 0x58, 0x7c, 0x06}, |
| 315 // Subject: CN=login.yahoo.com |
| 316 // subjectAltName dNSName: login.yahoo.com |
| 317 {0x39, 0x2a, 0x43, 0x4f, 0x0e, 0x07, 0xdf, 0x1f, 0x8a, 0xa3, 0x05, 0xde, |
| 318 0x34, 0xe0, 0xc2, 0x29}, |
| 319 // Subject: CN=login.yahoo.com |
| 320 // subjectAltName dNSName: login.yahoo.com |
| 321 {0x3e, 0x75, 0xce, 0xd4, 0x6b, 0x69, 0x30, 0x21, 0x21, 0x88, 0x30, 0xae, |
| 322 0x86, 0xa8, 0x2a, 0x71}, |
318 }; | 323 }; |
319 | 324 |
320 const std::string& serial_number = cert->serial_number(); | 325 const std::string& serial_number = cert->serial_number(); |
321 if (!serial_number.empty() && (serial_number[0] & 0x80) != 0) { | 326 if (!serial_number.empty() && (serial_number[0] & 0x80) != 0) { |
322 // This is a negative serial number, which isn't technically allowed but | 327 // This is a negative serial number, which isn't technically allowed but |
323 // which probably happens. In order to avoid confusing a negative serial | 328 // which probably happens. In order to avoid confusing a negative serial |
324 // number with a positive one once the leading zeros have been removed, we | 329 // number with a positive one once the leading zeros have been removed, we |
325 // disregard it. | 330 // disregard it. |
326 return false; | 331 return false; |
327 } | 332 } |
328 | 333 |
329 base::StringPiece serial(serial_number); | 334 base::StringPiece serial(serial_number); |
330 // Remove leading zeros. | 335 // Remove leading zeros. |
331 while (serial.size() > 1 && serial[0] == 0) | 336 while (serial.size() > 1 && serial[0] == 0) |
332 serial.remove_prefix(1); | 337 serial.remove_prefix(1); |
333 | 338 |
334 if (serial.size() == kComodoSerialBytes) { | 339 if (serial.size() == kComodoSerialBytes) { |
335 for (unsigned i = 0; i < arraysize(kComodoSerials); i++) { | 340 for (unsigned i = 0; i < arraysize(kComodoSerials); i++) { |
336 if (memcmp(kComodoSerials[i], serial.data(), kComodoSerialBytes) == 0) { | 341 if (memcmp(kComodoSerials[i], serial.data(), kComodoSerialBytes) == 0) { |
337 UMA_HISTOGRAM_ENUMERATION("Net.SSLCertBlacklisted", i, | 342 UMA_HISTOGRAM_ENUMERATION( |
338 arraysize(kComodoSerials) + 1); | 343 "Net.SSLCertBlacklisted", i, arraysize(kComodoSerials) + 1); |
339 return true; | 344 return true; |
340 } | 345 } |
341 } | 346 } |
342 } | 347 } |
343 | 348 |
344 return false; | 349 return false; |
345 } | 350 } |
346 | 351 |
347 // static | 352 // static |
348 // NOTE: This implementation assumes and enforces that the hashes are SHA1. | 353 // NOTE: This implementation assumes and enforces that the hashes are SHA1. |
349 bool CertVerifyProc::IsPublicKeyBlacklisted( | 354 bool CertVerifyProc::IsPublicKeyBlacklisted( |
350 const HashValueVector& public_key_hashes) { | 355 const HashValueVector& public_key_hashes) { |
351 static const unsigned kNumHashes = 14; | 356 static const unsigned kNumHashes = 14; |
352 static const uint8 kHashes[kNumHashes][base::kSHA1Length] = { | 357 static const uint8 kHashes[kNumHashes][base::kSHA1Length] = { |
353 // Subject: CN=DigiNotar Root CA | 358 // Subject: CN=DigiNotar Root CA |
354 // Issuer: CN=Entrust.net x2 and self-signed | 359 // Issuer: CN=Entrust.net x2 and self-signed |
355 {0x41, 0x0f, 0x36, 0x36, 0x32, 0x58, 0xf3, 0x0b, 0x34, 0x7d, | 360 {0x41, 0x0f, 0x36, 0x36, 0x32, 0x58, 0xf3, 0x0b, 0x34, 0x7d, 0x12, 0xce, |
356 0x12, 0xce, 0x48, 0x63, 0xe4, 0x33, 0x43, 0x78, 0x06, 0xa8}, | 361 0x48, 0x63, 0xe4, 0x33, 0x43, 0x78, 0x06, 0xa8}, |
357 // Subject: CN=DigiNotar Cyber CA | 362 // Subject: CN=DigiNotar Cyber CA |
358 // Issuer: CN=GTE CyberTrust Global Root | 363 // Issuer: CN=GTE CyberTrust Global Root |
359 {0xc4, 0xf9, 0x66, 0x37, 0x16, 0xcd, 0x5e, 0x71, 0xd6, 0x95, | 364 {0xc4, 0xf9, 0x66, 0x37, 0x16, 0xcd, 0x5e, 0x71, 0xd6, 0x95, 0x0b, 0x5f, |
360 0x0b, 0x5f, 0x33, 0xce, 0x04, 0x1c, 0x95, 0xb4, 0x35, 0xd1}, | 365 0x33, 0xce, 0x04, 0x1c, 0x95, 0xb4, 0x35, 0xd1}, |
361 // Subject: CN=DigiNotar Services 1024 CA | 366 // Subject: CN=DigiNotar Services 1024 CA |
362 // Issuer: CN=Entrust.net | 367 // Issuer: CN=Entrust.net |
363 {0xe2, 0x3b, 0x8d, 0x10, 0x5f, 0x87, 0x71, 0x0a, 0x68, 0xd9, | 368 {0xe2, 0x3b, 0x8d, 0x10, 0x5f, 0x87, 0x71, 0x0a, 0x68, 0xd9, 0x24, 0x80, |
364 0x24, 0x80, 0x50, 0xeb, 0xef, 0xc6, 0x27, 0xbe, 0x4c, 0xa6}, | 369 0x50, 0xeb, 0xef, 0xc6, 0x27, 0xbe, 0x4c, 0xa6}, |
365 // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2 | 370 // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2 |
366 // Issuer: CN=Staat der Nederlanden Organisatie CA - G2 | 371 // Issuer: CN=Staat der Nederlanden Organisatie CA - G2 |
367 {0x7b, 0x2e, 0x16, 0xbc, 0x39, 0xbc, 0xd7, 0x2b, 0x45, 0x6e, | 372 {0x7b, 0x2e, 0x16, 0xbc, 0x39, 0xbc, 0xd7, 0x2b, 0x45, 0x6e, 0x9f, 0x05, |
368 0x9f, 0x05, 0x5d, 0x1d, 0xe6, 0x15, 0xb7, 0x49, 0x45, 0xdb}, | 373 0x5d, 0x1d, 0xe6, 0x15, 0xb7, 0x49, 0x45, 0xdb}, |
369 // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven | 374 // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven |
370 // Issuer: CN=Staat der Nederlanden Overheid CA | 375 // Issuer: CN=Staat der Nederlanden Overheid CA |
371 {0xe8, 0xf9, 0x12, 0x00, 0xc6, 0x5c, 0xee, 0x16, 0xe0, 0x39, | 376 {0xe8, 0xf9, 0x12, 0x00, 0xc6, 0x5c, 0xee, 0x16, 0xe0, 0x39, 0xb9, 0xf8, |
372 0xb9, 0xf8, 0x83, 0x84, 0x16, 0x61, 0x63, 0x5f, 0x81, 0xc5}, | 377 0x83, 0x84, 0x16, 0x61, 0x63, 0x5f, 0x81, 0xc5}, |
373 // Subject: O=Digicert Sdn. Bhd. | 378 // Subject: O=Digicert Sdn. Bhd. |
374 // Issuer: CN=GTE CyberTrust Global Root | 379 // Issuer: CN=GTE CyberTrust Global Root |
375 // Expires: Jul 17 15:16:54 2012 GMT | 380 // Expires: Jul 17 15:16:54 2012 GMT |
376 {0x01, 0x29, 0xbc, 0xd5, 0xb4, 0x48, 0xae, 0x8d, 0x24, 0x96, | 381 {0x01, 0x29, 0xbc, 0xd5, 0xb4, 0x48, 0xae, 0x8d, 0x24, 0x96, 0xd1, 0xc3, |
377 0xd1, 0xc3, 0xe1, 0x97, 0x23, 0x91, 0x90, 0x88, 0xe1, 0x52}, | 382 0xe1, 0x97, 0x23, 0x91, 0x90, 0x88, 0xe1, 0x52}, |
378 // Subject: O=Digicert Sdn. Bhd. | 383 // Subject: O=Digicert Sdn. Bhd. |
379 // Issuer: CN=Entrust.net Certification Authority (2048) | 384 // Issuer: CN=Entrust.net Certification Authority (2048) |
380 // Expires: Jul 16 17:53:37 2015 GMT | 385 // Expires: Jul 16 17:53:37 2015 GMT |
381 {0xd3, 0x3c, 0x5b, 0x41, 0xe4, 0x5c, 0xc4, 0xb3, 0xbe, 0x9a, | 386 {0xd3, 0x3c, 0x5b, 0x41, 0xe4, 0x5c, 0xc4, 0xb3, 0xbe, 0x9a, 0xd6, 0x95, |
382 0xd6, 0x95, 0x2c, 0x4e, 0xcc, 0x25, 0x28, 0x03, 0x29, 0x81}, | 387 0x2c, 0x4e, 0xcc, 0x25, 0x28, 0x03, 0x29, 0x81}, |
383 // Issuer: CN=Trustwave Organization Issuing CA, Level 2 | 388 // Issuer: CN=Trustwave Organization Issuing CA, Level 2 |
384 // Covers two certificates, the latter of which expires Apr 15 21:09:30 | 389 // Covers two certificates, the latter of which expires Apr 15 21:09:30 |
385 // 2021 GMT. | 390 // 2021 GMT. |
386 {0xe1, 0x2d, 0x89, 0xf5, 0x6d, 0x22, 0x76, 0xf8, 0x30, 0xe6, | 391 {0xe1, 0x2d, 0x89, 0xf5, 0x6d, 0x22, 0x76, 0xf8, 0x30, 0xe6, 0xce, 0xaf, |
387 0xce, 0xaf, 0xa6, 0x6c, 0x72, 0x5c, 0x0b, 0x41, 0xa9, 0x32}, | 392 0xa6, 0x6c, 0x72, 0x5c, 0x0b, 0x41, 0xa9, 0x32}, |
388 // Cyberoam CA certificate. Private key leaked, but this certificate would | 393 // Cyberoam CA certificate. Private key leaked, but this certificate would |
389 // only have been installed by Cyberoam customers. The certificate expires | 394 // only have been installed by Cyberoam customers. The certificate expires |
390 // in 2036, but we can probably remove in a couple of years (2014). | 395 // in 2036, but we can probably remove in a couple of years (2014). |
391 {0xd9, 0xf5, 0xc6, 0xce, 0x57, 0xff, 0xaa, 0x39, 0xcc, 0x7e, | 396 {0xd9, 0xf5, 0xc6, 0xce, 0x57, 0xff, 0xaa, 0x39, 0xcc, 0x7e, 0xd1, 0x72, |
392 0xd1, 0x72, 0xbd, 0x53, 0xe0, 0xd3, 0x07, 0x83, 0x4b, 0xd1}, | 397 0xbd, 0x53, 0xe0, 0xd3, 0x07, 0x83, 0x4b, 0xd1}, |
393 // Win32/Sirefef.gen!C generates fake certificates with this public key. | 398 // Win32/Sirefef.gen!C generates fake certificates with this public key. |
394 {0xa4, 0xf5, 0x6e, 0x9e, 0x1d, 0x9a, 0x3b, 0x7b, 0x1a, 0xc3, | 399 {0xa4, 0xf5, 0x6e, 0x9e, 0x1d, 0x9a, 0x3b, 0x7b, 0x1a, 0xc3, 0x31, 0xcf, |
395 0x31, 0xcf, 0x64, 0xfc, 0x76, 0x2c, 0xd0, 0x51, 0xfb, 0xa4}, | 400 0x64, 0xfc, 0x76, 0x2c, 0xd0, 0x51, 0xfb, 0xa4}, |
396 // ANSSI certificate under which a MITM proxy was mistakenly operated. | 401 // ANSSI certificate under which a MITM proxy was mistakenly operated. |
397 // Expires: Jul 18 10:05:28 2014 GMT | 402 // Expires: Jul 18 10:05:28 2014 GMT |
398 {0x3e, 0xcf, 0x4b, 0xbb, 0xe4, 0x60, 0x96, 0xd5, 0x14, 0xbb, | 403 {0x3e, 0xcf, 0x4b, 0xbb, 0xe4, 0x60, 0x96, 0xd5, 0x14, 0xbb, 0x53, 0x9b, |
399 0x53, 0x9b, 0xb9, 0x13, 0xd7, 0x7a, 0xa4, 0xef, 0x31, 0xbf}, | 404 0xb9, 0x13, 0xd7, 0x7a, 0xa4, 0xef, 0x31, 0xbf}, |
400 // Three retired intermediate certificates from Symantec. No compromise; | 405 // Three retired intermediate certificates from Symantec. No compromise; |
401 // just for robustness. All expire May 17 23:59:59 2018. | 406 // just for robustness. All expire May 17 23:59:59 2018. |
402 // See https://bugzilla.mozilla.org/show_bug.cgi?id=966060 | 407 // See https://bugzilla.mozilla.org/show_bug.cgi?id=966060 |
403 {0x68, 0x5e, 0xec, 0x0a, 0x39, 0xf6, 0x68, 0xae, 0x8f, 0xd8, | 408 {0x68, 0x5e, 0xec, 0x0a, 0x39, 0xf6, 0x68, 0xae, 0x8f, 0xd8, 0x96, 0x4f, |
404 0x96, 0x4f, 0x98, 0x74, 0x76, 0xb4, 0x50, 0x4f, 0xd2, 0xbe}, | 409 0x98, 0x74, 0x76, 0xb4, 0x50, 0x4f, 0xd2, 0xbe}, |
405 {0x0e, 0x50, 0x2d, 0x4d, 0xd1, 0xe1, 0x60, 0x36, 0x8a, 0x31, | 410 {0x0e, 0x50, 0x2d, 0x4d, 0xd1, 0xe1, 0x60, 0x36, 0x8a, 0x31, 0xf0, 0x6a, |
406 0xf0, 0x6a, 0x81, 0x04, 0x31, 0xba, 0x6f, 0x72, 0xc0, 0x41}, | 411 0x81, 0x04, 0x31, 0xba, 0x6f, 0x72, 0xc0, 0x41}, |
407 {0x93, 0xd1, 0x53, 0x22, 0x29, 0xcc, 0x2a, 0xbd, 0x21, 0xdf, | 412 {0x93, 0xd1, 0x53, 0x22, 0x29, 0xcc, 0x2a, 0xbd, 0x21, 0xdf, 0xf5, 0x97, |
408 0xf5, 0x97, 0xee, 0x32, 0x0f, 0xe4, 0x24, 0x6f, 0x3d, 0x0c}, | 413 0xee, 0x32, 0x0f, 0xe4, 0x24, 0x6f, 0x3d, 0x0c}, |
409 }; | 414 }; |
410 | 415 |
411 for (unsigned i = 0; i < kNumHashes; i++) { | 416 for (unsigned i = 0; i < kNumHashes; i++) { |
412 for (HashValueVector::const_iterator j = public_key_hashes.begin(); | 417 for (HashValueVector::const_iterator j = public_key_hashes.begin(); |
413 j != public_key_hashes.end(); ++j) { | 418 j != public_key_hashes.end(); |
| 419 ++j) { |
414 if (j->tag == HASH_VALUE_SHA1 && | 420 if (j->tag == HASH_VALUE_SHA1 && |
415 memcmp(j->data(), kHashes[i], base::kSHA1Length) == 0) { | 421 memcmp(j->data(), kHashes[i], base::kSHA1Length) == 0) { |
416 return true; | 422 return true; |
417 } | 423 } |
418 } | 424 } |
419 } | 425 } |
420 | 426 |
421 return false; | 427 return false; |
422 } | 428 } |
423 | 429 |
424 static const size_t kMaxTLDLength = 4; | 430 static const size_t kMaxTLDLength = 4; |
425 | 431 |
426 // CheckNameConstraints verifies that every name in |dns_names| is in one of | 432 // CheckNameConstraints verifies that every name in |dns_names| is in one of |
427 // the domains specified by |tlds|. The |tlds| array is terminated by an empty | 433 // the domains specified by |tlds|. The |tlds| array is terminated by an empty |
428 // string. | 434 // string. |
429 static bool CheckNameConstraints(const std::vector<std::string>& dns_names, | 435 static bool CheckNameConstraints(const std::vector<std::string>& dns_names, |
430 const char tlds[][kMaxTLDLength]) { | 436 const char tlds[][kMaxTLDLength]) { |
431 for (std::vector<std::string>::const_iterator i = dns_names.begin(); | 437 for (std::vector<std::string>::const_iterator i = dns_names.begin(); |
432 i != dns_names.end(); ++i) { | 438 i != dns_names.end(); |
| 439 ++i) { |
433 bool ok = false; | 440 bool ok = false; |
434 url::CanonHostInfo host_info; | 441 url::CanonHostInfo host_info; |
435 const std::string dns_name = CanonicalizeHost(*i, &host_info); | 442 const std::string dns_name = CanonicalizeHost(*i, &host_info); |
436 if (host_info.IsIPAddress()) | 443 if (host_info.IsIPAddress()) |
437 continue; | 444 continue; |
438 | 445 |
439 const size_t registry_len = registry_controlled_domains::GetRegistryLength( | 446 const size_t registry_len = registry_controlled_domains::GetRegistryLength( |
440 dns_name, | 447 dns_name, |
441 registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | 448 registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
442 registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); | 449 registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 const char (*tlds)[kMaxTLDLength]; | 482 const char (*tlds)[kMaxTLDLength]; |
476 }; | 483 }; |
477 | 484 |
478 // static | 485 // static |
479 bool CertVerifyProc::HasNameConstraintsViolation( | 486 bool CertVerifyProc::HasNameConstraintsViolation( |
480 const HashValueVector& public_key_hashes, | 487 const HashValueVector& public_key_hashes, |
481 const std::string& common_name, | 488 const std::string& common_name, |
482 const std::vector<std::string>& dns_names, | 489 const std::vector<std::string>& dns_names, |
483 const std::vector<std::string>& ip_addrs) { | 490 const std::vector<std::string>& ip_addrs) { |
484 static const char kTLDsANSSI[][kMaxTLDLength] = { | 491 static const char kTLDsANSSI[][kMaxTLDLength] = { |
485 "fr", // France | 492 "fr", // France |
486 "gp", // Guadeloupe | 493 "gp", // Guadeloupe |
487 "gf", // Guyane | 494 "gf", // Guyane |
488 "mq", // Martinique | 495 "mq", // Martinique |
489 "re", // Réunion | 496 "re", // Réunion |
490 "yt", // Mayotte | 497 "yt", // Mayotte |
491 "pm", // Saint-Pierre et Miquelon | 498 "pm", // Saint-Pierre et Miquelon |
492 "bl", // Saint Barthélemy | 499 "bl", // Saint Barthélemy |
493 "mf", // Saint Martin | 500 "mf", // Saint Martin |
494 "wf", // Wallis et Futuna | 501 "wf", // Wallis et Futuna |
495 "pf", // Polynésie française | 502 "pf", // Polynésie française |
496 "nc", // Nouvelle Calédonie | 503 "nc", // Nouvelle Calédonie |
497 "tf", // Terres australes et antarctiques françaises | 504 "tf", // Terres australes et antarctiques françaises |
498 "", | 505 "", |
499 }; | 506 }; |
500 | 507 |
501 static const char kTLDsTest[][kMaxTLDLength] = { | 508 static const char kTLDsTest[][kMaxTLDLength] = { |
502 "com", | 509 "com", "", |
503 "", | |
504 }; | 510 }; |
505 | 511 |
506 static const PublicKeyTLDLimitation kLimits[] = { | 512 static const PublicKeyTLDLimitation kLimits[] = { |
507 // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI, | 513 // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI, |
508 // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr | 514 // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr |
509 { | 515 { |
510 {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad, | 516 {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad, 0xae, 0x27, |
511 0xae, 0x27, 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73}, | 517 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73}, |
512 kTLDsANSSI, | 518 kTLDsANSSI, |
513 }, | 519 }, |
514 // Not a real certificate - just for testing. This is the SPKI hash of | 520 // Not a real certificate - just for testing. This is the SPKI hash of |
515 // the keys used in net/data/ssl/certificates/name_constraint_*.crt. | 521 // the keys used in net/data/ssl/certificates/name_constraint_*.crt. |
516 { | 522 { |
517 {0x15, 0x45, 0xd7, 0x3b, 0x58, 0x6b, 0x47, 0xcf, 0xc1, 0x44, | 523 {0x15, 0x45, 0xd7, 0x3b, 0x58, 0x6b, 0x47, 0xcf, 0xc1, 0x44, 0xa2, 0xc9, |
518 0xa2, 0xc9, 0xaa, 0xab, 0x98, 0x3d, 0x21, 0xcc, 0x42, 0xde}, | 524 0xaa, 0xab, 0x98, 0x3d, 0x21, 0xcc, 0x42, 0xde}, |
519 kTLDsTest, | 525 kTLDsTest, |
520 }, | 526 }, |
521 }; | 527 }; |
522 | 528 |
523 for (unsigned i = 0; i < arraysize(kLimits); ++i) { | 529 for (unsigned i = 0; i < arraysize(kLimits); ++i) { |
524 for (HashValueVector::const_iterator j = public_key_hashes.begin(); | 530 for (HashValueVector::const_iterator j = public_key_hashes.begin(); |
525 j != public_key_hashes.end(); ++j) { | 531 j != public_key_hashes.end(); |
| 532 ++j) { |
526 if (j->tag == HASH_VALUE_SHA1 && | 533 if (j->tag == HASH_VALUE_SHA1 && |
527 memcmp(j->data(), kLimits[i].public_key, base::kSHA1Length) == 0) { | 534 memcmp(j->data(), kLimits[i].public_key, base::kSHA1Length) == 0) { |
528 if (dns_names.empty() && ip_addrs.empty()) { | 535 if (dns_names.empty() && ip_addrs.empty()) { |
529 std::vector<std::string> dns_names; | 536 std::vector<std::string> dns_names; |
530 dns_names.push_back(common_name); | 537 dns_names.push_back(common_name); |
531 if (!CheckNameConstraints(dns_names, kLimits[i].tlds)) | 538 if (!CheckNameConstraints(dns_names, kLimits[i].tlds)) |
532 return true; | 539 return true; |
533 } else { | 540 } else { |
534 if (!CheckNameConstraints(dns_names, kLimits[i].tlds)) | 541 if (!CheckNameConstraints(dns_names, kLimits[i].tlds)) |
535 return true; | 542 return true; |
536 } | 543 } |
537 } | 544 } |
538 } | 545 } |
539 } | 546 } |
540 | 547 |
541 return false; | 548 return false; |
542 } | 549 } |
543 | 550 |
544 } // namespace net | 551 } // namespace net |
OLD | NEW |