Remove separate fields for CT compliance details available
SSLInfo and CTVerifyResult both have a boolean field indicating whether the
compliance status field has been populated. It's easy for consumers to forget to
check the boolean, so this CL gets rid of it and folds it into the compliance
status field by introducing a new enum value to indicate that we don't know
anything about CT compliance.
Cq-Include-Trybots: master.tryserver.chromium.android:android_cronet_tester;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I4ff270ebc6dba38b89cf2d1f078f9ef9cebc8422
Reviewed-on: https://chromium-review.googlesource.com/788175
Commit-Queue: Emily Stark <[email protected]>
Reviewed-by: Ryan Sleevi <[email protected]>
Cr-Commit-Position: refs/heads/master@{#520041}
diff --git a/net/cert/ct_policy_enforcer.cc b/net/cert/ct_policy_enforcer.cc
index e22e0e3..0f77780 100644
--- a/net/cert/ct_policy_enforcer.cc
+++ b/net/cert/ct_policy_enforcer.cc
@@ -85,6 +85,7 @@
return "NOT_DIVERSE_SCTS";
case ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY:
return "BUILD_NOT_TIMELY";
+ case ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE:
case ct::CTPolicyCompliance::CT_POLICY_MAX:
NOTREACHED();
return "unknown";
diff --git a/net/cert/ct_policy_status.h b/net/cert/ct_policy_status.h
index 6028217..eb167b61 100644
--- a/net/cert/ct_policy_status.h
+++ b/net/cert/ct_policy_status.h
@@ -24,6 +24,9 @@
// isn't timely and therefore log information might be out of date
// (for example a log might no longer be considered trustworthy).
CT_POLICY_BUILD_NOT_TIMELY = 3,
+ // Compliance details for the connection are not available, e.g. because a
+ // resource was loaded from disk cache.
+ CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE = 4,
CT_POLICY_MAX
};
diff --git a/net/cert/ct_verify_result.cc b/net/cert/ct_verify_result.cc
index 3f2e9083..b376241f 100644
--- a/net/cert/ct_verify_result.cc
+++ b/net/cert/ct_verify_result.cc
@@ -11,8 +11,8 @@
namespace ct {
CTVerifyResult::CTVerifyResult()
- : ct_policies_applied(false),
- policy_compliance(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS),
+ : policy_compliance(
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE),
policy_compliance_required(false) {}
CTVerifyResult::CTVerifyResult(const CTVerifyResult& other) = default;
diff --git a/net/cert/ct_verify_result.h b/net/cert/ct_verify_result.h
index 0a7129c..4d7ad4f 100644
--- a/net/cert/ct_verify_result.h
+++ b/net/cert/ct_verify_result.h
@@ -30,13 +30,12 @@
// All SCTs and their statuses
SignedCertificateTimestampAndStatusList scts;
- // True if any CT policies were applied on this connection.
- bool ct_policies_applied;
// The result of evaluating whether the connection complies with the
// CT certificate policy.
CTPolicyCompliance policy_compliance;
// True if the connection was required to comply with the CT certificate
- // policy. This value is only meaningful if |ct_policies_applied| is true.
+ // policy. This value is not meaningful if |policy_compliance| is
+ // COMPLIANCE_DETAILS_NOT_AVAILABLE.
bool policy_compliance_required;
};
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 961c70c..425b387 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -887,6 +887,10 @@
using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
std::string hostname = host_port_pair.host();
+ // A connection is considered compliant if it has sufficient SCTs or if the
+ // build is outdated. Other statuses are not considered compliant; this
+ // includes COMPLIANCE_DETAILS_NOT_AVAILABLE because compliance must have been
+ // evaluated in order to determine that the connection is compliant.
bool complies =
(policy_compliance ==
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS ||
@@ -1468,9 +1472,10 @@
return;
if (!ssl_info.is_issued_by_known_root)
return;
- if (!ssl_info.ct_compliance_details_available)
- return;
if (ssl_info.ct_policy_compliance ==
+ ct::CTPolicyCompliance::
+ CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE ||
+ ssl_info.ct_policy_compliance ==
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS ||
ssl_info.ct_policy_compliance ==
ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY) {
@@ -1502,8 +1507,6 @@
// public root or did not comply with CT policy.
if (!ssl_info.is_issued_by_known_root)
return;
- if (!ssl_info.ct_compliance_details_available)
- return;
if (ssl_info.ct_policy_compliance !=
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS) {
// If an Expect-CT header is observed over a non-compliant connection, the
@@ -1514,9 +1517,12 @@
// at connection setup time, so it needs to be reported here while
// processing the header.
if (ssl_info.ct_policy_compliance ==
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY) {
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY ||
+ ssl_info.ct_policy_compliance ==
+ ct::CTPolicyCompliance::
+ CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE) {
// Only send reports for truly non-compliant connections, not those for
- // which compliance wasn't checked due to an out-of-date build.
+ // which compliance wasn't checked.
return;
}
ExpectCTState state;
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 7695a295..373e176 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -1447,7 +1447,6 @@
TEST_F(TransportSecurityStateTest, InvalidExpectCTHeader) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
ssl_info.is_issued_by_known_root = true;
@@ -1479,7 +1478,6 @@
TEST_F(TransportSecurityStateTest, ExpectCTNonPublicRoot) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
ssl_info.is_issued_by_known_root = false;
@@ -1509,9 +1507,8 @@
TEST_F(TransportSecurityStateTest, ExpectCTComplianceNotAvailable) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = false;
ssl_info.ct_policy_compliance =
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE;
ssl_info.is_issued_by_known_root = true;
scoped_refptr<X509Certificate> cert1 =
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
@@ -1529,7 +1526,8 @@
state.ProcessExpectCTHeader("preload", host_port, ssl_info);
EXPECT_EQ(0u, reporter.num_failures());
- ssl_info.ct_compliance_details_available = true;
+ ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
state.ProcessExpectCTHeader("preload", host_port, ssl_info);
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1539,7 +1537,6 @@
TEST_F(TransportSecurityStateTest, ExpectCTCompliantCert) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
ssl_info.is_issued_by_known_root = true;
@@ -1570,7 +1567,6 @@
TEST_F(TransportSecurityStateTest, PreloadedExpectCTBuildNotTimely) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY;
ssl_info.is_issued_by_known_root = true;
@@ -1603,7 +1599,6 @@
TEST_F(TransportSecurityStateTest, DynamicExpectCTBuildNotTimely) {
HostPortPair host_port("example.test", 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY;
ssl_info.is_issued_by_known_root = true;
@@ -1640,7 +1635,6 @@
TEST_F(TransportSecurityStateTest, ExpectCTNotPreloaded) {
HostPortPair host_port("not-expect-ct-preloaded.test", 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
ssl_info.is_issued_by_known_root = true;
@@ -1670,7 +1664,6 @@
TEST_F(TransportSecurityStateTest, ExpectCTReporter) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
ssl_info.is_issued_by_known_root = true;
@@ -1712,7 +1705,6 @@
TEST_F(TransportSecurityStateTest, RepeatedExpectCTReportsForStaticExpectCT) {
HostPortPair host_port(kExpectCTStaticHostname, 443);
SSLInfo ssl_info;
- ssl_info.ct_compliance_details_available = true;
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
ssl_info.is_issued_by_known_root = true;
@@ -2541,7 +2533,6 @@
const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
@@ -2598,7 +2589,6 @@
const char kHeader[] = "max-age=123,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
@@ -2637,7 +2627,6 @@
const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance = ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
base::test::ScopedFeatureList feature_list;
@@ -2680,7 +2669,6 @@
const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
@@ -2725,7 +2713,6 @@
const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = false;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance = ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
base::test::ScopedFeatureList feature_list;
@@ -2746,8 +2733,8 @@
const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = false;
- ssl.ct_policy_compliance = ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ ssl.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE;
scoped_refptr<X509Certificate> cert1 =
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
@@ -2777,7 +2764,6 @@
const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance = ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
scoped_refptr<X509Certificate> cert1 =
@@ -3001,7 +2987,6 @@
const char kHistogramName[] = "Net.ExpectCTHeader.ParseSuccess";
SSLInfo ssl;
ssl.is_issued_by_known_root = true;
- ssl.ct_compliance_details_available = true;
ssl.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
diff --git a/net/quic/chromium/crypto/proof_verifier_chromium.cc b/net/quic/chromium/crypto/proof_verifier_chromium.cc
index 79009ff1..22402263 100644
--- a/net/quic/chromium/crypto/proof_verifier_chromium.cc
+++ b/net/quic/chromium/crypto/proof_verifier_chromium.cc
@@ -391,7 +391,6 @@
if (enforce_policy_checking_ &&
(result == OK ||
(IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
- verify_details_->ct_verify_result.ct_policies_applied = true;
SCTList verified_scts = ct::SCTsMatchingStatus(
verify_details_->ct_verify_result.scts, ct::SCT_STATUS_OK);
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index f490126..ecdf6f8 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1502,8 +1502,6 @@
server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
&ct_verify_result_.scts, net_log_);
- ct_verify_result_.ct_policies_applied = true;
-
SCTList verified_scts =
ct::SCTsMatchingStatus(ct_verify_result_.scts, ct::SCT_STATUS_OK);
diff --git a/net/ssl/ssl_info.cc b/net/ssl/ssl_info.cc
index 5dfca4d..9d9c2f4 100644
--- a/net/ssl/ssl_info.cc
+++ b/net/ssl/ssl_info.cc
@@ -43,7 +43,6 @@
public_key_hashes = info.public_key_hashes;
pinning_failure_log = info.pinning_failure_log;
signed_certificate_timestamps = info.signed_certificate_timestamps;
- ct_compliance_details_available = info.ct_compliance_details_available;
ct_policy_compliance = info.ct_policy_compliance;
ct_policy_compliance_required = info.ct_policy_compliance_required;
ocsp_result = info.ocsp_result;
@@ -67,8 +66,8 @@
base::STLClearObject(&public_key_hashes);
base::STLClearObject(&pinning_failure_log);
base::STLClearObject(&signed_certificate_timestamps);
- ct_compliance_details_available = false;
- ct_policy_compliance = ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
+ ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE;
ct_policy_compliance_required = false;
ocsp_result = OCSPVerifyResult();
}
@@ -83,7 +82,6 @@
ct_verify_result.scts.begin(),
ct_verify_result.scts.end());
- ct_compliance_details_available = ct_verify_result.ct_policies_applied;
ct_policy_compliance = ct_verify_result.policy_compliance;
ct_policy_compliance_required = ct_verify_result.policy_compliance_required;
}
diff --git a/net/ssl/ssl_info.h b/net/ssl/ssl_info.h
index 480c7c51..fd39bbc 100644
--- a/net/ssl/ssl_info.h
+++ b/net/ssl/ssl_info.h
@@ -128,20 +128,13 @@
// status.
SignedCertificateTimestampAndStatusList signed_certificate_timestamps;
- // True if Certificate Transparency policies were applied on this
- // connection and results are available. If true, the field below
- // (|ct_policy_compliance|) will contain information about whether
- // the connection complied with the policy and why the connection
- // was considered non-compliant, if applicable.
- bool ct_compliance_details_available;
-
// Whether the connection complied with the CT cert policy, and if
- // not, why not. Only meaningful if |ct_compliance_details_available|
- // is true.
+ // not, why not.
ct::CTPolicyCompliance ct_policy_compliance;
// True if the connection was required to comply with the CT cert policy. Only
- // meaningful if |ct_compliance_details_available| is true.
+ // meaningful if |ct_policy_compliance| is not
+ // COMPLIANCE_DETAILS_NOT_AVAILABLE.
bool ct_policy_compliance_required;
// OCSP stapling details.
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index bc7273d8..1b1afc07 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -100,8 +100,10 @@
// Records per-request histograms relating to Certificate Transparency
// compliance.
void RecordCTHistograms(const net::SSLInfo& ssl_info) {
- if (!ssl_info.ct_compliance_details_available)
+ if (ssl_info.ct_policy_compliance ==
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE) {
return;
+ }
if (!ssl_info.is_issued_by_known_root)
return;
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index 699e8a00..e0820ee 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -1080,7 +1080,6 @@
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
ssl_socket_data.ssl_info.is_issued_by_known_root = true;
- ssl_socket_data.ssl_info.ct_compliance_details_available = true;
ssl_socket_data.ssl_info.ct_policy_compliance_required = false;
ssl_socket_data.ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
@@ -1122,7 +1121,6 @@
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
ssl_socket_data.ssl_info.is_issued_by_known_root = false;
- ssl_socket_data.ssl_info.ct_compliance_details_available = true;
ssl_socket_data.ssl_info.ct_policy_compliance_required = false;
ssl_socket_data.ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
@@ -1159,7 +1157,6 @@
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
ssl_socket_data.ssl_info.is_issued_by_known_root = true;
- ssl_socket_data.ssl_info.ct_compliance_details_available = true;
ssl_socket_data.ssl_info.ct_policy_compliance_required = true;
ssl_socket_data.ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
@@ -1202,7 +1199,6 @@
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
ssl_socket_data.ssl_info.is_issued_by_known_root = true;
- ssl_socket_data.ssl_info.ct_compliance_details_available = true;
ssl_socket_data.ssl_info.ct_policy_compliance_required = true;
ssl_socket_data.ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;