summaryrefslogtreecommitdiffstats
path: root/chrome/browser/component_updater/ev_whitelist_component_installer.cc
blob: aba62c556da8ed679dcb1f782b2500f5a5a9bab8 (plain)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2014 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 "chrome/browser/component_updater/ev_whitelist_component_installer.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/version.h"
#include "components/component_updater/component_updater_paths.h"
#include "components/packed_ct_ev_whitelist/packed_ct_ev_whitelist.h"
#include "content/public/browser/browser_thread.h"

using component_updater::ComponentUpdateService;

namespace {
const base::FilePath::CharType kCompressedEVWhitelistFileName[] =
    FILE_PATH_LITERAL("ev_hashes_whitelist.bin");

// Prior implementations (< M46) of this installer would copy the whitelist
// file from the installed component directory to the top of the user data
// directory which is not necessary. Delete this unused file.
// todo(cmumford): Delete this function >= M50.
void DeleteWhitelistCopy(const base::FilePath& user_data_dir) {
  base::DeleteFile(user_data_dir.Append(kCompressedEVWhitelistFileName), false);
}

void LoadWhitelistFromDisk(const base::FilePath& whitelist_path,
                           const base::Version& version) {
  if (whitelist_path.empty())
    return;

  VLOG(1) << "Reading EV whitelist from file: " << whitelist_path.value();
  std::string compressed_list;
  if (!base::ReadFileToString(whitelist_path, &compressed_list)) {
    VLOG(1) << "Failed reading from " << whitelist_path.value();
    return;
  }

  scoped_refptr<net::ct::EVCertsWhitelist> new_whitelist(
      new packed_ct_ev_whitelist::PackedEVCertsWhitelist(compressed_list,
                                                         version));
  compressed_list.clear();
  if (!new_whitelist->IsValid()) {
    VLOG(1) << "Failed uncompressing EV certs whitelist.";
    return;
  }

  VLOG(0) << "EV whitelist: Successfully loaded.";
  packed_ct_ev_whitelist::SetEVCertsWhitelist(new_whitelist);
}

}  // namespace

namespace component_updater {

// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
// The extension id is: oafdbfcohdcjandcenmccfopbeklnicp
const uint8_t kPublicKeySHA256[32] = {
    0xe0, 0x53, 0x15, 0x2e, 0x73, 0x29, 0x0d, 0x32, 0x4d, 0xc2, 0x25,
    0xef, 0x14, 0xab, 0xd8, 0x2f, 0x84, 0xf5, 0x85, 0x9e, 0xc0, 0xfa,
    0x94, 0xbc, 0x99, 0xc9, 0x5a, 0x27, 0x55, 0x19, 0x83, 0xef};

const char kEVWhitelistManifestName[] = "EV Certs CT whitelist";

bool EVWhitelistComponentInstallerTraits::CanAutoUpdate() const {
  return true;
}

bool EVWhitelistComponentInstallerTraits::OnCustomInstall(
    const base::DictionaryValue& manifest,
    const base::FilePath& install_dir) {
  VLOG(1) << "Entering EVWhitelistComponentInstallerTraits::OnCustomInstall.";

  return true;  // Nothing custom here.
}

base::FilePath EVWhitelistComponentInstallerTraits::GetInstalledPath(
    const base::FilePath& base) {
  // EV whitelist is encoded the same way for all platforms
  return base.Append(FILE_PATH_LITERAL("_platform_specific"))
      .Append(FILE_PATH_LITERAL("all"))
      .Append(kCompressedEVWhitelistFileName);
}

void EVWhitelistComponentInstallerTraits::ComponentReady(
    const base::Version& version,
    const base::FilePath& install_dir,
    scoped_ptr<base::DictionaryValue> manifest) {
  VLOG(0) << "Component ready, version " << version.GetString() << " in "
          << install_dir.value();

  if (!content::BrowserThread::PostBlockingPoolTask(
          FROM_HERE, base::Bind(&LoadWhitelistFromDisk,
                                GetInstalledPath(install_dir), version))) {
    NOTREACHED();
  }
}

// Called during startup and installation before ComponentReady().
bool EVWhitelistComponentInstallerTraits::VerifyInstallation(
    const base::DictionaryValue& manifest,
    const base::FilePath& install_dir) const {
  return base::PathExists(GetInstalledPath(install_dir));
}

base::FilePath EVWhitelistComponentInstallerTraits::GetBaseDirectory() const {
  base::FilePath result;
  PathService::Get(DIR_COMPONENT_EV_WHITELIST, &result);
  return result;
}

void EVWhitelistComponentInstallerTraits::GetHash(
    std::vector<uint8_t>* hash) const {
  hash->assign(kPublicKeySHA256,
               kPublicKeySHA256 + arraysize(kPublicKeySHA256));
}

std::string EVWhitelistComponentInstallerTraits::GetName() const {
  return kEVWhitelistManifestName;
}

void RegisterEVWhitelistComponent(ComponentUpdateService* cus,
                                  const base::FilePath& user_data_dir) {
  VLOG(1) << "Registering EV whitelist component.";

  scoped_ptr<ComponentInstallerTraits> traits(
      new EVWhitelistComponentInstallerTraits());
  // |cus| will take ownership of |installer| during installer->Register(cus).
  DefaultComponentInstaller* installer =
      new DefaultComponentInstaller(traits.Pass());
  installer->Register(cus, base::Closure());

  content::BrowserThread::PostAfterStartupTask(
      FROM_HERE, content::BrowserThread::GetBlockingPool(),
      base::Bind(&DeleteWhitelistCopy, user_data_dir));
}

}  // namespace component_updater