Chromium Code Reviews| Index: net/cert/cert_policy_enforcer.cc |
| diff --git a/net/cert/cert_policy_enforcer.cc b/net/cert/cert_policy_enforcer.cc |
| index c9ce7cc4a0873268a0fc910bb7906ff69ae44350..2377ac7317d94da1b0a6d794847b81602f5df672 100644 |
| --- a/net/cert/cert_policy_enforcer.cc |
| +++ b/net/cert/cert_policy_enforcer.cc |
| @@ -6,15 +6,20 @@ |
| #include <algorithm> |
| +#include "base/bind.h" |
| #include "base/build_time.h" |
| +#include "base/callback_helpers.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/metrics/histogram.h" |
| #include "base/numerics/safe_conversions.h" |
| #include "base/strings/string_number_conversions.h" |
| +#include "base/values.h" |
| +#include "net/base/net_log.h" |
| #include "net/cert/ct_ev_whitelist.h" |
| #include "net/cert/ct_verify_result.h" |
| #include "net/cert/signed_certificate_timestamp.h" |
| #include "net/cert/x509_certificate.h" |
| +#include "net/cert/x509_certificate_net_log_param.h" |
| namespace net { |
| @@ -60,11 +65,55 @@ enum CTComplianceStatus { |
| CT_COMPLIANCE_MAX, |
| }; |
| +const char* ComplianceStatusToString(CTComplianceStatus status) { |
| + switch (status) { |
| + case CT_NOT_COMPLIANT: |
| + return "NOT_COMPLIANT"; |
| + break; |
| + case CT_IN_WHITELIST: |
| + return "WHITELISTED"; |
| + break; |
| + case CT_ENOUGH_SCTS: |
| + return "ENOUGH_SCTS"; |
| + break; |
| + case CT_COMPLIANCE_MAX: |
| + break; |
| + } |
| + |
| + return "unknown"; |
| +} |
| + |
| void LogCTComplianceStatusToUMA(CTComplianceStatus status) { |
| UMA_HISTOGRAM_ENUMERATION("Net.SSL_EVCertificateCTCompliance", status, |
| CT_COMPLIANCE_MAX); |
| } |
| +struct PolicyComplianceResult { |
| + PolicyComplianceResult() { Reset(); } |
| + |
| + void Reset() { |
|
mmenke
2014/12/10 20:36:39
Not needed. Can just do all this in the construct
Eran Messeri
2014/12/12 12:44:56
Done.
|
| + ct_presence_required = false; |
| + build_timely = false; |
| + result = CT_NOT_COMPLIANT; |
| + } |
| + |
| + bool ct_presence_required; |
| + bool build_timely; |
| + CTComplianceStatus result; |
|
mmenke
2014/12/10 20:36:39
May want to document these (Disclaimer: I know no
mmenke
2014/12/10 20:36:40
result->result is a bit ugly.
Eran Messeri
2014/12/12 12:44:56
Done.
Eran Messeri
2014/12/12 12:44:56
Done, changed.
|
| +}; |
| + |
| +base::Value* NetLogComplianceCheckResultCallback(X509Certificate* cert, |
| + PolicyComplianceResult* result, |
| + NetLog::LogLevel log_level) { |
| + base::DictionaryValue* dict = new base::DictionaryValue(); |
| + dict->Set("certificate", NetLogX509CertificateCallback(cert, log_level)); |
| + dict->SetBoolean("policy_enforcement_required", result->ct_presence_required); |
| + dict->SetBoolean("build_timely", result->build_timely); |
| + dict->SetString("ct_compliance_status", |
| + ComplianceStatusToString(result->result)); |
|
mmenke
2014/12/10 20:36:40
Logging this when one of the others is false seems
Eran Messeri
2014/12/12 12:44:56
Acknowledged - it indeed does not make sense to lo
|
| + return dict; |
| +} |
| + |
| } // namespace |
| CertPolicyEnforcer::CertPolicyEnforcer(size_t num_ct_logs, |
| @@ -78,24 +127,29 @@ CertPolicyEnforcer::~CertPolicyEnforcer() { |
| bool CertPolicyEnforcer::DoesConformToCTEVPolicy( |
| X509Certificate* cert, |
| const ct::EVCertsWhitelist* ev_whitelist, |
| - const ct::CTVerifyResult& ct_result) { |
| - if (!require_ct_for_ev_) |
| + const ct::CTVerifyResult& ct_result, |
| + const BoundNetLog& net_log) { |
| + PolicyComplianceResult result; |
| + CheckCTEVPolicyCompliance(cert, ev_whitelist, ct_result, &result); |
| + |
| + NetLog::ParametersCallback net_log_callback = |
| + base::Bind(&NetLogComplianceCheckResultCallback, base::Unretained(cert), |
| + base::Unretained(&result)); |
|
Ryan Sleevi
2014/12/10 20:09:26
You don't log anything about the ev_whitelist, suc
Eran Messeri
2014/12/10 20:37:03
Good point, I'll add logging of the EV whitelist v
|
| + |
| + net_log.AddEvent(NetLog::TYPE_EV_CERT_CT_COMPLIANCE_CHECKED, |
| + net_log_callback); |
| + |
| + if (!result.ct_presence_required) |
| return true; |
| - if (!IsBuildTimely()) |
| + if (!result.build_timely) |
| return false; |
| - if (IsCertificateInWhitelist(cert, ev_whitelist)) { |
| - LogCTComplianceStatusToUMA(CT_IN_WHITELIST); |
| - return true; |
| - } |
| + LogCTComplianceStatusToUMA(result.result); |
| - if (HasRequiredNumberOfSCTs(cert, ct_result)) { |
| - LogCTComplianceStatusToUMA(CT_ENOUGH_SCTS); |
| + if (result.result == CT_IN_WHITELIST || result.result == CT_ENOUGH_SCTS) |
| return true; |
| - } |
| - LogCTComplianceStatusToUMA(CT_NOT_COMPLIANT); |
| return false; |
| } |
| @@ -162,4 +216,31 @@ bool CertPolicyEnforcer::HasRequiredNumberOfSCTs( |
| std::min(num_required_embedded_scts, min_acceptable_logs); |
| } |
| +void CertPolicyEnforcer::CheckCTEVPolicyCompliance( |
|
mmenke
2014/12/10 20:36:40
This doesn't seem to need to be a member of CertPo
Eran Messeri
2014/12/12 12:44:56
Done, although that led to a behaviour change as i
|
| + X509Certificate* cert, |
| + const ct::EVCertsWhitelist* ev_whitelist, |
| + const ct::CTVerifyResult& ct_result, |
| + PolicyComplianceResult* check_result) { |
| + check_result->Reset(); |
| + if (!require_ct_for_ev_) |
| + return; |
| + check_result->ct_presence_required = true; |
| + |
| + if (!IsBuildTimely()) |
| + return; |
| + check_result->build_timely = true; |
| + |
| + if (IsCertificateInWhitelist(cert, ev_whitelist)) { |
| + check_result->result = CT_IN_WHITELIST; |
| + return; |
| + } |
| + |
| + if (HasRequiredNumberOfSCTs(cert, ct_result)) { |
| + check_result->result = CT_ENOUGH_SCTS; |
| + return; |
| + } |
| + |
| + check_result->result = CT_NOT_COMPLIANT; |
| +} |
| + |
| } // namespace net |