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

Unified Diff: net/http/transport_security_state_unittest.cc

Issue 1579063002: Implement a skeleton version of Expect CT reports (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove unnecessary (?) NET_EXPORTs Created 4 years, 9 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
Index: net/http/transport_security_state_unittest.cc
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 75c7c751904df00fa823ac82646c9a4ef42b22ea..c31f0951ac16307617e9495fa78ea80e1cb14d4b 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -23,6 +23,7 @@
#include "net/cert/asn1_util.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
+#include "net/cert/ct_policy_status.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
@@ -46,6 +47,8 @@ const char kHost[] = "example.test";
const char kSubdomain[] = "foo.example.test";
const uint16_t kPort = 443;
const char kReportUri[] = "http://report-example.test/test";
+const char kExpectCTStaticHostname[] = "preloaded-expect-ct.badssl.com";
+const char kExpectCTStaticReportURI[] = "https://report.badssl.com/expect-ct";
// kGoodPath is blog.torproject.org.
const char* const kGoodPath[] = {
@@ -100,6 +103,34 @@ class MockCertificateReportSender
std::string latest_report_;
};
+// A mock ExpectCTReporter that remembers the latest violation that was
+// reported and the number of violations reported.
+class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
+ public:
+ MockExpectCTReporter() : num_failures_(0) {}
+ ~MockExpectCTReporter() override {}
+
+ void OnExpectCTFailed(const HostPortPair& host_port_pair,
+ const GURL& report_uri,
+ const net::SSLInfo& ssl_info) override {
+ num_failures_++;
+ host_port_pair_ = host_port_pair;
+ report_uri_ = report_uri;
+ ssl_info_ = ssl_info;
+ }
+
+ const HostPortPair& host_port_pair() { return host_port_pair_; }
+ const GURL& report_uri() { return report_uri_; }
+ const SSLInfo& ssl_info() { return ssl_info_; }
+ uint32_t num_failures() { return num_failures_; }
+
+ private:
+ HostPortPair host_port_pair_;
+ GURL report_uri_;
+ SSLInfo ssl_info_;
+ uint32_t num_failures_;
+};
+
void CompareCertificateChainWithList(
const scoped_refptr<X509Certificate>& cert_chain,
const base::ListValue* cert_list) {
@@ -210,6 +241,12 @@ class TransportSecurityStateTest : public testing::Test {
TransportSecurityState::PKPState* pkp_result) {
return state->GetStaticDomainState(host, sts_result, pkp_result);
}
+
+ bool GetExpectCTState(TransportSecurityState* state,
+ const std::string& host,
+ TransportSecurityState::ExpectCTState* result) {
+ return state->GetStaticExpectCTState(host, result);
+ }
};
TEST_F(TransportSecurityStateTest, DomainNameOddities) {
@@ -1553,16 +1590,152 @@ TEST_F(TransportSecurityStateTest, HPKPReportRateLimiting) {
// Tests that static (preloaded) expect CT state is read correctly.
TEST_F(TransportSecurityStateTest, PreloadedExpectCT) {
- const char kHostname[] = "preloaded-expect-ct.badssl.com";
TransportSecurityState state;
TransportSecurityStateTest::EnableStaticExpectCT(&state);
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_TRUE(state.GetStaticExpectCTState(kHostname, &expect_ct_state));
- EXPECT_EQ(kHostname, expect_ct_state.domain);
- EXPECT_EQ(GURL("https://report.badssl.com/expect-ct"),
- expect_ct_state.report_uri);
- EXPECT_FALSE(state.GetStaticExpectCTState("pinning-test.badssl.com",
- &expect_ct_state));
+ EXPECT_TRUE(
+ GetExpectCTState(&state, kExpectCTStaticHostname, &expect_ct_state));
+ EXPECT_EQ(kExpectCTStaticHostname, expect_ct_state.domain);
+ EXPECT_EQ(GURL(kExpectCTStaticReportURI), expect_ct_state.report_uri);
+ EXPECT_FALSE(
+ GetExpectCTState(&state, "pinning-test.badssl.com", &expect_ct_state));
+}
+
+// Tests that the Expect CT reporter is not notified for invalid or absent
+// header values.
+TEST_F(TransportSecurityStateTest, InvalidExpectCTHeader) {
+ HostPortPair host_port(kExpectCTStaticHostname, 443);
+ SSLInfo ssl_info;
+ ssl_info.ct_compliance_details_available = true;
+ ssl_info.ct_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_info.is_issued_by_known_root = true;
+
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.ProcessExpectCTHeader("", host_port, ssl_info);
+ EXPECT_EQ(0u, reporter.num_failures());
+
+ state.ProcessExpectCTHeader("blah blah", host_port, ssl_info);
+ EXPECT_EQ(0u, reporter.num_failures());
+
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is only notified about certificates
+// chaining to public roots.
+TEST_F(TransportSecurityStateTest, ExpectCTNonPublicRoot) {
+ HostPortPair host_port(kExpectCTStaticHostname, 443);
+ SSLInfo ssl_info;
+ ssl_info.ct_compliance_details_available = true;
+ ssl_info.ct_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_info.is_issued_by_known_root = false;
+
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(0u, reporter.num_failures());
+
+ ssl_info.is_issued_by_known_root = true;
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is not notified when compliance
+// details aren't available.
+TEST_F(TransportSecurityStateTest, ExpectCTComplianceNotAvailable) {
+ HostPortPair host_port(kExpectCTStaticHostname, 443);
+ SSLInfo ssl_info;
+ ssl_info.ct_compliance_details_available = false;
+ ssl_info.ct_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_info.is_issued_by_known_root = true;
+
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(0u, reporter.num_failures());
+
+ ssl_info.ct_compliance_details_available = true;
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is not notified about compliant
+// connections.
+TEST_F(TransportSecurityStateTest, ExpectCTCompliantCert) {
+ HostPortPair host_port(kExpectCTStaticHostname, 443);
+ SSLInfo ssl_info;
+ ssl_info.ct_compliance_details_available = true;
+ ssl_info.ct_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS;
+ ssl_info.is_issued_by_known_root = true;
+
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(0u, reporter.num_failures());
+
+ ssl_info.ct_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is not notified for a site that
+// isn't preloaded.
+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_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+ ssl_info.is_issued_by_known_root = true;
+
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(0u, reporter.num_failures());
+
+ host_port.set_host(kExpectCTStaticHostname);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is notified for noncompliant
+// connections.
+TEST_F(TransportSecurityStateTest, ExpectCTReporter) {
+ HostPortPair host_port(kExpectCTStaticHostname, 443);
+ SSLInfo ssl_info;
+ ssl_info.ct_compliance_details_available = true;
+ ssl_info.ct_cert_policy_compliance =
+ ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+ ssl_info.is_issued_by_known_root = true;
+
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ EXPECT_EQ(1u, reporter.num_failures());
+ EXPECT_TRUE(reporter.ssl_info().ct_compliance_details_available);
+ EXPECT_EQ(ssl_info.ct_cert_policy_compliance,
+ reporter.ssl_info().ct_cert_policy_compliance);
+ EXPECT_EQ(host_port.host(), reporter.host_port_pair().host());
+ EXPECT_EQ(host_port.port(), reporter.host_port_pair().port());
+ EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri());
}
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698