1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/login/owner_manager.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <string> 8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <vector> 9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/file_path.h" 11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/file_util.h" 12513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/browser_process.h" 134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/chromeos/boot_times_loader.h" 14513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_type.h" 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace chromeos { 20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenOwnerManager::OwnerManager() 22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : private_key_(NULL), 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public_key_(0), 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen utils_(OwnerKeyUtils::Create()) { 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenOwnerManager::~OwnerManager() {} 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid OwnerManager::UpdateOwnerKey(const BrowserThread::ID thread_id, 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<uint8>& key, 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen KeyUpdateDelegate* d) { 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public_key_ = key; 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen thread_id, FROM_HERE, 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, &OwnerManager::CallKeyUpdateDelegate, d)); 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid OwnerManager::LoadOwnerKey() { 424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("LoadOwnerKeyStart", false); 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Loading owner key"; 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NotificationType result = NotificationType::OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED; 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If |public_key_| isn't empty, we already have the key, so don't 48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // try to import again. 49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (public_key_.empty() && 50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen !utils_->ImportPublicKey(utils_->GetOwnerKeyFilePath(), &public_key_)) { 51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen result = NotificationType::OWNER_KEY_FETCH_ATTEMPT_FAILED; 52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Whether we loaded the public key or not, send a notification indicating 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // that we're done with this attempt. 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::UI, FROM_HERE, 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(this, 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &OwnerManager::SendNotification, 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen result, 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NotificationService::NoDetails())); 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool OwnerManager::EnsurePublicKey() { 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (public_key_.empty()) 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen LoadOwnerKey(); 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return !public_key_.empty(); 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool OwnerManager::EnsurePrivateKey() { 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!EnsurePublicKey()) 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!private_key_.get()) 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private_key_.reset(utils_->FindPrivateKey(public_key_)); 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return private_key_.get() != NULL; 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid OwnerManager::Sign(const BrowserThread::ID thread_id, 82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const std::string& data, 83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Delegate* d) { 844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("SignStart", false); 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If it's not the case that we can get both keys... 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!(EnsurePublicKey() && EnsurePrivateKey())) { 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen thread_id, FROM_HERE, 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(this, 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &OwnerManager::CallDelegate, 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen d, KEY_UNAVAILABLE, std::vector<uint8>())); 944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("SignEnd", false); 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Starting signing attempt"; 99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen KeyOpCode return_code = SUCCESS; 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::vector<uint8> signature; 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!utils_->Sign(data, &signature, private_key_.get())) { 102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return_code = OPERATION_FAILED; 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen thread_id, FROM_HERE, 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(this, 108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &OwnerManager::CallDelegate, 109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen d, return_code, signature)); 1104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("SignEnd", false); 111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid OwnerManager::Verify(const BrowserThread::ID thread_id, 114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const std::string& data, 115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const std::vector<uint8>& signature, 116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Delegate* d) { 1174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("VerifyStart", false); 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!EnsurePublicKey()) { 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen thread_id, FROM_HERE, 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(this, 124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &OwnerManager::CallDelegate, 125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen d, KEY_UNAVAILABLE, std::vector<uint8>())); 1264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("VerifyEnd", false); 127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Starting verify attempt"; 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen KeyOpCode return_code = SUCCESS; 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!utils_->Verify(data, signature, public_key_)) { 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return_code = OPERATION_FAILED; 134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen thread_id, FROM_HERE, 137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(this, 138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &OwnerManager::CallDelegate, 139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen d, return_code, std::vector<uint8>())); 1404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BootTimesLoader::Get()->AddLoginTimeMarker("VerifyEnd", false); 141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid OwnerManager::SendNotification(NotificationType type, 144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const NotificationDetails& details) { 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::current()->Notify( 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen type, 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::AllSources(), 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen details); 149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} // namespace chromeos 152