diff options
author | rsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-05 19:12:54 +0000 |
---|---|---|
committer | rsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-05 19:12:54 +0000 |
commit | 614f29d47d90b2290b87296e10db66873b58b882 (patch) | |
tree | cb054cf51ee9efa44aa5dba83e765d0215232c02 | |
parent | 683e11181382a2b78bd057c3e3f3edd385431367 (diff) | |
download | chromium_src-614f29d47d90b2290b87296e10db66873b58b882.zip chromium_src-614f29d47d90b2290b87296e10db66873b58b882.tar.gz chromium_src-614f29d47d90b2290b87296e10db66873b58b882.tar.bz2 |
Reland r215489 - Add histograms for certificate's & CA's compliance to the Baseline Requirements
Track the (Leaf, Intermediate Root) certificate (algorithm) x (size),
based on whether or not the certificate was issued before or after the
BR compliance date of 2012-12-31.
This is in advance of considering changes to security indicators.
BUG=102949
TBR=jar@chromium.org,wtc@chromium.org
Review URL: https://chromiumcodereview.appspot.com/22203003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215654 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/cert/cert_verify_proc.cc | 123 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 43 |
2 files changed, 148 insertions, 18 deletions
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc index 783b383..b9bbbe0 100644 --- a/net/cert/cert_verify_proc.cc +++ b/net/cert/cert_verify_proc.cc @@ -6,6 +6,7 @@ #include "base/metrics/histogram.h" #include "base/sha1.h" +#include "base/strings/stringprintf.h" #include "build/build_config.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" @@ -34,6 +35,69 @@ namespace net { namespace { +// Constants used to build histogram names +const char kLeafCert[] = "Leaf"; +const char kIntermediateCert[] = "Intermediate"; +const char kRootCert[] = "Root"; +// Matches the order of X509Certificate::PublicKeyType +const char* const kCertTypeStrings[] = { + "Unknown", + "RSA", + "DSA", + "ECDSA", + "DH", + "ECDH" +}; +// Histogram buckets for RSA/DSA/DH key sizes. +const int kRsaDsaKeySizes[] = {512, 768, 1024, 1536, 2048, 3072, 4096, 8192, + 16384}; +// Histogram buckets for ECDSA/ECDH key sizes. The list is based upon the FIPS +// 186-4 approved curves. +const int kEccKeySizes[] = {163, 192, 224, 233, 256, 283, 384, 409, 521, 571}; + +const char* CertTypeToString(int cert_type) { + if (cert_type < 0 || + static_cast<size_t>(cert_type) >= arraysize(kCertTypeStrings)) { + return "Unsupported"; + } + return kCertTypeStrings[cert_type]; +} + +void RecordPublicKeyHistogram(const char* chain_position, + bool after_baseline_date, + size_t size_bits, + X509Certificate::PublicKeyType cert_type) { + std::string histogram_name = + base::StringPrintf("CertificateType.%s.%s.%s", + after_baseline_date ? "BR" : "NonBR", + chain_position, + CertTypeToString(cert_type)); + // Do not use UMA_HISTOGRAM_... macros here, as it caches the Histogram + // instance and thus only works if |histogram_name| is constant. + base::HistogramBase* counter = NULL; + + // Histogram buckets are contingent upon the underlying algorithm being used. + if (cert_type == X509Certificate::kPublicKeyTypeECDH || + cert_type == X509Certificate::kPublicKeyTypeECDSA) { + // Typical key sizes match SECP/FIPS 186-3 recommendations for prime and + // binary curves - which range from 163 bits to 571 bits. + counter = base::CustomHistogram::FactoryGet( + histogram_name, + base::CustomHistogram::ArrayToCustomRanges(kEccKeySizes, + arraysize(kEccKeySizes)), + base::HistogramBase::kUmaTargetedHistogramFlag); + } else { + // Key sizes < 1024 bits should cause errors, while key sizes > 16K are not + // uniformly supported by the underlying cryptographic libraries. + counter = base::CustomHistogram::FactoryGet( + histogram_name, + base::CustomHistogram::ArrayToCustomRanges(kRsaDsaKeySizes, + arraysize(kRsaDsaKeySizes)), + base::HistogramBase::kUmaTargetedHistogramFlag); + } + counter->Add(size_bits); +} + // Returns true if |type| is |kPublicKeyTypeRSA| or |kPublicKeyTypeDSA|, and // if |size_bits| is < 1024. Note that this means there may be false // negatives: keys for other algorithms and which are weak will pass this @@ -48,6 +112,45 @@ bool IsWeakKey(X509Certificate::PublicKeyType type, size_t size_bits) { } } +// Returns true if |cert| contains a known-weak key. Additionally, histograms +// the observed keys for future tightening of the definition of what +// constitutes a weak key. +bool ExaminePublicKeys(const scoped_refptr<X509Certificate>& cert, + bool should_histogram) { + // The effective date of the CA/Browser Forum's Baseline Requirements - + // 2014-01-01 00:00:00 UTC. + const base::Time kBaselineEffectiveDate = + base::Time::FromInternalValue(GG_INT64_C(13033008000000000)); + + size_t size_bits = 0; + X509Certificate::PublicKeyType type = X509Certificate::kPublicKeyTypeUnknown; + bool weak_key = false; + bool after_baseline_date = cert->valid_expiry() >= kBaselineEffectiveDate; + + X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &size_bits, &type); + if (should_histogram) + RecordPublicKeyHistogram(kLeafCert, after_baseline_date, size_bits, type); + if (IsWeakKey(type, size_bits)) + weak_key = true; + + const X509Certificate::OSCertHandles& intermediates = + cert->GetIntermediateCertificates(); + for (size_t i = 0; i < intermediates.size(); ++i) { + X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type); + if (should_histogram) { + RecordPublicKeyHistogram( + (i < intermediates.size() - 1) ? kIntermediateCert : kRootCert, + after_baseline_date, + size_bits, + type); + } + if (!weak_key && IsWeakKey(type, size_bits)) + weak_key = true; + } + + return weak_key; +} + } // namespace // static @@ -103,24 +206,8 @@ int CertVerifyProc::Verify(X509Certificate* cert, } // Check for weak keys in the entire verified chain. - size_t size_bits = 0; - X509Certificate::PublicKeyType type = - X509Certificate::kPublicKeyTypeUnknown; - bool weak_key = false; - - X509Certificate::GetPublicKeyInfo( - verify_result->verified_cert->os_cert_handle(), &size_bits, &type); - if (IsWeakKey(type, size_bits)) { - weak_key = true; - } else { - const X509Certificate::OSCertHandles& intermediates = - verify_result->verified_cert->GetIntermediateCertificates(); - for (size_t i = 0; i < intermediates.size(); ++i) { - X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type); - if (IsWeakKey(type, size_bits)) - weak_key = true; - } - } + bool weak_key = ExaminePublicKeys(verify_result->verified_cert, + verify_result->is_issued_by_known_root); if (weak_key) { verify_result->cert_status |= CERT_STATUS_WEAK_KEY; diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d7d32e6..71021e3 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -1133,6 +1133,14 @@ other types of suffix sets. </summary> </histogram> +<histogram name="CertificateType"> + <summary> + Information about the certificate algorithms and sizes in use on the web, to + examine compliance with the CA/Browser Forum requirements and security best + practice. + </summary> +</histogram> + <histogram name="Chrome.SearchSelectExempt" enum="SearchEngine"> <obsolete> Deprecated 8/2013. No longer tracked. @@ -22422,6 +22430,41 @@ other types of suffix sets. <affected-histogram name="PLT.CommitToFirstPaint"/> </fieldtrial> +<fieldtrial name="CertificateTypeAlgorithms" separator="."> + <group name="DH" label="DH"/> + <group name="DSA" label="DSA"/> + <group name="ECDH" label="ECDH"/> + <group name="ECDSA" label="ECDSA"/> + <group name="RSA" label="RSA"/> + <group name="Unknown" label="SPKI unrecognized by cert library"/> + <group name="Unsupported" label="Un-histogrammed type - please fix"/> + <affected-histogram name="CertificateType.BR.Intermediate"/> + <affected-histogram name="CertificateType.BR.Leaf"/> + <affected-histogram name="CertificateType.BR.Root"/> + <affected-histogram name="CertificateType.NonBR.Intermediate"/> + <affected-histogram name="CertificateType.NonBR.Leaf"/> + <affected-histogram name="CertificateType.NonBR.Root"/> +</fieldtrial> + +<fieldtrial name="CertificateTypeBRValidity" separator="."> + <group name="BR" + label="The *leaf* certificate of the chain expires after 2013-12-31, + meaning that it should be in scope for the Baseline + Requirement's key size requirements"/> + <group name="NonBR" + label="The *leaf* certificate of the chain expires on or before + 2013-12-31"/> + <affected-histogram name="CertificateType"/> +</fieldtrial> + +<fieldtrial name="CertificateTypeChainPosition" separator="."> + <group name="Intermediate" label="Intermediate's SPKI"/> + <group name="Leaf" label="Leaf's SPKI"/> + <group name="Root" label="Root's SPKI"/> + <affected-histogram name="CertificateType.BR"/> + <affected-histogram name="CertificateType.NonBR"/> +</fieldtrial> + <fieldtrial name="ConnCountImpact"> <group name="conn_count_16" label="with 16 persistent connections per host"/> <group name="conn_count_4" label="with 4 persistent connections per host"/> |