| 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 |