15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sha1.h" 92385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/strings/stringprintf.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/net_util.h" 13d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_status_flags.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verifier.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_result.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/crl_set.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h" 19d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "url/url_canon.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_NSS) || defined(OS_IOS) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc_nss.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(USE_OPENSSL) && !defined(OS_ANDROID) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc_openssl.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_ANDROID) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc_android.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc_mac.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_verify_proc_win.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error Implement certificate verification. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Constants used to build histogram names 412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kLeafCert[] = "Leaf"; 422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kIntermediateCert[] = "Intermediate"; 432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kRootCert[] = "Root"; 442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Matches the order of X509Certificate::PublicKeyType 452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char* const kCertTypeStrings[] = { 462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "Unknown", 472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "RSA", 482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "DSA", 492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "ECDSA", 502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "DH", 512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "ECDH" 522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}; 532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Histogram buckets for RSA/DSA/DH key sizes. 542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst int kRsaDsaKeySizes[] = {512, 768, 1024, 1536, 2048, 3072, 4096, 8192, 552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 16384}; 562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Histogram buckets for ECDSA/ECDH key sizes. The list is based upon the FIPS 572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// 186-4 approved curves. 582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst int kEccKeySizes[] = {163, 192, 224, 233, 256, 283, 384, 409, 521, 571}; 592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char* CertTypeToString(int cert_type) { 612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (cert_type < 0 || 622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch static_cast<size_t>(cert_type) >= arraysize(kCertTypeStrings)) { 632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return "Unsupported"; 642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return kCertTypeStrings[cert_type]; 662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid RecordPublicKeyHistogram(const char* chain_position, 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool baseline_keysize_applies, 702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch size_t size_bits, 712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch X509Certificate::PublicKeyType cert_type) { 722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch std::string histogram_name = 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::StringPrintf("CertificateType2.%s.%s.%s", 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch baseline_keysize_applies ? "BR" : "NonBR", 752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch chain_position, 762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch CertTypeToString(cert_type)); 772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Do not use UMA_HISTOGRAM_... macros here, as it caches the Histogram 782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // instance and thus only works if |histogram_name| is constant. 792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::HistogramBase* counter = NULL; 802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Histogram buckets are contingent upon the underlying algorithm being used. 822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (cert_type == X509Certificate::kPublicKeyTypeECDH || 832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch cert_type == X509Certificate::kPublicKeyTypeECDSA) { 842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Typical key sizes match SECP/FIPS 186-3 recommendations for prime and 852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // binary curves - which range from 163 bits to 571 bits. 862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch counter = base::CustomHistogram::FactoryGet( 872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch histogram_name, 882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::CustomHistogram::ArrayToCustomRanges(kEccKeySizes, 892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch arraysize(kEccKeySizes)), 902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::HistogramBase::kUmaTargetedHistogramFlag); 912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } else { 922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Key sizes < 1024 bits should cause errors, while key sizes > 16K are not 932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // uniformly supported by the underlying cryptographic libraries. 942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch counter = base::CustomHistogram::FactoryGet( 952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch histogram_name, 962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::CustomHistogram::ArrayToCustomRanges(kRsaDsaKeySizes, 972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch arraysize(kRsaDsaKeySizes)), 982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::HistogramBase::kUmaTargetedHistogramFlag); 992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch counter->Add(size_bits); 1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 1022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if |type| is |kPublicKeyTypeRSA| or |kPublicKeyTypeDSA|, and 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if |size_bits| is < 1024. Note that this means there may be false 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// negatives: keys for other algorithms and which are weak will pass this 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// test. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsWeakKey(X509Certificate::PublicKeyType type, size_t size_bits) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case X509Certificate::kPublicKeyTypeRSA: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case X509Certificate::kPublicKeyTypeDSA: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_bits < 1024; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Returns true if |cert| contains a known-weak key. Additionally, histograms 1182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// the observed keys for future tightening of the definition of what 1192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// constitutes a weak key. 1202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool ExaminePublicKeys(const scoped_refptr<X509Certificate>& cert, 1212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch bool should_histogram) { 1222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // The effective date of the CA/Browser Forum's Baseline Requirements - 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 2012-07-01 00:00:00 UTC. 1242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const base::Time kBaselineEffectiveDate = 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Time::FromInternalValue(GG_INT64_C(12985574400000000)); 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The effective date of the key size requirements from Appendix A, v1.1.5 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 2014-01-01 00:00:00 UTC. 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Time kBaselineKeysizeEffectiveDate = 1292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch base::Time::FromInternalValue(GG_INT64_C(13033008000000000)); 1302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch size_t size_bits = 0; 1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch X509Certificate::PublicKeyType type = X509Certificate::kPublicKeyTypeUnknown; 1332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch bool weak_key = false; 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool baseline_keysize_applies = 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch cert->valid_start() >= kBaselineEffectiveDate && 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch cert->valid_expiry() >= kBaselineKeysizeEffectiveDate; 1372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &size_bits, &type); 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (should_histogram) { 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RecordPublicKeyHistogram(kLeafCert, baseline_keysize_applies, size_bits, 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch type); 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (IsWeakKey(type, size_bits)) 1442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch weak_key = true; 1452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const X509Certificate::OSCertHandles& intermediates = 1472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch cert->GetIntermediateCertificates(); 1482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch for (size_t i = 0; i < intermediates.size(); ++i) { 1492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type); 1502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (should_histogram) { 1512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch RecordPublicKeyHistogram( 1522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch (i < intermediates.size() - 1) ? kIntermediateCert : kRootCert, 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch baseline_keysize_applies, 1542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch size_bits, 1552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch type); 1562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!weak_key && IsWeakKey(type, size_bits)) 1582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch weak_key = true; 1592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return weak_key; 1622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 1632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CertVerifyProc* CertVerifyProc::CreateDefault() { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_NSS) || defined(OS_IOS) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CertVerifyProcNSS(); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(USE_OPENSSL) && !defined(OS_ANDROID) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CertVerifyProcOpenSSL(); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_ANDROID) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new CertVerifyProcAndroid(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CertVerifyProcMac(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CertVerifyProcWin(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CertVerifyProc::CertVerifyProc() {} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CertVerifyProc::~CertVerifyProc() {} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CertVerifyProc::Verify(X509Certificate* cert, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& hostname, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CRLSet* crl_set, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CertificateList& additional_trust_anchors, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CertVerifyResult* verify_result) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->Reset(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->verified_cert = cert; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsBlacklisted(cert)) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->cert_status |= CERT_STATUS_REVOKED; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_CERT_REVOKED; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // We do online revocation checking for EV certificates that aren't covered 202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // by a fresh CRLSet. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rsleevi): http://crbug.com/142974 - Allow preferences to fully 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disable revocation checking. 205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (flags & CertVerifier::VERIFY_EV_CERT) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv = VerifyInternal(cert, hostname, flags, crl_set, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) additional_trust_anchors, verify_result); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallback", 2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) verify_result->common_name_fallback_used); 2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!verify_result->is_issued_by_known_root) { 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallbackPrivateCA", 2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) verify_result->common_name_fallback_used); 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This check is done after VerifyInternal so that VerifyInternal can fill 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the list of public key hashes. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPublicKeyBlacklisted(verify_result->public_key_hashes)) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->cert_status |= CERT_STATUS_REVOKED; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = MapCertStatusToNetError(verify_result->cert_status); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) std::vector<std::string> dns_names, ip_addrs; 226d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) cert->GetSubjectAltName(&dns_names, &ip_addrs); 227d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (HasNameConstraintsViolation(verify_result->public_key_hashes, 228d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) cert->subject().common_name, 229d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) dns_names, 230d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) ip_addrs)) { 231d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) verify_result->cert_status |= CERT_STATUS_NAME_CONSTRAINT_VIOLATION; 232d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) rv = MapCertStatusToNetError(verify_result->cert_status); 233d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 234d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for weak keys in the entire verified chain. 2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch bool weak_key = ExaminePublicKeys(verify_result->verified_cert, 2372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch verify_result->is_issued_by_known_root); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (weak_key) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->cert_status |= CERT_STATUS_WEAK_KEY; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Avoid replacing a more serious error, such as an OS/library failure, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by ensuring that if verification failed, it failed with a certificate 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == OK || IsCertificateError(rv)) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = MapCertStatusToNetError(verify_result->cert_status); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Treat certificates signed using broken signature algorithms as invalid. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (verify_result->has_md2 || verify_result->has_md4) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->cert_status |= CERT_STATUS_INVALID; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = MapCertStatusToNetError(verify_result->cert_status); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag certificates using weak signature algorithms. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (verify_result->has_md5) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verify_result->cert_status |= CERT_STATUS_WEAK_SIGNATURE_ALGORITHM; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Avoid replacing a more serious error, such as an OS/library failure, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by ensuring that if verification failed, it failed with a certificate 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == OK || IsCertificateError(rv)) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = MapCertStatusToNetError(verify_result->cert_status); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_ANDROID) 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Flag certificates from publicly-trusted CAs that are issued to intranet 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // hosts. While the CA/Browser Forum Baseline Requirements (v1.1) permit 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // these to be issued until 1 November 2015, they represent a real risk for 268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the deployment of gTLDs and are being phased out ahead of the hard 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // deadline. 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(ppi): is_issued_by_known_root is incorrect on Android. Once this is 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // fixed, re-enable this check for Android. crbug.com/116838 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (verify_result->is_issued_by_known_root && IsHostnameNonUnique(hostname)) { 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) verify_result->cert_status |= CERT_STATUS_NON_UNIQUE_NAME; 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CertVerifyProc::IsBlacklisted(X509Certificate* cert) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const unsigned kComodoSerialBytes = 16; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const uint8 kComodoSerials[][kComodoSerialBytes] = { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not a real certificate. For testing only. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x07,0x7a,0x59,0xbc,0xd5,0x34,0x59,0x60,0x1c,0xa6,0x90,0x72,0x67,0xa6,0xdd,0x1c}, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The next nine certificates all expire on Fri Mar 14 23:59:59 2014. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some serial numbers actually have a leading 0x00 byte required to 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // encode a positive integer in DER if the most significant bit is 0. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We omit the leading 0x00 bytes to make all serial numbers 16 bytes. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=mail.google.com 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: mail.google.com, www.mail.google.com 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x04,0x7e,0xcb,0xe9,0xfc,0xa5,0x5f,0x7b,0xd0,0x9e,0xae,0x36,0xe1,0x0c,0xae,0x1e}, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=global trustee 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: global trustee 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: not a CA certificate. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xd8,0xf3,0x5f,0x4e,0xb7,0x87,0x2b,0x2d,0xab,0x06,0x92,0xe3,0x15,0x38,0x2f,0xb0}, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=login.live.com 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: login.live.com, www.login.live.com 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xb0,0xb7,0x13,0x3e,0xd0,0x96,0xf9,0xb5,0x6f,0xae,0x91,0xc8,0x74,0xbd,0x3a,0xc0}, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=addons.mozilla.org 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: addons.mozilla.org, www.addons.mozilla.org 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x92,0x39,0xd5,0x34,0x8f,0x40,0xd1,0x69,0x5a,0x74,0x54,0x70,0xe1,0xf2,0x3f,0x43}, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=login.skype.com 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: login.skype.com, www.login.skype.com 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xe9,0x02,0x8b,0x95,0x78,0xe4,0x15,0xdc,0x1a,0x71,0x0a,0x2b,0x88,0x15,0x44,0x47}, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=login.yahoo.com 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: login.yahoo.com, www.login.yahoo.com 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xd7,0x55,0x8f,0xda,0xf5,0xf1,0x10,0x5b,0xb2,0x13,0x28,0x2b,0x70,0x77,0x29,0xa3}, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=www.google.com 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: www.google.com, google.com 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xf5,0xc8,0x6a,0xf3,0x61,0x62,0xf1,0x3a,0x64,0xf5,0x4f,0x6d,0xc9,0x58,0x7c,0x06}, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=login.yahoo.com 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: login.yahoo.com 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x39,0x2a,0x43,0x4f,0x0e,0x07,0xdf,0x1f,0x8a,0xa3,0x05,0xde,0x34,0xe0,0xc2,0x29}, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=login.yahoo.com 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subjectAltName dNSName: login.yahoo.com 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x3e,0x75,0xce,0xd4,0x6b,0x69,0x30,0x21,0x21,0x88,0x30,0xae,0x86,0xa8,0x2a,0x71}, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& serial_number = cert->serial_number(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!serial_number.empty() && (serial_number[0] & 0x80) != 0) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a negative serial number, which isn't technically allowed but 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which probably happens. In order to avoid confusing a negative serial 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number with a positive one once the leading zeros have been removed, we 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disregard it. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece serial(serial_number); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove leading zeros. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (serial.size() > 1 && serial[0] == 0) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serial.remove_prefix(1); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (serial.size() == kComodoSerialBytes) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < arraysize(kComodoSerials); i++) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (memcmp(kComodoSerials[i], serial.data(), kComodoSerialBytes) == 0) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Net.SSLCertBlacklisted", i, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(kComodoSerials) + 1); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: This implementation assumes and enforces that the hashes are SHA1. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CertVerifyProc::IsPublicKeyBlacklisted( 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HashValueVector& public_key_hashes) { 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static const unsigned kNumHashes = 11; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const uint8 kHashes[kNumHashes][base::kSHA1Length] = { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=DigiNotar Root CA 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=Entrust.net x2 and self-signed 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x41, 0x0f, 0x36, 0x36, 0x32, 0x58, 0xf3, 0x0b, 0x34, 0x7d, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x12, 0xce, 0x48, 0x63, 0xe4, 0x33, 0x43, 0x78, 0x06, 0xa8}, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=DigiNotar Cyber CA 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=GTE CyberTrust Global Root 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xc4, 0xf9, 0x66, 0x37, 0x16, 0xcd, 0x5e, 0x71, 0xd6, 0x95, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x0b, 0x5f, 0x33, 0xce, 0x04, 0x1c, 0x95, 0xb4, 0x35, 0xd1}, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=DigiNotar Services 1024 CA 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=Entrust.net 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xe2, 0x3b, 0x8d, 0x10, 0x5f, 0x87, 0x71, 0x0a, 0x68, 0xd9, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x24, 0x80, 0x50, 0xeb, 0xef, 0xc6, 0x27, 0xbe, 0x4c, 0xa6}, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=Staat der Nederlanden Organisatie CA - G2 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x7b, 0x2e, 0x16, 0xbc, 0x39, 0xbc, 0xd7, 0x2b, 0x45, 0x6e, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x9f, 0x05, 0x5d, 0x1d, 0xe6, 0x15, 0xb7, 0x49, 0x45, 0xdb}, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=Staat der Nederlanden Overheid CA 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xe8, 0xf9, 0x12, 0x00, 0xc6, 0x5c, 0xee, 0x16, 0xe0, 0x39, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xb9, 0xf8, 0x83, 0x84, 0x16, 0x61, 0x63, 0x5f, 0x81, 0xc5}, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: O=Digicert Sdn. Bhd. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=GTE CyberTrust Global Root 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expires: Jul 17 15:16:54 2012 GMT 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x01, 0x29, 0xbc, 0xd5, 0xb4, 0x48, 0xae, 0x8d, 0x24, 0x96, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xd1, 0xc3, 0xe1, 0x97, 0x23, 0x91, 0x90, 0x88, 0xe1, 0x52}, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subject: O=Digicert Sdn. Bhd. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=Entrust.net Certification Authority (2048) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expires: Jul 16 17:53:37 2015 GMT 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xd3, 0x3c, 0x5b, 0x41, 0xe4, 0x5c, 0xc4, 0xb3, 0xbe, 0x9a, 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xd6, 0x95, 0x2c, 0x4e, 0xcc, 0x25, 0x28, 0x03, 0x29, 0x81}, 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issuer: CN=Trustwave Organization Issuing CA, Level 2 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Covers two certificates, the latter of which expires Apr 15 21:09:30 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2021 GMT. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xe1, 0x2d, 0x89, 0xf5, 0x6d, 0x22, 0x76, 0xf8, 0x30, 0xe6, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xce, 0xaf, 0xa6, 0x6c, 0x72, 0x5c, 0x0b, 0x41, 0xa9, 0x32}, 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cyberoam CA certificate. Private key leaked, but this certificate would 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only have been installed by Cyberoam customers. The certificate expires 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in 2036, but we can probably remove in a couple of years (2014). 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0xd9, 0xf5, 0xc6, 0xce, 0x57, 0xff, 0xaa, 0x39, 0xcc, 0x7e, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xd1, 0x72, 0xbd, 0x53, 0xe0, 0xd3, 0x07, 0x83, 0x4b, 0xd1}, 396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Win32/Sirefef.gen!C generates fake certificates with this public key. 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {0xa4, 0xf5, 0x6e, 0x9e, 0x1d, 0x9a, 0x3b, 0x7b, 0x1a, 0xc3, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0x31, 0xcf, 0x64, 0xfc, 0x76, 0x2c, 0xd0, 0x51, 0xfb, 0xa4}, 399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ANSSI certificate under which a MITM proxy was mistakenly operated. 400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Expires: Jul 18 10:05:28 2014 GMT 401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) {0x3e, 0xcf, 0x4b, 0xbb, 0xe4, 0x60, 0x96, 0xd5, 0x14, 0xbb, 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 0x53, 0x9b, 0xb9, 0x13, 0xd7, 0x7a, 0xa4, 0xef, 0x31, 0xbf}, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < kNumHashes; i++) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HashValueVector::const_iterator j = public_key_hashes.begin(); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j != public_key_hashes.end(); ++j) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j->tag == HASH_VALUE_SHA1 && 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcmp(j->data(), kHashes[i], base::kSHA1Length) == 0) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 418d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)static const size_t kMaxTLDLength = 4; 419d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 420d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// CheckNameConstraints verifies that every name in |dns_names| is in one of 421d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// the domains specified by |tlds|. The |tlds| array is terminated by an empty 422d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// string. 423d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)static bool CheckNameConstraints(const std::vector<std::string>& dns_names, 424d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const char tlds[][kMaxTLDLength]) { 425d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (std::vector<std::string>::const_iterator i = dns_names.begin(); 426d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) i != dns_names.end(); ++i) { 427d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) bool ok = false; 428d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) url_canon::CanonHostInfo host_info; 429d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const std::string dns_name = CanonicalizeHost(*i, &host_info); 430d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (host_info.IsIPAddress()) 431d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) continue; 432d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 433d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const size_t registry_len = registry_controlled_domains::GetRegistryLength( 434d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) dns_name, 435d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, 436d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); 437d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // If the name is not in a known TLD, ignore it. This permits internal 438d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // names. 439d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (registry_len == 0) 440d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) continue; 441d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 442d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (size_t j = 0; tlds[j][0]; ++j) { 443d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const size_t tld_length = strlen(tlds[j]); 444d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // The DNS name must have "." + tlds[j] as a suffix. 445d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (i->size() <= (1 /* period before TLD */ + tld_length)) 446d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) continue; 447d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 448d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const char* suffix = &dns_name[i->size() - tld_length - 1]; 449d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (suffix[0] != '.') 450d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) continue; 451d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (memcmp(&suffix[1], tlds[j], tld_length) != 0) 452d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) continue; 453d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) ok = true; 454d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) break; 455d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 456d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 457d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!ok) 458d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return false; 459d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 460d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 461d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return true; 462d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} 463d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 464d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// PublicKeyTLDLimitation contains a SHA1, SPKI hash and a pointer to an array 465d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// of fixed-length strings that contain the TLDs that the SPKI is allowed to 466d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// issue for. 467d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)struct PublicKeyTLDLimitation { 468d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) uint8 public_key[base::kSHA1Length]; 469d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const char (*tlds)[kMaxTLDLength]; 470d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)}; 471d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 472d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static 473d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool CertVerifyProc::HasNameConstraintsViolation( 474d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const HashValueVector& public_key_hashes, 475d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const std::string& common_name, 476d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const std::vector<std::string>& dns_names, 477d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const std::vector<std::string>& ip_addrs) { 478d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) static const char kTLDsANSSI[][kMaxTLDLength] = { 479d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "fr", // France 480d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "gp", // Guadeloupe 481d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "gf", // Guyane 482d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "mq", // Martinique 483d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "re", // Réunion 484d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "yt", // Mayotte 485d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "pm", // Saint-Pierre et Miquelon 486d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "bl", // Saint Barthélemy 487d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "mf", // Saint Martin 488d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "wf", // Wallis et Futuna 489d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "pf", // Polynésie française 490d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "nc", // Nouvelle Calédonie 491d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "tf", // Terres australes et antarctiques françaises 492d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "", 493d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) }; 494d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 495d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) static const char kTLDsTest[][kMaxTLDLength] = { 496d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "com", 497d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) "", 498d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) }; 499d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 500d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) static const PublicKeyTLDLimitation kLimits[] = { 501d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI, 502d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr 503d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) { 504d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad, 505d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 0xae, 0x27, 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73}, 506d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) kTLDsANSSI, 507d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) }, 508d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // Not a real certificate - just for testing. This is the SPKI hash of 509d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // the keys used in net/data/ssl/certificates/name_constraint_*.crt. 510d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) { 511d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) {0x15, 0x45, 0xd7, 0x3b, 0x58, 0x6b, 0x47, 0xcf, 0xc1, 0x44, 512d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 0xa2, 0xc9, 0xaa, 0xab, 0x98, 0x3d, 0x21, 0xcc, 0x42, 0xde}, 513d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) kTLDsTest, 514d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) }, 515d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) }; 516d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 517d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (unsigned i = 0; i < arraysize(kLimits); ++i) { 518d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (HashValueVector::const_iterator j = public_key_hashes.begin(); 519d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) j != public_key_hashes.end(); ++j) { 520d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (j->tag == HASH_VALUE_SHA1 && 521d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) memcmp(j->data(), kLimits[i].public_key, base::kSHA1Length) == 0) { 522d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (dns_names.empty() && ip_addrs.empty()) { 523d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) std::vector<std::string> dns_names; 524d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) dns_names.push_back(common_name); 525d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!CheckNameConstraints(dns_names, kLimits[i].tlds)) 526d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return true; 527d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } else { 528d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!CheckNameConstraints(dns_names, kLimits[i].tlds)) 529d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return true; 530d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 531d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 532d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 533d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 534d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 535d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return false; 536d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} 537d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 539