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

Unified Diff: net/cert/ct_policy_enforcer.cc

Issue 1578993003: Add Expect CT policy that gets checked on all certs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 10 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/cert/ct_policy_enforcer.h ('k') | net/cert/ct_policy_enforcer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/ct_policy_enforcer.cc
diff --git a/net/cert/ct_policy_enforcer.cc b/net/cert/ct_policy_enforcer.cc
index aa8838b2ff34f9909e66d6b6385ffce89fb9c427..e036087c5cab04ec9b16e33d1f25cf2f17118d50 100644
--- a/net/cert/ct_policy_enforcer.cc
+++ b/net/cert/ct_policy_enforcer.cc
@@ -130,35 +130,42 @@ bool HasEnoughDiverseSCTs(const ct::SCTList& verified_scts) {
(verified_scts.size() != num_google_issued_scts);
}
-enum CTComplianceStatus {
- CT_NOT_COMPLIANT = 0,
- CT_IN_WHITELIST = 1,
- CT_ENOUGH_SCTS = 2,
- CT_NOT_ENOUGH_DIVERSE_SCTS = 3,
- CT_COMPLIANCE_MAX,
-};
-
-const char* ComplianceStatusToString(CTComplianceStatus status) {
+const char* EVPolicyComplianceToString(ct::EVPolicyCompliance status) {
switch (status) {
- case CT_NOT_COMPLIANT:
- return "NOT_COMPLIANT";
- break;
- case CT_IN_WHITELIST:
+ case ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY:
+ return "POLICY_DOES_NOT_APPLY";
+ case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST:
return "WHITELISTED";
- break;
- case CT_ENOUGH_SCTS:
- return "ENOUGH_SCTS";
- break;
- case CT_NOT_ENOUGH_DIVERSE_SCTS:
- return "NOT_ENOUGH_DIVERSE_SCTS";
- break;
- case CT_COMPLIANCE_MAX:
+ case ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS:
+ return "COMPLIES_VIA_SCTS";
+ case ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS:
+ return "NOT_ENOUGH_SCTS";
+ case ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS:
+ return "SCTS_NOT_DIVERSE";
+ case ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY:
+ return "BUILD_NOT_TIMELY";
+ case ct::EVPolicyCompliance::EV_POLICY_MAX:
break;
}
return "unknown";
}
+const char* CertPolicyComplianceToString(ct::CertPolicyCompliance status) {
+ switch (status) {
+ case ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS:
+ return "COMPLIES_VIA_SCTS";
+ case ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS:
+ return "NOT_ENOUGH_SCTS";
+ case ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS:
+ return "NOT_DIVERSE_SCTS";
+ case ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY:
+ return "BUILD_NOT_TIMELY";
+ }
+
+ return "unknown";
+}
+
enum EVWhitelistStatus {
EV_WHITELIST_NOT_PRESENT = 0,
EV_WHITELIST_INVALID = 1,
@@ -166,11 +173,13 @@ enum EVWhitelistStatus {
EV_WHITELIST_MAX,
};
-void LogCTEVComplianceStatusToUMA(CTComplianceStatus status,
- const ct::EVCertsWhitelist* ev_whitelist) {
- UMA_HISTOGRAM_ENUMERATION("Net.SSL_EVCertificateCTCompliance", status,
- CT_COMPLIANCE_MAX);
- if (status == CT_NOT_COMPLIANT) {
+void LogEVPolicyComplianceToUMA(ct::EVPolicyCompliance status,
+ const ct::EVCertsWhitelist* ev_whitelist) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.SSL_EVCTCompliance", static_cast<int>(status),
+ static_cast<int>(ct::EVPolicyCompliance::EV_POLICY_MAX));
+ if (status == ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS ||
+ status == ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS) {
EVWhitelistStatus ev_whitelist_status = EV_WHITELIST_NOT_PRESENT;
if (ev_whitelist != NULL) {
if (ev_whitelist->IsValid())
@@ -184,20 +193,22 @@ void LogCTEVComplianceStatusToUMA(CTComplianceStatus status,
}
}
-struct ComplianceDetails {
- ComplianceDetails() : build_timely(false), status(CT_NOT_COMPLIANT) {}
+struct EVComplianceDetails {
+ EVComplianceDetails()
+ : build_timely(false),
+ status(ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY) {}
// Whether the build is not older than 10 weeks.
bool build_timely;
// Compliance status - meaningful only if |build_timely| is true.
- CTComplianceStatus status;
+ ct::EVPolicyCompliance status;
// EV whitelist version.
base::Version whitelist_version;
};
-scoped_ptr<base::Value> NetLogComplianceCheckResultCallback(
+scoped_ptr<base::Value> NetLogEVComplianceCheckResultCallback(
X509Certificate* cert,
- ComplianceDetails* details,
+ EVComplianceDetails* details,
NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode));
@@ -205,7 +216,7 @@ scoped_ptr<base::Value> NetLogComplianceCheckResultCallback(
dict->SetBoolean("build_timely", details->build_timely);
if (details->build_timely) {
dict->SetString("ct_compliance_status",
- ComplianceStatusToString(details->status));
+ EVPolicyComplianceToString(details->status));
if (details->whitelist_version.IsValid())
dict->SetString("ev_whitelist_version",
details->whitelist_version.GetString());
@@ -213,6 +224,19 @@ scoped_ptr<base::Value> NetLogComplianceCheckResultCallback(
return std::move(dict);
}
+scoped_ptr<base::Value> NetLogCertComplianceCheckResultCallback(
+ X509Certificate* cert,
+ bool build_timely,
+ ct::CertPolicyCompliance compliance,
+ NetLogCaptureMode capture_mode) {
+ scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ dict->Set("certificate", NetLogX509CertificateCallback(cert, capture_mode));
+ dict->SetBoolean("build_timely", build_timely);
+ dict->SetString("ct_compliance_status",
+ CertPolicyComplianceToString(compliance));
+ return std::move(dict);
+}
+
// Returns true if all SCTs in |verified_scts| were issued on, or after, the
// date specified in kDiverseSCTRequirementStartDate
bool AllSCTsPastDistinctSCTRequirementEnforcementDate(
@@ -247,49 +271,100 @@ bool IsCertificateInWhitelist(const X509Certificate& cert,
return cert_in_ev_whitelist;
}
+ct::CertPolicyCompliance CheckCertPolicyCompliance(
+ X509Certificate* cert,
+ const ct::SCTList& verified_scts,
+ const BoundNetLog& net_log) {
+ if (!HasRequiredNumberOfSCTs(*cert, verified_scts))
+ return ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+ if (AllSCTsPastDistinctSCTRequirementEnforcementDate(verified_scts) &&
+ !HasEnoughDiverseSCTs(verified_scts)) {
+ return ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+ }
+
+ return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS;
+}
+
+ct::EVPolicyCompliance CertPolicyComplianceToEVPolicyCompliance(
+ ct::CertPolicyCompliance cert_policy_compliance) {
+ switch (cert_policy_compliance) {
+ case ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS:
+ return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS;
+ case ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS:
+ return ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS;
+ case ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS:
+ return ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS;
+ case ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY:
+ return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY;
+ }
+ return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
+}
+
void CheckCTEVPolicyCompliance(X509Certificate* cert,
const ct::EVCertsWhitelist* ev_whitelist,
const ct::SCTList& verified_scts,
- ComplianceDetails* result) {
- if (!IsBuildTimely())
- return;
- result->build_timely = true;
-
+ const BoundNetLog& net_log,
+ EVComplianceDetails* result) {
+ result->status = CertPolicyComplianceToEVPolicyCompliance(
+ CheckCertPolicyCompliance(cert, verified_scts, net_log));
if (ev_whitelist && ev_whitelist->IsValid())
result->whitelist_version = ev_whitelist->Version();
- if (IsCertificateInWhitelist(*cert, ev_whitelist)) {
- result->status = CT_IN_WHITELIST;
- return;
+ if (result->status != ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS &&
+ IsCertificateInWhitelist(*cert, ev_whitelist)) {
+ result->status = ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST;
}
+}
- if (!HasRequiredNumberOfSCTs(*cert, verified_scts)) {
- result->status = CT_NOT_COMPLIANT;
- return;
- }
+} // namespace
- if (AllSCTsPastDistinctSCTRequirementEnforcementDate(verified_scts) &&
- !HasEnoughDiverseSCTs(verified_scts)) {
- result->status = CT_NOT_ENOUGH_DIVERSE_SCTS;
- return;
+ct::CertPolicyCompliance CTPolicyEnforcer::DoesConformToCertPolicy(
+ X509Certificate* cert,
+ const ct::SCTList& verified_scts,
+ const BoundNetLog& net_log) {
+ // If the build is not timely, no certificate is considered compliant
+ // with CT policy. The reasoning is that, for example, a log might
+ // have been pulled and is no longer considered valid; thus, a client
+ // needs up-to-date information about logs to consider certificates to
+ // be compliant with policy.
+ bool build_timely = IsBuildTimely();
+ ct::CertPolicyCompliance compliance;
+ if (!build_timely) {
+ compliance = ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY;
+ } else {
+ compliance = CheckCertPolicyCompliance(cert, verified_scts, net_log);
}
- result->status = CT_ENOUGH_SCTS;
-}
+ NetLog::ParametersCallback net_log_callback =
+ base::Bind(&NetLogCertComplianceCheckResultCallback,
+ base::Unretained(cert), build_timely, compliance);
-} // namespace
+ net_log.AddEvent(NetLog::TYPE_CERT_CT_COMPLIANCE_CHECKED, net_log_callback);
+
+ return compliance;
+}
ct::EVPolicyCompliance CTPolicyEnforcer::DoesConformToCTEVPolicy(
X509Certificate* cert,
const ct::EVCertsWhitelist* ev_whitelist,
const ct::SCTList& verified_scts,
const BoundNetLog& net_log) {
- ComplianceDetails details;
-
- CheckCTEVPolicyCompliance(cert, ev_whitelist, verified_scts, &details);
+ EVComplianceDetails details;
+ // If the build is not timely, no certificate is considered compliant
+ // with EV policy. The reasoning is that, for example, a log might
+ // have been pulled and is no longer considered valid; thus, a client
+ // needs up-to-date information about logs to consider certificates to
+ // be compliant with policy.
+ details.build_timely = IsBuildTimely();
+ if (!details.build_timely) {
+ details.status = ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY;
+ } else {
+ CheckCTEVPolicyCompliance(cert, ev_whitelist, verified_scts, net_log,
+ &details);
+ }
NetLog::ParametersCallback net_log_callback =
- base::Bind(&NetLogComplianceCheckResultCallback, base::Unretained(cert),
+ base::Bind(&NetLogEVComplianceCheckResultCallback, base::Unretained(cert),
base::Unretained(&details));
net_log.AddEvent(NetLog::TYPE_EV_CERT_CT_COMPLIANCE_CHECKED,
@@ -298,22 +373,9 @@ ct::EVPolicyCompliance CTPolicyEnforcer::DoesConformToCTEVPolicy(
if (!details.build_timely)
return ct::EVPolicyCompliance::EV_POLICY_BUILD_NOT_TIMELY;
- LogCTEVComplianceStatusToUMA(details.status, ev_whitelist);
+ LogEVPolicyComplianceToUMA(details.status, ev_whitelist);
- switch (details.status) {
- case CT_NOT_COMPLIANT:
- return ct::EVPolicyCompliance::EV_POLICY_NOT_ENOUGH_SCTS;
- case CT_IN_WHITELIST:
- return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST;
- case CT_ENOUGH_SCTS:
- return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS;
- case CT_NOT_ENOUGH_DIVERSE_SCTS:
- return ct::EVPolicyCompliance::EV_POLICY_NOT_DIVERSE_SCTS;
- case CT_COMPLIANCE_MAX:
- return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
- }
-
- return ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
+ return details.status;
}
} // namespace net
« no previous file with comments | « net/cert/ct_policy_enforcer.h ('k') | net/cert/ct_policy_enforcer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698