summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-05 19:12:54 +0000
committerrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-05 19:12:54 +0000
commit614f29d47d90b2290b87296e10db66873b58b882 (patch)
treecb054cf51ee9efa44aa5dba83e765d0215232c02
parent683e11181382a2b78bd057c3e3f3edd385431367 (diff)
downloadchromium_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.cc123
-rw-r--r--tools/metrics/histograms/histograms.xml43
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"/>