1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/component_updater/ev_whitelist_component_installer.h"
6
7#include <string>
8#include <vector>
9
10#include "base/bind.h"
11#include "base/files/file_path.h"
12#include "base/files/file_util.h"
13#include "base/lazy_instance.h"
14#include "base/logging.h"
15#include "base/path_service.h"
16#include "components/component_updater/component_updater_paths.h"
17#include "content/public/browser/browser_thread.h"
18#include "net/ssl/ssl_config_service.h"
19
20using component_updater::ComponentUpdateService;
21
22namespace {
23const base::FilePath::CharType kCompressedEVWhitelistFileName[] =
24    FILE_PATH_LITERAL("ev_hashes_whitelist.bin");
25}  // namespace
26
27namespace component_updater {
28
29// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
30// The extension id is: oafdbfcohdcjandcenmccfopbeklnicp
31const uint8_t kPublicKeySHA256[32] = {
32    0xe0, 0x53, 0x15, 0x2e, 0x73, 0x29, 0x0d, 0x32, 0x4d, 0xc2, 0x25,
33    0xef, 0x14, 0xab, 0xd8, 0x2f, 0x84, 0xf5, 0x85, 0x9e, 0xc0, 0xfa,
34    0x94, 0xbc, 0x99, 0xc9, 0x5a, 0x27, 0x55, 0x19, 0x83, 0xef};
35
36const char kEVWhitelistManifestName[] = "EV Certs CT whitelist";
37
38EVWhitelistComponentInstallerTraits::EVWhitelistComponentInstallerTraits() {
39}
40
41bool EVWhitelistComponentInstallerTraits::CanAutoUpdate() const {
42  return true;
43}
44
45bool EVWhitelistComponentInstallerTraits::OnCustomInstall(
46    const base::DictionaryValue& manifest,
47    const base::FilePath& install_dir) {
48  VLOG(1) << "Entering EVWhitelistComponentInstallerTraits::OnCustomInstall.";
49
50  return true;  // Nothing custom here.
51}
52
53base::FilePath EVWhitelistComponentInstallerTraits::GetInstalledPath(
54    const base::FilePath& base) {
55  // EV whitelist is encoded the same way for all platforms
56  return base.Append(FILE_PATH_LITERAL("_platform_specific"))
57      .Append(FILE_PATH_LITERAL("all"))
58      .Append(kCompressedEVWhitelistFileName);
59}
60
61void EVWhitelistComponentInstallerTraits::ComponentReady(
62    const base::Version& version,
63    const base::FilePath& path,
64    scoped_ptr<base::DictionaryValue> manifest) {
65  VLOG(1) << "Component ready, version " << version.GetString() << " in "
66          << path.value();
67
68  // TODO(eranm): Uncomment once https://codereview.chromium.org/462543002/
69  // is in.
70  /*
71  const base::FilePath whitelist_file = GetInstalledPath(path);
72  base::Callback<void(void)> set_cb =
73      base::Bind(&net::ct::SetEVWhitelistFromFile, whitelist_file);
74  content::BrowserThread::PostBlockingPoolTask(
75      FROM_HERE,
76      set_cb);
77      */
78}
79
80bool EVWhitelistComponentInstallerTraits::VerifyInstallation(
81    const base::FilePath& install_dir) const {
82  const base::FilePath expected_file = GetInstalledPath(install_dir);
83  VLOG(1) << "Verifying install: " << expected_file.value();
84  if (!base::PathExists(expected_file)) {
85    VLOG(1) << "File missing.";
86    return false;
87  }
88
89  std::string compressed_whitelist;
90  if (!base::ReadFileToString(expected_file, &compressed_whitelist)) {
91    VLOG(1) << "Failed reading the compressed EV hashes whitelist.";
92    return false;
93  }
94
95  VLOG(1) << "Whitelist size: " << compressed_whitelist.size();
96
97  return !compressed_whitelist.empty();
98}
99
100base::FilePath EVWhitelistComponentInstallerTraits::GetBaseDirectory() const {
101  base::FilePath result;
102  PathService::Get(DIR_COMPONENT_EV_WHITELIST, &result);
103  return result;
104}
105
106void EVWhitelistComponentInstallerTraits::GetHash(
107    std::vector<uint8_t>* hash) const {
108  hash->assign(kPublicKeySHA256,
109               kPublicKeySHA256 + arraysize(kPublicKeySHA256));
110}
111
112std::string EVWhitelistComponentInstallerTraits::GetName() const {
113  return kEVWhitelistManifestName;
114}
115
116void RegisterEVWhitelistComponent(ComponentUpdateService* cus) {
117  VLOG(1) << "Registering EV whitelist component.";
118
119  scoped_ptr<ComponentInstallerTraits> traits(
120      new EVWhitelistComponentInstallerTraits());
121  // |cus| will take ownership of |installer| during installer->Register(cus).
122  DefaultComponentInstaller* installer =
123      new DefaultComponentInstaller(traits.Pass());
124  installer->Register(cus);
125}
126
127}  // namespace component_updater
128