Commit d59a9318 authored by Lucas Garron's avatar Lucas Garron

Add Expect-Staple to preload list

BUG=598021
R=agl@chromium.org, estark@chromium.org, lgarron@chromium.org

Review URL: https://codereview.chromium.org/2034843003 .

Cr-Commit-Position: refs/heads/master@{#397844}
parent 3836df28
......@@ -375,6 +375,9 @@ struct PreloadResult {
bool has_pins;
bool expect_ct;
uint32_t expect_ct_report_uri_id;
bool expect_staple;
bool expect_staple_include_subdomains;
uint32_t expect_staple_report_uri_id;
};
// DecodeHSTSPreloadRaw resolves |hostname| in the preloaded data. It returns
......@@ -510,10 +513,22 @@ bool DecodeHSTSPreloadRaw(const std::string& search_hostname,
return false;
}
if (!reader.Next(&tmp.expect_staple))
return false;
tmp.expect_staple_include_subdomains = false;
if (tmp.expect_staple) {
if (!reader.Next(&tmp.expect_staple_include_subdomains))
return false;
if (!reader.Read(4, &tmp.expect_staple_report_uri_id))
return false;
}
tmp.hostname_offset = hostname_offset;
if (hostname_offset == 0 || hostname[hostname_offset - 1] == '.') {
*out_found = tmp.sts_include_subdomains || tmp.pkp_include_subdomains;
*out_found = tmp.sts_include_subdomains ||
tmp.pkp_include_subdomains ||
tmp.expect_staple_include_subdomains;
*out = tmp;
if (hostname_offset > 0) {
......@@ -602,6 +617,7 @@ TransportSecurityState::TransportSecurityState()
report_sender_(nullptr),
enable_static_pins_(true),
enable_static_expect_ct_(true),
enable_static_expect_staple_(false),
expect_ct_reporter_(nullptr),
sent_reports_cache_(kMaxHPKPReportCacheEntries) {
// Static pinning is only enabled for official builds to make sure that
......@@ -856,6 +872,29 @@ bool TransportSecurityState::GetStaticExpectCTState(
return true;
}
bool TransportSecurityState::GetStaticExpectStapleState(
const std::string& host,
ExpectStapleState* expect_staple_state) const {
DCHECK(CalledOnValidThread());
if (!IsBuildTimely())
return false;
PreloadResult result;
if (!DecodeHSTSPreload(host, &result))
return false;
if (!enable_static_expect_staple_ || !result.expect_staple)
return false;
expect_staple_state->domain = host.substr(result.hostname_offset);
expect_staple_state->include_subdomains =
result.expect_staple_include_subdomains;
expect_staple_state->report_uri =
GURL(kExpectStapleReportURIs[result.expect_staple_report_uri_id]);
return true;
}
bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
DCHECK(CalledOnValidThread());
......@@ -1310,6 +1349,11 @@ TransportSecurityState::ExpectCTState::ExpectCTState() {}
TransportSecurityState::ExpectCTState::~ExpectCTState() {}
TransportSecurityState::ExpectStapleState::ExpectStapleState()
: include_subdomains(false) {}
TransportSecurityState::ExpectStapleState::~ExpectStapleState() {}
bool TransportSecurityState::PKPState::CheckPublicKeyPins(
const HashValueVector& hashes,
std::string* failure_log) const {
......
......@@ -198,6 +198,23 @@ class NET_EXPORT TransportSecurityState
GURL report_uri;
};
// An ExpectStapleState describes a site that expects valid OCSP information
// to be stapled to its certificate on every connection.
class NET_EXPORT ExpectStapleState {
public:
ExpectStapleState();
~ExpectStapleState();
// The domain which matched during a search for this Expect-Staple entry
std::string domain;
// The URI reports are sent to if a valid OCSP response is not stapled
GURL report_uri;
// True if subdomains are subject to this policy
bool include_subdomains;
};
// An interface for asynchronously sending HPKP violation reports.
class NET_EXPORT ReportSender {
public:
......@@ -447,6 +464,14 @@ class NET_EXPORT TransportSecurityState
bool GetStaticExpectCTState(const std::string& host,
ExpectCTState* expect_ct_result) const;
// Returns true and updates |*expect_staple_result| iff there is a static
// (built-in) state for |host| with expect_staple=true, or if |host| is a
// subdomain of another domain with expect_staple=true and
// include_subdomains_for_expect_staple=true.
bool GetStaticExpectStapleState(
const std::string& host,
ExpectStapleState* expect_staple_result) const;
// The sets of hosts that have enabled TransportSecurity. |domain| will always
// be empty for a STSState or PKPState in these maps; the domain
// comes from the map keys instead. In addition, |upgrade_mode| in the
......@@ -465,6 +490,9 @@ class NET_EXPORT TransportSecurityState
// True if static expect-CT state should be used.
bool enable_static_expect_ct_;
// True if static expect-staple state should be used.
bool enable_static_expect_staple_;
ExpectCTReporter* expect_ct_reporter_;
// Keeps track of reports that have been sent recently for
......
This diff is collapsed.
......@@ -211,7 +211,8 @@
{ "name": "pinningtest.appspot.com", "include_subdomains": true, "pins": "test" },
{ "name": "pinning-test.badssl.com", "include_subdomains": true, "pins": "test" },
{ "name": "preloaded-expect-ct.badssl.com", "expect_ct": true, "expect_ct_report_uri": "https://report.badssl.com/expect-ct" },
{ "name": "preloaded-expect-staple.badssl.com", "expect_staple": true, "expect_staple_report_uri": "https://report.badssl.com/expect-staple" },
{ "name": "preloaded-expect-staple-include-subdomains.badssl.com", "expect_staple": true, "expect_staple_report_uri": "https://report.badssl.com/expect-staple", "include_subdomains_for_expect_staple": true },
// Now we force HTTPS for subtrees of google.com.
{ "name": "accounts.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "admin.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
......@@ -45,6 +45,11 @@ 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";
const char kExpectStapleStaticHostname[] = "preloaded-expect-staple.badssl.com";
const char kExpectStapleStaticReportURI[] =
"https://report.badssl.com/expect-staple";
const char kExpectStapleStaticIncludeSubdomainsHostname[] =
"preloaded-expect-staple-include-subdomains.badssl.com";
// kGoodPath is blog.torproject.org.
const char* const kGoodPath[] = {
......@@ -246,6 +251,10 @@ class TransportSecurityStateTest : public testing::Test {
state->enable_static_expect_ct_ = true;
}
static void EnableStaticExpectStaple(TransportSecurityState* state) {
state->enable_static_expect_staple_ = true;
}
static HashValueVector GetSampleSPKIHashes() {
HashValueVector spki_hashes;
HashValue hash(HASH_VALUE_SHA256);
......@@ -267,6 +276,12 @@ class TransportSecurityStateTest : public testing::Test {
TransportSecurityState::ExpectCTState* result) {
return state->GetStaticExpectCTState(host, result);
}
bool GetExpectStapleState(TransportSecurityState* state,
const std::string& host,
TransportSecurityState::ExpectStapleState* result) {
return state->GetStaticExpectStapleState(host, result);
}
};
TEST_F(TransportSecurityStateTest, DomainNameOddities) {
......@@ -1667,6 +1682,38 @@ TEST_F(TransportSecurityStateTest, PreloadedExpectCT) {
GetExpectCTState(&state, "pinning-test.badssl.com", &expect_ct_state));
}
// Tests that static (preloaded) expect staple state is read correctly.
TEST_F(TransportSecurityStateTest, PreloadedExpectStaple) {
TransportSecurityState state;
TransportSecurityState::ExpectStapleState expect_staple_state;
EXPECT_FALSE(GetExpectStapleState(&state, kExpectStapleStaticHostname,
&expect_staple_state));
TransportSecurityStateTest::EnableStaticExpectStaple(&state);
EXPECT_TRUE(GetExpectStapleState(&state, kExpectStapleStaticHostname,
&expect_staple_state));
EXPECT_EQ(kExpectStapleStaticHostname, expect_staple_state.domain);
EXPECT_EQ(GURL(kExpectStapleStaticReportURI), expect_staple_state.report_uri);
EXPECT_FALSE(expect_staple_state.include_subdomains);
EXPECT_FALSE(GetExpectStapleState(&state, "pinning-test.badssl.com",
&expect_staple_state));
std::string subdomain = "subdomain.";
subdomain += kExpectStapleStaticHostname;
EXPECT_FALSE(GetExpectStapleState(&state, subdomain, &expect_staple_state));
}
TEST_F(TransportSecurityStateTest, PreloadedExpectStapleIncludeSubdomains) {
TransportSecurityState state;
TransportSecurityStateTest::EnableStaticExpectStaple(&state);
TransportSecurityState::ExpectStapleState expect_staple_state;
std::string subdomain = "subdomain.";
subdomain += kExpectStapleStaticIncludeSubdomainsHostname;
EXPECT_TRUE(GetExpectStapleState(&state, subdomain, &expect_staple_state));
EXPECT_EQ(kExpectStapleStaticIncludeSubdomainsHostname,
expect_staple_state.domain);
EXPECT_TRUE(expect_staple_state.include_subdomains);
EXPECT_EQ(GURL(kExpectStapleStaticReportURI), expect_staple_state.report_uri);
}
// Tests that the Expect CT reporter is not notified for invalid or absent
// header values.
TEST_F(TransportSecurityStateTest, InvalidExpectCTHeader) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment