Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / net / crl_set_fetcher.cc
blob9adaf7ff617888417869056e03bd3044fc0bb687
1 // Copyright (c) 2012 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/net/crl_set_fetcher.h"
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/numerics/safe_conversions.h"
10 #include "base/path_service.h"
11 #include "base/rand_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/component_updater/component_updater_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/chrome_constants.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "net/cert/crl_set.h"
20 #include "net/ssl/ssl_config_service.h"
22 using component_updater::ComponentUpdateService;
23 using content::BrowserThread;
25 CRLSetFetcher::CRLSetFetcher() : cus_(NULL) {}
27 bool CRLSetFetcher::GetCRLSetFilePath(base::FilePath* path) const {
28 bool ok = PathService::Get(chrome::DIR_USER_DATA, path);
29 if (!ok) {
30 NOTREACHED();
31 return false;
33 *path = path->Append(chrome::kCRLSetFilename);
34 return true;
37 void CRLSetFetcher::StartInitialLoad(ComponentUpdateService* cus) {
38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40 cus_ = cus;
42 if (!BrowserThread::PostTask(
43 BrowserThread::FILE, FROM_HERE,
44 base::Bind(&CRLSetFetcher::DoInitialLoadFromDisk, this))) {
45 NOTREACHED();
49 void CRLSetFetcher::DoInitialLoadFromDisk() {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
52 base::FilePath crl_set_file_path;
53 if (!GetCRLSetFilePath(&crl_set_file_path))
54 return;
56 LoadFromDisk(crl_set_file_path, &crl_set_);
58 uint32 sequence_of_loaded_crl = 0;
59 if (crl_set_.get())
60 sequence_of_loaded_crl = crl_set_->sequence();
62 // Get updates, advertising the sequence number of the CRL set that we just
63 // loaded, if any.
64 if (!BrowserThread::PostTask(
65 BrowserThread::UI, FROM_HERE,
66 base::Bind(
67 &CRLSetFetcher::RegisterComponent,
68 this,
69 sequence_of_loaded_crl))) {
70 NOTREACHED();
74 void CRLSetFetcher::LoadFromDisk(base::FilePath path,
75 scoped_refptr<net::CRLSet>* out_crl_set) {
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
78 std::string crl_set_bytes;
79 if (!base::ReadFileToString(path, &crl_set_bytes))
80 return;
82 if (!net::CRLSet::Parse(crl_set_bytes, out_crl_set)) {
83 LOG(WARNING) << "Failed to parse CRL set from " << path.MaybeAsASCII();
84 return;
87 VLOG(1) << "Loaded " << crl_set_bytes.size() << " bytes of CRL set from disk";
89 if (!BrowserThread::PostTask(
90 BrowserThread::IO, FROM_HERE,
91 base::Bind(
92 &CRLSetFetcher::SetCRLSetIfNewer, this, *out_crl_set))) {
93 NOTREACHED();
97 void CRLSetFetcher::SetCRLSetIfNewer(
98 scoped_refptr<net::CRLSet> crl_set) {
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
101 scoped_refptr<net::CRLSet> old_crl_set(net::SSLConfigService::GetCRLSet());
102 if (old_crl_set.get() && old_crl_set->sequence() > crl_set->sequence()) {
103 LOG(WARNING) << "Refusing to downgrade CRL set from #"
104 << old_crl_set->sequence()
105 << "to #"
106 << crl_set->sequence();
107 } else {
108 net::SSLConfigService::SetCRLSet(crl_set);
109 VLOG(1) << "Installed CRL set #" << crl_set->sequence();
113 // kPublicKeySHA256 is the SHA256 hash of the SubjectPublicKeyInfo of the key
114 // that's used to sign generated CRL sets.
115 static const uint8 kPublicKeySHA256[32] = {
116 0x75, 0xda, 0xf8, 0xcb, 0x77, 0x68, 0x40, 0x33,
117 0x65, 0x4c, 0x97, 0xe5, 0xc5, 0x1b, 0xcd, 0x81,
118 0x7b, 0x1e, 0xeb, 0x11, 0x2c, 0xe1, 0xa4, 0x33,
119 0x8c, 0xf5, 0x72, 0x5e, 0xed, 0xb8, 0x43, 0x97,
122 void CRLSetFetcher::RegisterComponent(uint32 sequence_of_loaded_crl) {
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 component_updater::CrxComponent component;
126 component.pk_hash.assign(kPublicKeySHA256,
127 kPublicKeySHA256 + sizeof(kPublicKeySHA256));
128 component.installer = this;
129 component.name = "CRLSet";
130 component.version = Version(base::UintToString(sequence_of_loaded_crl));
131 if (!component.version.IsValid()) {
132 NOTREACHED();
133 component.version = Version("0");
136 if (cus_->RegisterComponent(component) !=
137 ComponentUpdateService::kOk) {
138 NOTREACHED() << "RegisterComponent returned error";
142 void CRLSetFetcher::OnUpdateError(int error) {
143 LOG(WARNING) << "CRLSetFetcher got error " << error
144 << " from component installer";
147 bool CRLSetFetcher::Install(const base::DictionaryValue& manifest,
148 const base::FilePath& unpack_path) {
149 base::FilePath crl_set_file_path =
150 unpack_path.Append(FILE_PATH_LITERAL("crl-set"));
151 base::FilePath save_to;
152 if (!GetCRLSetFilePath(&save_to))
153 return true;
155 std::string crl_set_bytes;
156 if (!base::ReadFileToString(crl_set_file_path, &crl_set_bytes)) {
157 LOG(WARNING) << "Failed to find crl-set file inside CRX";
158 return false;
161 bool is_delta;
162 if (!net::CRLSet::GetIsDeltaUpdate(crl_set_bytes, &is_delta)) {
163 LOG(WARNING) << "GetIsDeltaUpdate failed on CRL set from update CRX";
164 return false;
167 if (!is_delta) {
168 if (!net::CRLSet::Parse(crl_set_bytes, &crl_set_)) {
169 LOG(WARNING) << "Failed to parse CRL set from update CRX";
170 return false;
172 int size = base::checked_cast<int>(crl_set_bytes.size());
173 if (file_util::WriteFile(save_to, crl_set_bytes.data(), size) != size) {
174 LOG(WARNING) << "Failed to save new CRL set to disk";
175 // We don't return false here because we can still use this CRL set. When
176 // we restart we might revert to an older version, then we'll
177 // advertise the older version to Omaha and everything will still work.
179 } else {
180 scoped_refptr<net::CRLSet> new_crl_set;
181 if (!crl_set_->ApplyDelta(crl_set_bytes, &new_crl_set)) {
182 LOG(WARNING) << "Failed to parse delta CRL set";
183 return false;
185 VLOG(1) << "Applied CRL set delta #" << crl_set_->sequence()
186 << "->#" << new_crl_set->sequence();
187 const std::string new_crl_set_bytes = new_crl_set->Serialize();
188 int size = base::checked_cast<int>(new_crl_set_bytes.size());
189 if (file_util::WriteFile(save_to, new_crl_set_bytes.data(), size) != size) {
190 LOG(WARNING) << "Failed to save new CRL set to disk";
191 // We don't return false here because we can still use this CRL set. When
192 // we restart we might revert to an older version, then we'll
193 // advertise the older version to Omaha and everything will still work.
195 crl_set_ = new_crl_set;
198 if (!BrowserThread::PostTask(
199 BrowserThread::IO, FROM_HERE,
200 base::Bind(
201 &CRLSetFetcher::SetCRLSetIfNewer, this, crl_set_))) {
202 NOTREACHED();
205 return true;
208 bool CRLSetFetcher::GetInstalledFile(
209 const std::string& file, base::FilePath* installed_file) {
210 return false;
213 CRLSetFetcher::~CRLSetFetcher() {}