// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "content/browser/web_package/signed_exchange_handler.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/page_type.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_throttle.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/test_data_directory.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_interceptor.h"
#include "services/network/public/cpp/features.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"

namespace content {

namespace {

const uint64_t kSignatureHeaderDate = 1520834000;  // 2018-03-12T05:53:20Z

class NavigationFailureObserver : public WebContentsObserver {
 public:
  explicit NavigationFailureObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents) {}
  ~NavigationFailureObserver() override = default;

  void DidStartNavigation(NavigationHandle* handle) override {
    auto throttle = std::make_unique<TestNavigationThrottle>(handle);
    throttle->SetCallback(
        TestNavigationThrottle::WILL_FAIL_REQUEST,
        base::BindRepeating(&NavigationFailureObserver::OnWillFailRequestCalled,
                            base::Unretained(this)));
    handle->RegisterThrottleForTesting(
        std::unique_ptr<TestNavigationThrottle>(std::move(throttle)));
  }

  bool did_fail() const { return did_fail_; }

 private:
  void OnWillFailRequestCalled() { did_fail_ = true; }

  bool did_fail_ = false;

  DISALLOW_COPY_AND_ASSIGN(NavigationFailureObserver);
};

}  // namespace

class SignedExchangeRequestHandlerBrowserTest : public ContentBrowserTest {
 public:
  SignedExchangeRequestHandlerBrowserTest()
      : mock_cert_verifier_(std::make_unique<net::MockCertVerifier>()) {
    // This installs "root_ca_cert.pem" from which our test certificates are
    // created. (Needed for the tests that use real certificate, i.e.
    // RealCertVerifier)
    net::EmbeddedTestServer::RegisterTestCerts();
  }

  void SetUp() override {
    SignedExchangeHandler::SetCertVerifierForTesting(mock_cert_verifier_.get());
    SignedExchangeHandler::SetVerificationTimeForTesting(
        base::Time::UnixEpoch() +
        base::TimeDelta::FromSeconds(kSignatureHeaderDate));
    SetUpFeatures();
    ContentBrowserTest::SetUp();
  }

  void TearDownOnMainThread() override {
    interceptor_.reset();
    SignedExchangeHandler::SetCertVerifierForTesting(nullptr);
    SignedExchangeHandler::SetVerificationTimeForTesting(
        base::Optional<base::Time>());
  }

 protected:
  virtual void SetUpFeatures() {
    feature_list_.InitWithFeatures({features::kSignedHTTPExchange},
                                   {network::features::kNetworkService});
  }

  static scoped_refptr<net::X509Certificate> LoadCertificate(
      const std::string& cert_file) {
    base::ScopedAllowBlockingForTesting allow_io;
    base::FilePath dir_path;
    base::PathService::Get(content::DIR_TEST_DATA, &dir_path);
    dir_path = dir_path.AppendASCII("sxg");

    return net::CreateCertificateChainFromFile(
        dir_path, cert_file, net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
  }

  void InstallUrlInterceptor(const GURL& url, const std::string& data_path) {
    if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
      if (!interceptor_) {
        interceptor_ =
            std::make_unique<URLLoaderInterceptor>(base::BindRepeating(
                &SignedExchangeRequestHandlerBrowserTest::OnInterceptCallback,
                base::Unretained(this)));
      }
      interceptor_data_path_map_[url] = data_path;
    } else {
      BrowserThread::PostTask(
          BrowserThread::IO, FROM_HERE,
          base::BindOnce(&InstallMockInterceptors, url, data_path));
    }
  }

  base::test::ScopedFeatureList feature_list_;
  std::unique_ptr<net::MockCertVerifier> mock_cert_verifier_;

 private:
  static void InstallMockInterceptors(const GURL& url,
                                      const std::string& data_path) {
    DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
    base::FilePath root_path;
    CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &root_path));
    net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
        url, net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
                 root_path.AppendASCII(data_path)));
  }

  bool OnInterceptCallback(URLLoaderInterceptor::RequestParams* params) {
    DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
    const auto it = interceptor_data_path_map_.find(params->url_request.url);
    if (it == interceptor_data_path_map_.end())
      return false;
    URLLoaderInterceptor::WriteResponse(it->second, params->client.get());
    return true;
  }

  std::unique_ptr<URLLoaderInterceptor> interceptor_;
  std::map<GURL, std::string> interceptor_data_path_map_;

  DISALLOW_COPY_AND_ASSIGN(SignedExchangeRequestHandlerBrowserTest);
};

class SignedExchangeRequestHandlerWithNetworkServiceBrowserTest
    : public SignedExchangeRequestHandlerBrowserTest {
  void SetUpFeatures() override {
    feature_list_.InitWithFeatures(
        {features::kSignedHTTPExchange, network::features::kNetworkService},
        {});
  }
};

IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, Simple) {
  InstallUrlInterceptor(
      GURL("https://cert.example.org/cert.msg"),
      "content/test/data/sxg/test.example.org.public.pem.cbor");

  // Make the MockCertVerifier treat the certificate
  // "prime256v1-sha256.public.pem" as valid for "test.example.org".
  scoped_refptr<net::X509Certificate> original_cert =
      LoadCertificate("prime256v1-sha256.public.pem");
  net::CertVerifyResult dummy_result;
  dummy_result.verified_cert = original_cert;
  dummy_result.cert_status = net::OK;
  dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
  dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
  mock_cert_verifier_->AddResultForCertAndHost(
      original_cert, "test.example.org", dummy_result, net::OK);

  embedded_test_server()->RegisterRequestMonitor(
      base::BindRepeating([](const net::test_server::HttpRequest& request) {
        if (request.relative_url == "/sxg/test.example.org_test.sxg") {
          const auto& accept_value = request.headers.find("accept")->second;
          EXPECT_THAT(accept_value,
                      ::testing::HasSubstr("application/signed-exchange;v=b1"));
        }
      }));
  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
  base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
  TitleWatcher title_watcher(shell()->web_contents(), title);
  NavigateToURL(shell(), url);
  EXPECT_EQ(title, title_watcher.WaitAndGetTitle());

  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetVisibleEntry();
  EXPECT_TRUE(entry->GetSSL().initialized);
  EXPECT_FALSE(!!(entry->GetSSL().content_status &
                  SSLStatus::DISPLAYED_INSECURE_CONTENT));
  ASSERT_TRUE(entry->GetSSL().certificate);

  // "test.example.org.public.pem.cbor" is generated from
  // "prime256v1-sha256.public.pem". So the SHA256 of the certificates must
  // match.
  const net::SHA256HashValue fingerprint =
      net::X509Certificate::CalculateFingerprint256(
          entry->GetSSL().certificate->cert_buffer());
  const net::SHA256HashValue original_fingerprint =
      net::X509Certificate::CalculateFingerprint256(
          original_cert->cert_buffer());
  EXPECT_EQ(original_fingerprint, fingerprint);
}

IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
                       InvalidContentType) {
  InstallUrlInterceptor(
      GURL("https://cert.example.org/cert.msg"),
      "content/test/data/sxg/test.example.org.public.pem.cbor");

  // Make the MockCertVerifier treat the certificate
  // "prime256v1-sha256.public.pem" as valid for "test.example.org".
  scoped_refptr<net::X509Certificate> original_cert =
      LoadCertificate("prime256v1-sha256.public.pem");
  net::CertVerifyResult dummy_result;
  dummy_result.verified_cert = original_cert;
  dummy_result.cert_status = net::OK;
  dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
  dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
  mock_cert_verifier_->AddResultForCertAndHost(
      original_cert, "test.example.org", dummy_result, net::OK);

  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url = embedded_test_server()->GetURL(
      "/sxg/test.example.org_test_invalid_content_type.sxg");

  NavigationFailureObserver failure_observer(shell()->web_contents());
  NavigateToURL(shell(), url);
  EXPECT_TRUE(failure_observer.did_fail());
  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetVisibleEntry();
  EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
}

IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, CertNotFound) {
  InstallUrlInterceptor(GURL("https://cert.example.org/cert.msg"),
                        "content/test/data/sxg/404.msg");

  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");

  NavigationFailureObserver failure_observer(shell()->web_contents());
  NavigateToURL(shell(), url);
  EXPECT_TRUE(failure_observer.did_fail());
  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetVisibleEntry();
  EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
}

IN_PROC_BROWSER_TEST_F(
    SignedExchangeRequestHandlerWithNetworkServiceBrowserTest,
    NetworkServiceEnabled) {
  InstallUrlInterceptor(
      GURL("https://test.example.org/cert.msg"),
      "content/test/data/sxg/test.example.org.public.pem.cbor");

  // Make the MockCertVerifier treat the certificate
  // "prime256v1-sha256.public.pem" as valid for "test.example.org".
  scoped_refptr<net::X509Certificate> original_cert =
      LoadCertificate("prime256v1-sha256.public.pem");
  net::CertVerifyResult dummy_result;
  dummy_result.verified_cert = original_cert;
  dummy_result.cert_status = net::OK;
  dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
  dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
  mock_cert_verifier_->AddResultForCertAndHost(
      original_cert, "test.example.org", dummy_result, net::OK);

  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");

  NavigationFailureObserver failure_observer(shell()->web_contents());
  NavigateToURL(shell(), url);
  EXPECT_TRUE(failure_observer.did_fail());
  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetVisibleEntry();
  EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
}

IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
                       RealCertVerifier) {
  InstallUrlInterceptor(
      GURL("https://cert.example.org/cert.msg"),
      "content/test/data/sxg/test.example.org.public.pem.cbor");

  // Use "real" CertVerifier.
  SignedExchangeHandler::SetCertVerifierForTesting(nullptr);

  embedded_test_server()->RegisterRequestMonitor(
      base::BindRepeating([](const net::test_server::HttpRequest& request) {
        if (request.relative_url == "/sxg/test.example.org_test.sxg") {
          const auto& accept_value = request.headers.find("accept")->second;
          EXPECT_THAT(accept_value,
                      ::testing::HasSubstr("application/signed-exchange;v=b1"));
        }
      }));
  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");

  // "test.example.org_test.sxg" should pass CertVerifier::Verify() and then
  // fail at SignedExchangeHandler::CheckOCSPStatus() because of the dummy OCSP
  // response.
  // TODO(https://crbug.com/815024): Make this test pass the OCSP check. We'll
  // need to either generate an OCSP response on the fly, or override the OCSP
  // verification time.
  content::ConsoleObserverDelegate console_observer(shell()->web_contents(),
                                                    "*OCSP*");
  shell()->web_contents()->SetDelegate(&console_observer);

  NavigationFailureObserver failure_observer(shell()->web_contents());
  NavigateToURL(shell(), url);
  EXPECT_TRUE(failure_observer.did_fail());
  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetVisibleEntry();
  EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());

  // Verify that it failed at the OCSP check step.
  // TODO(https://crbug.com/803774): Find a better way than matching against the
  // error message. We can probably make DevToolsProxy derive some context from
  // StoragePartition so that we can record and extract the detailed error
  // status for testing via that.
  console_observer.Wait();
  EXPECT_TRUE(base::StartsWith(console_observer.message(), "OCSP check failed.",
                               base::CompareCase::SENSITIVE));
}

}  // namespace content
