1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/transport_security_persister.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h" 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/transport_security_state.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTransportSecurityPersister::TransportSecurityPersister(bool readonly) 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : ALLOW_THIS_IN_INITIALIZER_LIST(save_coalescer_(this)), 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen readonly_(readonly) { 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTransportSecurityPersister::~TransportSecurityPersister() { 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transport_security_state_->SetDelegate(NULL); 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TransportSecurityPersister::Initialize( 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::TransportSecurityState* state, const FilePath& profile_path) { 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transport_security_state_ = state; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch state_file_ = 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_path.Append(FILE_PATH_LITERAL("TransportSecurity")); 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch state->SetDelegate(this); 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Task* task = NewRunnableMethod(this, 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &TransportSecurityPersister::Load); 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, task, 1000); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TransportSecurityPersister::Load() { 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string state; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!file_util::ReadFileToString(state_file_, &state)) 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &TransportSecurityPersister::CompleteLoad, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch state)); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TransportSecurityPersister::CompleteLoad(const std::string& state) { 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool dirty = false; 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!transport_security_state_->LoadEntries(state, &dirty)) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Failed to deserialize state: " << state; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (dirty) 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StateIsDirty(transport_security_state_); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TransportSecurityPersister::StateIsDirty( 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::TransportSecurityState* state) { 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(state == transport_security_state_); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (readonly_) 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!save_coalescer_.empty()) 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Task* task = save_coalescer_.NewRunnableMethod( 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &TransportSecurityPersister::Save); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 1000); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TransportSecurityPersister::Save() { 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string state; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!transport_security_state_->Serialise(&state)) 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &TransportSecurityPersister::CompleteSave, 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch state)); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TransportSecurityPersister::CompleteSave(const std::string& state) { 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!readonly_); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::WriteFile(state_file_, state.data(), state.size()); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 97