Revert "Remove HTTP-Based Public Key Pinning header parsing and persistence code."

This reverts commit e211b725cdb2b5e0e7cb37f45f2126eb09780562.

Reason for revert:
This is failing NetworkContextTest.CertReporting test in service_unittests:
https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/linux-ozone-rel/36048
https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/Cast%20Audio%20Linux/22797

Original change's description:
> Remove HTTP-Based Public Key Pinning header parsing and persistence code.
> 
> And related code that uses it.
> 
> Cronet depends on the base dynamic PKP support, so is not removed here.
> 
> Based on https://crrev.com/c/1005960 by palmer & nharper.
> 
> Bug: 779166
> Cq-Include-Trybots: luci.chromium.try:linux_mojo
> Change-Id: I44044a3960174fcba1f1e120b18cbef3ff769812
> Reviewed-on: https://chromium-review.googlesource.com/c/1260483
> Reviewed-by: Tom Sepez <[email protected]>
> Reviewed-by: John Abd-El-Malek <[email protected]>
> Reviewed-by: Ryan Sleevi <[email protected]>
> Reviewed-by: Matt Menke <[email protected]>
> Commit-Queue: Ryan Sleevi <[email protected]>
> Cr-Commit-Position: refs/heads/master@{#598657}

[email protected],[email protected],[email protected],[email protected],[email protected]

Change-Id: Id7ee1c2284e1cd95ac48a92bfad3dfae58380822
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 779166
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Reviewed-on: https://chromium-review.googlesource.com/c/1275507
Reviewed-by: Hiroki Nakagawa <[email protected]>
Commit-Queue: Hiroki Nakagawa <[email protected]>
Cr-Commit-Position: refs/heads/master@{#598666}
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 1c19b377..ac22382 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -6636,13 +6636,13 @@
 
 namespace {
 const char kExpectCTStaticHostname[] = "expect-ct.preloaded.test";
-const char kPKPReportUri[] = "http://report-uri.preloaded.test/pkp";
-const char kPKPHost[] = "with-report-uri-pkp.preloaded.test";
+const char kHPKPReportUri[] = "https://hpkp-report.test";
 }  // namespace
 
-// Tests that reports get sent on PKP violations when a report-uri is set.
-TEST_F(URLRequestTestHTTP, ProcessPKPAndSendReport) {
-  GURL report_uri(kPKPReportUri);
+// Tests that enabling HPKP on a domain does not affect the HSTS
+// validity/expiration.
+TEST_F(URLRequestTestHTTP, ProcessPKP) {
+  GURL report_uri(kHPKPReportUri);
   EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_test_server.SetSSLConfig(
       net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
@@ -6650,12 +6650,61 @@
       base::FilePath(kTestFilePath));
   ASSERT_TRUE(https_test_server.Start());
 
-  std::string test_server_hostname = kPKPHost;
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
+
+  TestDelegate d;
+  std::unique_ptr<URLRequest> request(default_context().CreateRequest(
+      https_test_server.GetURL("/hpkp-headers.html"), DEFAULT_PRIORITY, &d,
+      TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+  TransportSecurityState* security_state =
+      default_context().transport_security_state();
+  TransportSecurityState::STSState sts_state;
+  TransportSecurityState::PKPState pkp_state;
+  EXPECT_FALSE(
+      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
+  EXPECT_TRUE(
+      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
+  EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
+            sts_state.upgrade_mode);
+  EXPECT_FALSE(sts_state.include_subdomains);
+  EXPECT_FALSE(pkp_state.include_subdomains);
+  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
+  EXPECT_EQ(report_uri, pkp_state.report_uri);
+  EXPECT_NE(sts_state.expiry, pkp_state.expiry);
+}
+
+// Tests that reports get sent on HPKP violations when a report-uri is set.
+TEST_F(URLRequestTestHTTP, ProcessPKPAndSendReport) {
+  GURL report_uri(kHPKPReportUri);
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.SetSSLConfig(
+      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
 
   // Set up a pin for |test_server_hostname|.
   TransportSecurityState security_state;
-  security_state.EnableStaticPinsForTesting();
-  SetTransportSecurityStateSourceForTesting(&test_default::kHSTSSource);
+  const base::Time current_time(base::Time::Now());
+  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+  HashValueVector hashes;
+  HashValue hash1;
+  HashValue hash2;
+  // The values here don't matter, as long as they are different from
+  // the mocked CertVerifyResult below.
+  ASSERT_TRUE(
+      hash1.FromString("sha256/1111111111111111111111111111111111111111111="));
+  ASSERT_TRUE(
+      hash2.FromString("sha256/2222222222222222222222222222222222222222222="));
+  hashes.push_back(hash1);
+  hashes.push_back(hash2);
+  security_state.AddHPKP(test_server_hostname, expiry,
+                         false, /* include subdomains */
+                         hashes, report_uri);
 
   MockCertificateReportSender mock_report_sender;
   security_state.SetReportSender(&mock_report_sender);
@@ -6685,7 +6734,72 @@
   // Now send a request to trigger the violation.
   TestDelegate d;
   std::unique_ptr<URLRequest> violating_request(context.CreateRequest(
-      https_test_server.GetURL(test_server_hostname, "/simple.html"),
+      https_test_server.GetURL("/simple.html"), DEFAULT_PRIORITY, &d,
+      TRAFFIC_ANNOTATION_FOR_TESTS));
+  violating_request->Start();
+  d.RunUntilComplete();
+
+  // Check that a report was sent.
+  EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
+  ASSERT_FALSE(mock_report_sender.latest_report().empty());
+  EXPECT_EQ("application/json; charset=utf-8",
+            mock_report_sender.latest_content_type());
+  std::unique_ptr<base::Value> value(
+      base::JSONReader::Read(mock_report_sender.latest_report()));
+  ASSERT_TRUE(value);
+  ASSERT_TRUE(value->is_dict());
+  base::DictionaryValue* report_dict;
+  ASSERT_TRUE(value->GetAsDictionary(&report_dict));
+  std::string report_hostname;
+  EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
+  EXPECT_EQ(test_server_hostname, report_hostname);
+}
+
+// Tests that reports get sent on requests with
+// Public-Key-Pins-Report-Only headers.
+TEST_F(URLRequestTestHTTP, ProcessPKPReportOnly) {
+  GURL report_uri(kHPKPReportUri);
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.SetSSLConfig(
+      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
+
+  TransportSecurityState security_state;
+  MockCertificateReportSender mock_report_sender;
+  security_state.SetReportSender(&mock_report_sender);
+
+  // Set up a MockCertVerifier to violate the pin in the Report-Only
+  // header.
+  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
+  ASSERT_TRUE(cert);
+
+  MockCertVerifier cert_verifier;
+  CertVerifyResult verify_result;
+  verify_result.verified_cert = cert;
+  verify_result.is_issued_by_known_root = true;
+  HashValue hash;
+  // This value doesn't matter, as long as it is different from the pins
+  // for the request to hpkp-headers-report-only.html.
+  ASSERT_TRUE(
+      hash.FromString("sha256/1111111111111111111111111111111111111111111="));
+  verify_result.public_key_hashes.push_back(hash);
+  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
+
+  TestNetworkDelegate network_delegate;
+  TestURLRequestContext context(true);
+  context.set_transport_security_state(&security_state);
+  context.set_network_delegate(&network_delegate);
+  context.set_cert_verifier(&cert_verifier);
+  context.Init();
+
+  // Now send a request to trigger the violation.
+  TestDelegate d;
+  std::unique_ptr<URLRequest> violating_request(context.CreateRequest(
+      https_test_server.GetURL("/hpkp-headers-report-only.html"),
       DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
   violating_request->Start();
   d.RunUntilComplete();
@@ -6706,9 +6820,10 @@
   EXPECT_EQ(test_server_hostname, report_hostname);
 }
 
-// Tests that reports do not get sent on requests to static pkp hosts that
-// don't have pin violations.
-TEST_F(URLRequestTestHTTP, ProcessPKPWithNoViolation) {
+// Tests that reports do not get sent on requests with
+// Public-Key-Pins-Report-Only headers that don't have pin violations.
+TEST_F(URLRequestTestHTTP, ProcessPKPReportOnlyWithNoViolation) {
+  GURL report_uri(kHPKPReportUri);
   EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_test_server.SetSSLConfig(
       net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
@@ -6716,53 +6831,56 @@
       base::FilePath(kTestFilePath));
   ASSERT_TRUE(https_test_server.Start());
 
-  std::string test_server_hostname = kPKPHost;
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
 
   TransportSecurityState security_state;
-  security_state.EnableStaticPinsForTesting();
-  SetTransportSecurityStateSourceForTesting(&test_default::kHSTSSource);
   MockCertificateReportSender mock_report_sender;
   security_state.SetReportSender(&mock_report_sender);
 
-  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
-  ASSERT_TRUE(cert);
-  MockCertVerifier mock_cert_verifier;
-  CertVerifyResult verify_result;
-  verify_result.verified_cert = cert;
-  verify_result.is_issued_by_known_root = true;
-  HashValue hash;
-  // The expected value of GoodPin1 used by |test_default::kHSTSSource|.
-  ASSERT_TRUE(
-      hash.FromString("sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
-  verify_result.public_key_hashes.push_back(hash);
-  mock_cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
-
   TestNetworkDelegate network_delegate;
+  MockCertVerifier mock_cert_verifier;
   TestURLRequestContext context(true);
   context.set_transport_security_state(&security_state);
   context.set_network_delegate(&network_delegate);
   context.set_cert_verifier(&mock_cert_verifier);
+  mock_cert_verifier.set_default_result(OK);
   context.Init();
 
   // Now send a request that does not trigger the violation.
   TestDelegate d;
   std::unique_ptr<URLRequest> request(context.CreateRequest(
-      https_test_server.GetURL(test_server_hostname, "/simple.html"),
+      https_test_server.GetURL("/hpkp-headers-report-only.html"),
       DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
   request->Start();
   d.RunUntilComplete();
 
-  // Check that the request succeeded, a report was not sent and the pkp was
-  // not bypassed.
-  EXPECT_EQ(OK, d.request_status());
+  // Check that a report was not sent.
   EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
   EXPECT_EQ(std::string(), mock_report_sender.latest_report());
-  TransportSecurityState::STSState sts_state;
+}
+
+TEST_F(URLRequestTestHTTP, PKPNotProcessedOnIP) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+  // Make sure this test fails if the test server is changed to not
+  // listen on an IP by default.
+  ASSERT_TRUE(https_test_server.GetURL("/").HostIsIPAddress());
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
+
+  TestDelegate d;
+  std::unique_ptr<URLRequest> request(default_context().CreateRequest(
+      https_test_server.GetURL("/hpkp-headers.html"), DEFAULT_PRIORITY, &d,
+      TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  TransportSecurityState* security_state =
+      default_context().transport_security_state();
   TransportSecurityState::PKPState pkp_state;
-  EXPECT_TRUE(security_state.GetStaticDomainState(test_server_hostname,
-                                                  &sts_state, &pkp_state));
-  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
-  EXPECT_FALSE(request->ssl_info().pkp_bypassed);
+  EXPECT_FALSE(
+      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
 }
 
 TEST_F(URLRequestTestHTTP, PKPBypassRecorded) {
@@ -6786,15 +6904,23 @@
       hash.FromString("sha256/1111111111111111111111111111111111111111111="));
   verify_result.public_key_hashes.push_back(hash);
   cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
+  cert_verifier.set_default_result(OK);
 
-  std::string test_server_hostname = kPKPHost;
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
 
-  // Set up PKP
+  // Set up HPKP
+  base::Time current_time = base::Time::Now();
+  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(10000);
+  HashValue pin;
+  ASSERT_TRUE(
+      pin.FromString("sha256/2222222222222222222222222222222222222222222="));
+  HashValueVector hashes;
+  hashes.push_back(pin);
+  GURL report_uri(kHPKPReportUri);
   TransportSecurityState security_state;
-  security_state.EnableStaticPinsForTesting();
-  SetTransportSecurityStateSourceForTesting(&test_default::kHSTSSource);
-  MockCertificateReportSender mock_report_sender;
-  security_state.SetReportSender(&mock_report_sender);
+  security_state.AddHPKP(test_server_hostname, expiry,
+                         false, /* include subdomains */
+                         hashes, report_uri);
 
   TestNetworkDelegate network_delegate;
   TestURLRequestContext context(true);
@@ -6805,21 +6931,14 @@
 
   TestDelegate d;
   std::unique_ptr<URLRequest> request(context.CreateRequest(
-      https_test_server.GetURL(test_server_hostname, "/simple.html"),
-      DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+      https_test_server.GetURL("/hpkp-headers.html"), DEFAULT_PRIORITY, &d,
+      TRAFFIC_ANNOTATION_FOR_TESTS));
   request->Start();
   d.RunUntilComplete();
 
-  // Check that the request succeeded, a report was not sent and the PKP was
-  // bypassed.
-  EXPECT_EQ(OK, d.request_status());
-  EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
-  EXPECT_EQ(std::string(), mock_report_sender.latest_report());
-  TransportSecurityState::STSState sts_state;
   TransportSecurityState::PKPState pkp_state;
-  EXPECT_TRUE(security_state.GetStaticDomainState(test_server_hostname,
-                                                  &sts_state, &pkp_state));
-  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
+  EXPECT_TRUE(
+      security_state.GetDynamicPKPState(test_server_hostname, &pkp_state));
   EXPECT_TRUE(request->ssl_info().pkp_bypassed);
 }
 
@@ -6852,6 +6971,88 @@
   EXPECT_FALSE(sts_state.include_subdomains);
 }
 
+TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.SetSSLConfig(
+      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
+
+  TestDelegate d;
+  std::unique_ptr<URLRequest> request(default_context().CreateRequest(
+      https_test_server.GetURL("/hsts-and-hpkp-headers.html"), DEFAULT_PRIORITY,
+      &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  // We should have set parameters from the first header, not the second.
+  TransportSecurityState* security_state =
+      default_context().transport_security_state();
+  TransportSecurityState::STSState sts_state;
+  TransportSecurityState::PKPState pkp_state;
+  EXPECT_TRUE(
+      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
+  EXPECT_TRUE(
+      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
+  EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
+            sts_state.upgrade_mode);
+#if defined(OS_ANDROID)
+  // Android's CertVerifyProc does not (yet) handle pins.
+#else
+  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
+#endif
+  EXPECT_NE(sts_state.expiry, pkp_state.expiry);
+
+  // Even though there is an HSTS header asserting includeSubdomains, it is
+  // the *second* such header, and we MUST process only the first.
+  EXPECT_FALSE(sts_state.include_subdomains);
+  // includeSubdomains does not occur in the test HPKP header.
+  EXPECT_FALSE(pkp_state.include_subdomains);
+}
+
+// Tests that when multiple HPKP headers are present, asserting different
+// policies, that only the first such policy is processed.
+TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.SetSSLConfig(
+      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+
+  std::string test_server_hostname = https_test_server.GetURL("/").host();
+
+  TestDelegate d;
+  std::unique_ptr<URLRequest> request(default_context().CreateRequest(
+      https_test_server.GetURL("/hsts-and-hpkp-headers2.html"),
+      DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  TransportSecurityState* security_state =
+      default_context().transport_security_state();
+  TransportSecurityState::STSState sts_state;
+  TransportSecurityState::PKPState pkp_state;
+  EXPECT_TRUE(
+      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
+  EXPECT_TRUE(
+      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
+  EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
+            sts_state.upgrade_mode);
+#if defined(OS_ANDROID)
+  // Android's CertVerifyProc does not (yet) handle pins.
+#else
+  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
+#endif
+  EXPECT_NE(sts_state.expiry, pkp_state.expiry);
+
+  EXPECT_TRUE(sts_state.include_subdomains);
+  EXPECT_FALSE(pkp_state.include_subdomains);
+}
+
 // An ExpectCTReporter that records the number of times OnExpectCTFailed() was
 // called.
 class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {