OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/transport_security_persister.h" | 5 #include "net/http/transport_security_persister.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 base::DictionaryValue toplevel; | 141 base::DictionaryValue toplevel; |
142 base::Time now = base::Time::Now(); | 142 base::Time now = base::Time::Now(); |
143 TransportSecurityState::Iterator state(*transport_security_state_); | 143 TransportSecurityState::Iterator state(*transport_security_state_); |
144 for (; state.HasNext(); state.Advance()) { | 144 for (; state.HasNext(); state.Advance()) { |
145 const std::string& hostname = state.hostname(); | 145 const std::string& hostname = state.hostname(); |
146 const TransportSecurityState::DomainState& domain_state = | 146 const TransportSecurityState::DomainState& domain_state = |
147 state.domain_state(); | 147 state.domain_state(); |
148 | 148 |
149 base::DictionaryValue* serialized = new base::DictionaryValue; | 149 base::DictionaryValue* serialized = new base::DictionaryValue; |
150 serialized->SetBoolean(kStsIncludeSubdomains, | 150 serialized->SetBoolean(kStsIncludeSubdomains, |
151 domain_state.sts_include_subdomains); | 151 domain_state.dynamic_sts.include_subdomains); |
152 serialized->SetBoolean(kPkpIncludeSubdomains, | 152 serialized->SetBoolean(kPkpIncludeSubdomains, |
153 domain_state.pkp_include_subdomains); | 153 domain_state.dynamic_pkp.include_subdomains); |
154 serialized->SetDouble(kStsObserved, domain_state.sts_observed.ToDoubleT()); | 154 serialized->SetDouble(kStsObserved, |
155 serialized->SetDouble(kPkpObserved, domain_state.pkp_observed.ToDoubleT()); | 155 domain_state.dynamic_sts.last_observed.ToDoubleT()); |
156 serialized->SetDouble(kExpiry, domain_state.upgrade_expiry.ToDoubleT()); | 156 serialized->SetDouble(kPkpObserved, |
157 domain_state.dynamic_pkp.last_observed.ToDoubleT()); | |
158 serialized->SetDouble(kExpiry, domain_state.dynamic_sts.expiry.ToDoubleT()); | |
157 serialized->SetDouble(kDynamicSPKIHashesExpiry, | 159 serialized->SetDouble(kDynamicSPKIHashesExpiry, |
158 domain_state.dynamic_spki_hashes_expiry.ToDoubleT()); | 160 domain_state.dynamic_pkp.expiry.ToDoubleT()); |
159 | 161 |
160 switch (domain_state.upgrade_mode) { | 162 switch (domain_state.dynamic_sts.upgrade_mode) { |
161 case TransportSecurityState::DomainState::MODE_FORCE_HTTPS: | 163 case TransportSecurityState::DomainState::MODE_FORCE_HTTPS: |
162 serialized->SetString(kMode, kForceHTTPS); | 164 serialized->SetString(kMode, kForceHTTPS); |
163 break; | 165 break; |
164 case TransportSecurityState::DomainState::MODE_DEFAULT: | 166 case TransportSecurityState::DomainState::MODE_DEFAULT: |
165 serialized->SetString(kMode, kDefault); | 167 serialized->SetString(kMode, kDefault); |
166 break; | 168 break; |
167 default: | 169 default: |
168 NOTREACHED() << "DomainState with unknown mode"; | 170 NOTREACHED() << "DomainState with unknown mode"; |
169 delete serialized; | 171 delete serialized; |
170 continue; | 172 continue; |
171 } | 173 } |
172 | 174 |
173 serialized->Set(kStaticSPKIHashes, | 175 serialized->Set(kStaticSPKIHashes, |
174 SPKIHashesToListValue(domain_state.static_spki_hashes)); | 176 SPKIHashesToListValue(domain_state.static_pkp.spki_hashes)); |
175 | 177 |
176 if (now < domain_state.dynamic_spki_hashes_expiry) { | 178 if (now < domain_state.dynamic_pkp.expiry) { |
177 serialized->Set(kDynamicSPKIHashes, | 179 serialized->Set(kDynamicSPKIHashes, |
178 SPKIHashesToListValue(domain_state.dynamic_spki_hashes)); | 180 SPKIHashesToListValue(domain_state.dynamic_pkp.spki_hashes)); |
179 } | 181 } |
180 | 182 |
181 toplevel.Set(HashedDomainToExternalString(hostname), serialized); | 183 toplevel.Set(HashedDomainToExternalString(hostname), serialized); |
182 } | 184 } |
183 | 185 |
184 base::JSONWriter::WriteWithOptions(&toplevel, | 186 base::JSONWriter::WriteWithOptions(&toplevel, |
185 base::JSONWriter::OPTIONS_PRETTY_PRINT, | 187 base::JSONWriter::OPTIONS_PRETTY_PRINT, |
186 output); | 188 output); |
187 return true; | 189 return true; |
188 } | 190 } |
(...skipping 30 matching lines...) Expand all Loading... | |
219 double expiry; | 221 double expiry; |
220 double dynamic_spki_hashes_expiry = 0.0; | 222 double dynamic_spki_hashes_expiry = 0.0; |
221 TransportSecurityState::DomainState domain_state; | 223 TransportSecurityState::DomainState domain_state; |
222 | 224 |
223 // kIncludeSubdomains is a legacy synonym for kStsIncludeSubdomains and | 225 // kIncludeSubdomains is a legacy synonym for kStsIncludeSubdomains and |
224 // kPkpIncludeSubdomains. Parse at least one of these properties, | 226 // kPkpIncludeSubdomains. Parse at least one of these properties, |
225 // preferably the new ones. | 227 // preferably the new ones. |
226 bool include_subdomains = false; | 228 bool include_subdomains = false; |
227 bool parsed_include_subdomains = parsed->GetBoolean(kIncludeSubdomains, | 229 bool parsed_include_subdomains = parsed->GetBoolean(kIncludeSubdomains, |
228 &include_subdomains); | 230 &include_subdomains); |
229 domain_state.sts_include_subdomains = include_subdomains; | 231 domain_state.dynamic_sts.include_subdomains = include_subdomains; |
230 domain_state.pkp_include_subdomains = include_subdomains; | 232 domain_state.dynamic_pkp.include_subdomains = include_subdomains; |
231 if (parsed->GetBoolean(kStsIncludeSubdomains, &include_subdomains)) { | 233 if (parsed->GetBoolean(kStsIncludeSubdomains, &include_subdomains)) { |
232 domain_state.sts_include_subdomains = include_subdomains; | 234 domain_state.dynamic_sts.include_subdomains = include_subdomains; |
233 parsed_include_subdomains = true; | 235 parsed_include_subdomains = true; |
234 } | 236 } |
235 if (parsed->GetBoolean(kPkpIncludeSubdomains, &include_subdomains)) { | 237 if (parsed->GetBoolean(kPkpIncludeSubdomains, &include_subdomains)) { |
236 domain_state.pkp_include_subdomains = include_subdomains; | 238 domain_state.dynamic_pkp.include_subdomains = include_subdomains; |
237 parsed_include_subdomains = true; | 239 parsed_include_subdomains = true; |
238 } | 240 } |
239 | 241 |
240 if (!parsed_include_subdomains || | 242 if (!parsed_include_subdomains || |
241 !parsed->GetString(kMode, &mode_string) || | 243 !parsed->GetString(kMode, &mode_string) || |
242 !parsed->GetDouble(kExpiry, &expiry)) { | 244 !parsed->GetDouble(kExpiry, &expiry)) { |
243 LOG(WARNING) << "Could not parse some elements of entry " << i.key() | 245 LOG(WARNING) << "Could not parse some elements of entry " << i.key() |
244 << "; skipping entry"; | 246 << "; skipping entry"; |
245 continue; | 247 continue; |
246 } | 248 } |
247 | 249 |
248 // Don't fail if this key is not present. | 250 // Don't fail if this key is not present. |
249 parsed->GetDouble(kDynamicSPKIHashesExpiry, | 251 parsed->GetDouble(kDynamicSPKIHashesExpiry, |
250 &dynamic_spki_hashes_expiry); | 252 &dynamic_spki_hashes_expiry); |
251 | 253 |
252 const base::ListValue* pins_list = NULL; | 254 const base::ListValue* pins_list = NULL; |
255 // TODO(palmer): crbug.com/339907: We should stop deserializing into the | |
256 // static set. | |
257 // | |
Ryan Sleevi
2014/03/07 01:39:19
comment nit:
// TODO(palmer): http://crbug.com/33
palmer
2014/03/14 21:33:39
Done.
| |
253 // preloaded_spki_hashes is a legacy synonym for static_spki_hashes. | 258 // preloaded_spki_hashes is a legacy synonym for static_spki_hashes. |
254 if (parsed->GetList(kStaticSPKIHashes, &pins_list)) | 259 if (parsed->GetList(kStaticSPKIHashes, &pins_list)) |
255 SPKIHashesFromListValue(*pins_list, &domain_state.static_spki_hashes); | 260 SPKIHashesFromListValue(*pins_list, &domain_state.static_pkp.spki_hashes); |
256 else if (parsed->GetList(kPreloadedSPKIHashes, &pins_list)) | 261 else if (parsed->GetList(kPreloadedSPKIHashes, &pins_list)) |
257 SPKIHashesFromListValue(*pins_list, &domain_state.static_spki_hashes); | 262 SPKIHashesFromListValue(*pins_list, &domain_state.static_pkp.spki_hashes); |
258 | 263 |
259 if (parsed->GetList(kDynamicSPKIHashes, &pins_list)) | 264 if (parsed->GetList(kDynamicSPKIHashes, &pins_list)) { |
260 SPKIHashesFromListValue(*pins_list, &domain_state.dynamic_spki_hashes); | 265 SPKIHashesFromListValue(*pins_list, |
266 &domain_state.dynamic_pkp.spki_hashes); | |
267 } | |
261 | 268 |
262 if (mode_string == kForceHTTPS || mode_string == kStrict) { | 269 if (mode_string == kForceHTTPS || mode_string == kStrict) { |
263 domain_state.upgrade_mode = | 270 domain_state.dynamic_sts.upgrade_mode = |
264 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; | 271 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
265 } else if (mode_string == kDefault || mode_string == kPinningOnly) { | 272 } else if (mode_string == kDefault || mode_string == kPinningOnly) { |
266 domain_state.upgrade_mode = | 273 domain_state.dynamic_sts.upgrade_mode = |
267 TransportSecurityState::DomainState::MODE_DEFAULT; | 274 TransportSecurityState::DomainState::MODE_DEFAULT; |
268 } else { | 275 } else { |
269 LOG(WARNING) << "Unknown TransportSecurityState mode string " | 276 LOG(WARNING) << "Unknown TransportSecurityState mode string " |
270 << mode_string << " found for entry " << i.key() | 277 << mode_string << " found for entry " << i.key() |
271 << "; skipping entry"; | 278 << "; skipping entry"; |
272 continue; | 279 continue; |
273 } | 280 } |
274 | 281 |
275 domain_state.upgrade_expiry = base::Time::FromDoubleT(expiry); | 282 domain_state.dynamic_sts.expiry = base::Time::FromDoubleT(expiry); |
276 domain_state.dynamic_spki_hashes_expiry = | 283 domain_state.dynamic_pkp.expiry = |
277 base::Time::FromDoubleT(dynamic_spki_hashes_expiry); | 284 base::Time::FromDoubleT(dynamic_spki_hashes_expiry); |
278 | 285 |
279 double sts_observed; | 286 double sts_observed; |
280 double pkp_observed; | 287 double pkp_observed; |
281 if (parsed->GetDouble(kStsObserved, &sts_observed)) { | 288 if (parsed->GetDouble(kStsObserved, &sts_observed)) { |
282 domain_state.sts_observed = base::Time::FromDoubleT(sts_observed); | 289 domain_state.dynamic_sts.last_observed = |
290 base::Time::FromDoubleT(sts_observed); | |
283 } else if (parsed->GetDouble(kCreated, &sts_observed)) { | 291 } else if (parsed->GetDouble(kCreated, &sts_observed)) { |
284 // kCreated is a legacy synonym for both kStsObserved and kPkpObserved. | 292 // kCreated is a legacy synonym for both kStsObserved and kPkpObserved. |
285 domain_state.sts_observed = base::Time::FromDoubleT(sts_observed); | 293 domain_state.dynamic_sts.last_observed = |
294 base::Time::FromDoubleT(sts_observed); | |
286 } else { | 295 } else { |
287 // We're migrating an old entry with no observation date. Make sure we | 296 // We're migrating an old entry with no observation date. Make sure we |
288 // write the new date back in a reasonable time frame. | 297 // write the new date back in a reasonable time frame. |
289 dirtied = true; | 298 dirtied = true; |
290 domain_state.sts_observed = base::Time::Now(); | 299 domain_state.dynamic_sts.last_observed = base::Time::Now(); |
291 } | 300 } |
292 if (parsed->GetDouble(kPkpObserved, &pkp_observed)) { | 301 if (parsed->GetDouble(kPkpObserved, &pkp_observed)) { |
293 domain_state.pkp_observed = base::Time::FromDoubleT(pkp_observed); | 302 domain_state.dynamic_pkp.last_observed = |
303 base::Time::FromDoubleT(pkp_observed); | |
294 } else if (parsed->GetDouble(kCreated, &pkp_observed)) { | 304 } else if (parsed->GetDouble(kCreated, &pkp_observed)) { |
295 domain_state.pkp_observed = base::Time::FromDoubleT(pkp_observed); | 305 domain_state.dynamic_pkp.last_observed = |
306 base::Time::FromDoubleT(pkp_observed); | |
296 } else { | 307 } else { |
297 dirtied = true; | 308 dirtied = true; |
298 domain_state.pkp_observed = base::Time::Now(); | 309 domain_state.dynamic_pkp.last_observed = base::Time::Now(); |
299 } | 310 } |
300 | 311 |
301 if (domain_state.upgrade_expiry <= current_time && | 312 if (domain_state.dynamic_sts.expiry <= current_time && |
302 domain_state.dynamic_spki_hashes_expiry <= current_time) { | 313 domain_state.dynamic_pkp.expiry <= current_time) { |
303 // Make sure we dirty the state if we drop an entry. | 314 // Make sure we dirty the state if we drop an entry. |
304 dirtied = true; | 315 dirtied = true; |
305 continue; | 316 continue; |
306 } | 317 } |
307 | 318 |
308 std::string hashed = ExternalStringToHashedDomain(i.key()); | 319 std::string hashed = ExternalStringToHashedDomain(i.key()); |
309 if (hashed.empty()) { | 320 if (hashed.empty()) { |
310 dirtied = true; | 321 dirtied = true; |
311 continue; | 322 continue; |
312 } | 323 } |
(...skipping 14 matching lines...) Expand all Loading... | |
327 bool dirty = false; | 338 bool dirty = false; |
328 if (!LoadEntries(state, &dirty)) { | 339 if (!LoadEntries(state, &dirty)) { |
329 LOG(ERROR) << "Failed to deserialize state: " << state; | 340 LOG(ERROR) << "Failed to deserialize state: " << state; |
330 return; | 341 return; |
331 } | 342 } |
332 if (dirty) | 343 if (dirty) |
333 StateIsDirty(transport_security_state_); | 344 StateIsDirty(transport_security_state_); |
334 } | 345 } |
335 | 346 |
336 } // namespace net | 347 } // namespace net |
OLD | NEW |