Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / component_updater / ev_whitelist_component_installer.cc
blob57b5fe3e70ab5f58270ed68637caa247bd7a4837
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.
5 #include "chrome/browser/component_updater/ev_whitelist_component_installer.h"
7 #include <string>
8 #include <vector>
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/numerics/safe_conversions.h"
16 #include "base/path_service.h"
17 #include "base/version.h"
18 #include "components/component_updater/component_updater_paths.h"
19 #include "components/packed_ct_ev_whitelist/packed_ct_ev_whitelist.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "net/ssl/ssl_config_service.h"
23 using component_updater::ComponentUpdateService;
25 namespace {
26 const base::FilePath::CharType kCompressedEVWhitelistFileName[] =
27 FILE_PATH_LITERAL("ev_hashes_whitelist.bin");
29 base::FilePath GetEVWhitelistFilePath(const base::FilePath& base_path) {
30 return base_path.Append(kCompressedEVWhitelistFileName);
33 void UpdateNewWhitelistData(const base::FilePath& new_whitelist_file,
34 const base::FilePath& stored_whitelist_path,
35 const base::Version& version) {
36 VLOG(1) << "Reading new EV whitelist from file: "
37 << new_whitelist_file.value();
38 std::string compressed_list;
39 if (!base::ReadFileToString(new_whitelist_file, &compressed_list)) {
40 VLOG(1) << "Failed reading from " << new_whitelist_file.value();
41 return;
44 scoped_refptr<net::ct::EVCertsWhitelist> new_whitelist(
45 new packed_ct_ev_whitelist::PackedEVCertsWhitelist(compressed_list,
46 version));
47 if (!new_whitelist->IsValid()) {
48 VLOG(1) << "Failed uncompressing EV certs whitelist.";
49 return;
52 if (base::IsValueInRangeForNumericType<int>(compressed_list.size())) {
53 const int list_size = base::checked_cast<int>(compressed_list.size());
54 if (base::WriteFile(stored_whitelist_path, compressed_list.data(),
55 list_size) != list_size) {
56 LOG(WARNING) << "Failed to save new EV whitelist to file.";
60 packed_ct_ev_whitelist::SetEVCertsWhitelist(new_whitelist);
63 void DoInitialLoadFromDisk(const base::FilePath& stored_whitelist_path) {
64 if (stored_whitelist_path.empty()) {
65 return;
68 VLOG(1) << "Initial load: reading EV whitelist from file: "
69 << stored_whitelist_path.value();
70 std::string compressed_list;
71 if (!base::ReadFileToString(stored_whitelist_path, &compressed_list)) {
72 VLOG(1) << "Failed reading from " << stored_whitelist_path.value();
73 return;
76 // The version number is unknown as the list is loaded from disk, not
77 // the component.
78 // In practice very quickly the component updater will call ComponentReady
79 // which will have a valid version.
80 scoped_refptr<net::ct::EVCertsWhitelist> new_whitelist(
81 new packed_ct_ev_whitelist::PackedEVCertsWhitelist(compressed_list,
82 Version()));
83 if (!new_whitelist->IsValid()) {
84 VLOG(1) << "Failed uncompressing EV certs whitelist.";
85 return;
88 VLOG(1) << "EV whitelist: Sucessfully loaded initial data.";
89 packed_ct_ev_whitelist::SetEVCertsWhitelist(new_whitelist);
92 } // namespace
94 namespace component_updater {
96 // The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
97 // The extension id is: oafdbfcohdcjandcenmccfopbeklnicp
98 const uint8_t kPublicKeySHA256[32] = {
99 0xe0, 0x53, 0x15, 0x2e, 0x73, 0x29, 0x0d, 0x32, 0x4d, 0xc2, 0x25,
100 0xef, 0x14, 0xab, 0xd8, 0x2f, 0x84, 0xf5, 0x85, 0x9e, 0xc0, 0xfa,
101 0x94, 0xbc, 0x99, 0xc9, 0x5a, 0x27, 0x55, 0x19, 0x83, 0xef};
103 const char kEVWhitelistManifestName[] = "EV Certs CT whitelist";
105 EVWhitelistComponentInstallerTraits::EVWhitelistComponentInstallerTraits(
106 const base::FilePath& base_path)
107 : ev_whitelist_path_(GetEVWhitelistFilePath(base_path)) {
110 bool EVWhitelistComponentInstallerTraits::CanAutoUpdate() const {
111 return true;
114 bool EVWhitelistComponentInstallerTraits::OnCustomInstall(
115 const base::DictionaryValue& manifest,
116 const base::FilePath& install_dir) {
117 VLOG(1) << "Entering EVWhitelistComponentInstallerTraits::OnCustomInstall.";
119 return true; // Nothing custom here.
122 base::FilePath EVWhitelistComponentInstallerTraits::GetInstalledPath(
123 const base::FilePath& base) {
124 // EV whitelist is encoded the same way for all platforms
125 return base.Append(FILE_PATH_LITERAL("_platform_specific"))
126 .Append(FILE_PATH_LITERAL("all"))
127 .Append(kCompressedEVWhitelistFileName);
130 void EVWhitelistComponentInstallerTraits::ComponentReady(
131 const base::Version& version,
132 const base::FilePath& path,
133 scoped_ptr<base::DictionaryValue> manifest) {
134 VLOG(1) << "Component ready, version " << version.GetString() << " in "
135 << path.value();
137 const base::FilePath whitelist_file = GetInstalledPath(path);
138 content::BrowserThread::PostBlockingPoolTask(
139 FROM_HERE, base::Bind(&UpdateNewWhitelistData, whitelist_file,
140 ev_whitelist_path_, version));
143 bool EVWhitelistComponentInstallerTraits::VerifyInstallation(
144 const base::DictionaryValue& manifest,
145 const base::FilePath& install_dir) const {
146 const base::FilePath expected_file = GetInstalledPath(install_dir);
147 VLOG(1) << "Verifying install: " << expected_file.value();
148 if (!base::PathExists(expected_file)) {
149 VLOG(1) << "File missing.";
150 return false;
153 std::string compressed_whitelist;
154 if (!base::ReadFileToString(expected_file, &compressed_whitelist)) {
155 VLOG(1) << "Failed reading the compressed EV hashes whitelist.";
156 return false;
159 VLOG(1) << "Whitelist size: " << compressed_whitelist.size();
161 return !compressed_whitelist.empty();
164 base::FilePath EVWhitelistComponentInstallerTraits::GetBaseDirectory() const {
165 base::FilePath result;
166 PathService::Get(DIR_COMPONENT_EV_WHITELIST, &result);
167 return result;
170 void EVWhitelistComponentInstallerTraits::GetHash(
171 std::vector<uint8_t>* hash) const {
172 hash->assign(kPublicKeySHA256,
173 kPublicKeySHA256 + arraysize(kPublicKeySHA256));
176 std::string EVWhitelistComponentInstallerTraits::GetName() const {
177 return kEVWhitelistManifestName;
180 void RegisterEVWhitelistComponent(ComponentUpdateService* cus,
181 const base::FilePath& path) {
182 VLOG(1) << "Registering EV whitelist component.";
184 scoped_ptr<ComponentInstallerTraits> traits(
185 new EVWhitelistComponentInstallerTraits(path));
186 // |cus| will take ownership of |installer| during installer->Register(cus).
187 DefaultComponentInstaller* installer =
188 new DefaultComponentInstaller(traits.Pass());
189 installer->Register(cus, base::Closure());
191 if (!content::BrowserThread::PostBlockingPoolTask(
192 FROM_HERE,
193 base::Bind(&DoInitialLoadFromDisk, GetEVWhitelistFilePath(path)))) {
194 NOTREACHED();
198 } // namespace component_updater