1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115

content / public / test / content_mock_cert_verifier.cc [blame]

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

#include "content/public/test/content_mock_cert_verifier.h"

#include "base/command_line.h"
#include "base/feature_list.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/network_service_util.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/network_service_test_helper.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "services/network/network_context.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_service.mojom.h"

namespace content {

ContentMockCertVerifier::CertVerifier::CertVerifier(
    net::MockCertVerifier* verifier)
    : verifier_(verifier) {}

ContentMockCertVerifier::CertVerifier::~CertVerifier() = default;

void ContentMockCertVerifier::CertVerifier::set_default_result(
    int default_result) {
  verifier_->set_default_result(default_result);

  // If set_default_result is called before the FeatureList is available, add
  // the command line flag since the network service may be running out of
  // process. We don't want to set the command line flag otherwise since it can
  // cause TSan errors.
  if (base::FeatureList::GetInstance() == nullptr) {
    // Set the default result as a flag in case the FeatureList has not been
    // initialized yet and we don't know if network service will run out of
    // process.
    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
        switches::kMockCertVerifierDefaultResultForTesting,
        base::NumberToString(default_result));
  }

  if (IsInProcessNetworkService())
    return;

  EnsureNetworkServiceTestInitialized();
  mojo::ScopedAllowSyncCallForTesting allow_sync_call;
  network_service_test_->MockCertVerifierSetDefaultResult(default_result);
}

void ContentMockCertVerifier::CertVerifier::AddResultForCert(
    scoped_refptr<net::X509Certificate> cert,
    const net::CertVerifyResult& verify_result,
    int rv) {
  AddResultForCertAndHost(cert, "*", verify_result, rv);
}

void ContentMockCertVerifier::CertVerifier::AddResultForCertAndHost(
    scoped_refptr<net::X509Certificate> cert,
    const std::string& host_pattern,
    const net::CertVerifyResult& verify_result,
    int rv) {
  verifier_->AddResultForCertAndHost(cert, host_pattern, verify_result, rv);

  if (IsInProcessNetworkService())
    return;

  EnsureNetworkServiceTestInitialized();
  mojo::ScopedAllowSyncCallForTesting allow_sync_call;
  network_service_test_->MockCertVerifierAddResultForCertAndHost(
      cert, host_pattern, verify_result, rv);
}

void ContentMockCertVerifier::CertVerifier::
    EnsureNetworkServiceTestInitialized() {
  if (!network_service_test_ || !network_service_test_.is_connected()) {
    network_service_test_.reset();
    GetNetworkService()->BindTestInterfaceForTesting(
        network_service_test_.BindNewPipeAndPassReceiver());
  }
  // TODO(crbug.com/41423903): Make sure the network process is started to avoid
  // a deadlock on Android.
  network_service_test_.FlushForTesting();
}

ContentMockCertVerifier::ContentMockCertVerifier()
    : mock_cert_verifier_(new net::MockCertVerifier()),
      cert_verifier_(mock_cert_verifier_.get()) {}

ContentMockCertVerifier::~ContentMockCertVerifier() {}

void ContentMockCertVerifier::SetUpCommandLine(
    base::CommandLine* command_line) {
  // Enable the MockCertVerifier in the network process via a switch. This is
  // because it's too early to call the service manager at this point (it's not
  // created yet), and by the time we can call the service manager in
  // SetUpOnMainThread the main profile has already been created.
  command_line->AppendSwitch(switches::kUseMockCertVerifierForTesting);
}

void ContentMockCertVerifier::SetUpInProcessBrowserTestFixture() {
  network::NetworkContext::SetCertVerifierForTesting(mock_cert_verifier_.get());
}

void ContentMockCertVerifier::TearDownInProcessBrowserTestFixture() {
  network::NetworkContext::SetCertVerifierForTesting(nullptr);
}

ContentMockCertVerifier::CertVerifier*
ContentMockCertVerifier::mock_cert_verifier() {
  return &cert_verifier_;
}

}  // namespace content