Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Unified Diff: net/tools/ct_mapper/my_visitor.cc

Issue 1238413004: Framework for iterating over certificates in CT database from Chromium code. (not for review) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make samples page work Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/tools/ct_mapper/my_visitor.h ('k') | net/tools/ct_mapper/sync-ct-database.sh » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/tools/ct_mapper/my_visitor.cc
diff --git a/net/tools/ct_mapper/my_visitor.cc b/net/tools/ct_mapper/my_visitor.cc
new file mode 100644
index 0000000000000000000000000000000000000000..15d3475568153b36314dcaa2e2702ba40fe21051
--- /dev/null
+++ b/net/tools/ct_mapper/my_visitor.cc
@@ -0,0 +1,258 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/tools/ct_mapper/my_visitor.h"
+
+#include <algorithm>
+
+#include "base/strings/stringprintf.h"
+#include "net/cert/internal/parsed_certificate.h"
+#include "net/cert/internal/signature_policy.h"
+#include "net/cert/internal/trust_store.h"
+#include "net/cert/internal/verify_certificate_chain.h"
+#include "net/der/encode_values.h"
+#include "net/der/input.h"
+#include "net/tools/ct_mapper/entry.h"
+#include "net/tools/ct_mapper/metrics.h"
+#include "net/tools/ct_mapper/visitor.h"
+
+namespace net {
+
+namespace {
+
+bool AddParsedCertificate(const der::Input& cert_data,
+ ParsedCertificateList* chain,
+ CertErrors* errors) {
+ ParseCertificateOptions options;
+ options.allow_invalid_serial_numbers = true;
+ scoped_refptr<ParsedCertificate> cert =
+ ParsedCertificate::CreateWithoutCopyingUnsafe(
+ cert_data.UnsafeData(), cert_data.Length(), options, errors);
+ if (!cert) {
+ return false;
+ }
+ chain->push_back(std::move(cert));
+ return true;
+}
+
+void LogCertPathErrors(CertPathErrors* errors,
+ const ParsedCertificateList& chain,
+ const std::string& name,
+ const Entry& entry,
+ CertError::Severity severity,
+ Metrics* metrics) {
+ if (errors->ContainsAnyErrorWithSeverity(severity)) {
+ MetricsItem* item = metrics->GetAndIncrementTotal(name);
+
+ // Identify all the errors.
+ std::set<std::string> error_set;
+ for (size_t i = 0; i < chain.size(); ++i) {
+ CertErrors* cert_errors = errors->GetErrorsForCert(i);
+ for (const auto& error_node : cert_errors->nodes()) {
+ if (error_node.severity == severity) {
+ error_set.insert(error_node.ToDebugString());
+ }
+ }
+ }
+
+ for (const auto& error : error_set) {
+ item->GetAndIncrementTotal(error)->AddSampleChain(entry);
+ }
+ }
+}
+
+void LogCertErrors(const CertErrors& errors,
+ const std::string& name,
+ const der::Input& cert,
+ CertError::Severity severity,
+ bool parsing_succeeded,
+ Metrics* metrics) {
+ if (errors.ContainsAnyErrorWithSeverity(severity)) {
+ MetricsItem* item = metrics->GetAndIncrementTotal(name);
+
+ // Identify all the errors.
+ std::set<std::string> error_set;
+ for (const auto& error_node : errors.nodes()) {
+ if (error_node.severity == severity) {
+ error_set.insert(error_node.ToDebugString());
+ }
+ }
+
+ for (const auto& error : error_set) {
+ item->GetAndIncrementTotal(error)->AddSampleCert(cert);
+ }
+ } else if (!parsing_succeeded && severity == CertError::SEVERITY_HIGH) {
+ metrics->GetAndIncrementTotal(name)
+ ->GetAndIncrementTotal("Unknown")
+ ->AddSampleCert(cert);
+ }
+}
+
+bool GetFullChain(const Entry& entry,
+ ParsedCertificateList* chain,
+ Metrics* metrics) {
+ chain->reserve(entry.extra_certs.size() + 1);
+
+ CertErrors errors;
+
+ MetricsItem* item = metrics->GetAndIncrementTotal("Parse Certificate");
+ bool parsing_succeeded = AddParsedCertificate(entry.cert, chain, &errors);
+
+ if (!parsing_succeeded) {
+ item->GetAndIncrementTotal("Failure");
+ } else {
+ item->GetAndIncrementTotal("Success");
+ }
+
+ LogCertErrors(errors, "Parse certificate Errors", entry.cert,
+ CertError::SEVERITY_HIGH, parsing_succeeded, metrics);
+ LogCertErrors(errors, "Parse certificate Warnings", entry.cert,
+ CertError::SEVERITY_WARNING, parsing_succeeded, metrics);
+
+ if (!parsing_succeeded)
+ return false;
+
+ for (const auto& extra_cert : entry.extra_certs) {
+ if (!AddParsedCertificate(extra_cert, chain, &errors)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+base::Time GetTime(const der::GeneralizedTime& der_time) {
+ base::Time::Exploded exploded;
+ exploded.year = der_time.year;
+ exploded.month = der_time.month;
+ exploded.day_of_month = der_time.day;
+ exploded.hour = der_time.hours;
+ exploded.minute = der_time.minutes;
+ exploded.second = der_time.seconds;
+ exploded.millisecond = 0;
+
+ base::Time t;
+ if (!base::Time::FromUTCExploded(exploded, &t))
+ return base::Time();
+ return t;
+}
+
+class MyVisitor : public Visitor {
+ public:
+ MyVisitor() : signature_policy_rsa_1024_(1024) {
+ now_time_ = base::Time::Now();
+ CHECK(der::EncodeTimeAsGeneralizedTime(now_time_, &now_));
+ user_initial_policy_set_ = {AnyPolicy()};
+ }
+
+ void Visit(const Entry& entry, Metrics* metrics) override {
+ // Count the entry types.
+ {
+ MetricsItem* item = metrics->GetAndIncrementTotal("CT Entry types");
+
+ switch (entry.type) {
+ case Entry::Type::kLeafCert:
+ item->GetAndIncrementTotal("Leaf");
+ break;
+ case Entry::Type::kExtraCert:
+ item->GetAndIncrementTotal("Extra Cert");
+ break;
+ }
+ }
+
+ // Parse all the certificate.
+ ParsedCertificateList chain;
+ if (!GetFullChain(entry, &chain, metrics))
+ return;
+
+ if (entry.type != Entry::Type::kLeafCert)
+ return;
+
+ base::Time not_before;
+ base::Time not_after;
+
+ GetChainExpiration(chain, &not_before, &not_after);
+ bool chain_expired = now_time_ < not_before || now_time_ > not_after;
+
+ if (chain_expired) {
+ // Use the midpoint of the chain's validity.
+ base::Time avg_t = not_before + (not_after - not_before) / 2;
+
+ der::GeneralizedTime t;
+ der::EncodeTimeAsGeneralizedTime(avg_t, &t);
+
+ TestVerifyChain(chain, "[expired] ", entry, t, metrics);
+ } else {
+ TestVerifyChain(chain, "", entry, now_, metrics);
+ }
+ }
+
+ private:
+ void TestVerifyChain(const ParsedCertificateList& chain,
+ const std::string& name_prefix,
+ const Entry& entry,
+ const der::GeneralizedTime& time,
+ Metrics* metrics) {
+ KeyPurpose required_key_purpose = KeyPurpose::SERVER_AUTH;
+ CertPathErrors errors;
+ VerifyCertificateChain(
+ chain, CertificateTrust::ForTrustAnchor(), &signature_policy_rsa_1024_,
+ time, required_key_purpose, InitialExplicitPolicy::kFalse,
+ user_initial_policy_set_, InitialPolicyMappingInhibit ::kFalse,
+ InitialAnyPolicyInhibit::kFalse, nullptr, &errors);
+
+ // Log whether validation succeeded.
+ {
+ MetricsItem* item =
+ metrics->GetAndIncrementTotal(name_prefix + "Verify Chain");
+ if (errors.ContainsHighSeverityErrors()) {
+ item->GetAndIncrementTotal("Failure")->AddSampleChain(entry);
+ } else {
+ item->GetAndIncrementTotal("Success");
+ }
+ }
+
+ // Log the breakdown of the errors.
+ LogCertPathErrors(&errors, chain, name_prefix + "Verify Chain Errors",
+ entry, CertError::SEVERITY_HIGH, metrics);
+
+ LogCertPathErrors(&errors, chain,
+ name_prefix + "Verify Chain Warnings", entry,
+ CertError::SEVERITY_WARNING, metrics);
+ }
+
+ void GetChainExpiration(const ParsedCertificateList& chain,
+ base::Time* not_before,
+ base::Time* not_after) const {
+ *not_before = base::Time();
+ *not_after = base::Time::Max();
+
+ // Determine whether any certificate in the chain (except root) is expired.
+ for (size_t i = 0; i + 1 < chain.size(); ++i) {
+ const auto& tbs = chain[i]->tbs();
+ *not_before = std::max(GetTime(tbs.validity_not_before), *not_before);
+ *not_after = std::min(GetTime(tbs.validity_not_after), *not_after);
+ }
+ }
+
+ der::GeneralizedTime now_;
+ base::Time now_time_;
+ std::set<der::Input> user_initial_policy_set_;
+ SimpleSignaturePolicy signature_policy_rsa_1024_;
+};
+
+class MyVisitorFactory : public VisitorFactory {
+ public:
+ std::unique_ptr<Visitor> Create() override {
+ return base::MakeUnique<MyVisitor>();
+ }
+};
+
+} // namespace
+
+std::unique_ptr<VisitorFactory> CreateMyVisitorFactory() {
+ return base::MakeUnique<MyVisitorFactory>();
+}
+
+} // namespace net
« no previous file with comments | « net/tools/ct_mapper/my_visitor.h ('k') | net/tools/ct_mapper/sync-ct-database.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698