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. 4 5 #include "chrome/browser/chromeos/ownership/owner_settings_service.h" 6 7 #include <string> 8 9 #include "base/bind.h" 10 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/chromeos/login/users/user.h" 12 #include "chrome/browser/chromeos/login/users/user_manager.h" 13 #include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" 14 #include "chrome/browser/chromeos/profiles/profile_helper.h" 15 #include "chrome/browser/profiles/profile.h" 16 #include "chromeos/dbus/dbus_thread_manager.h" 17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/notification_details.h" 19 #include "content/public/browser/notification_source.h" 20 #include "crypto/nss_util.h" 21 #include "crypto/nss_util_internal.h" 22 #include "crypto/rsa_private_key.h" 23 #include "crypto/scoped_nss_types.h" 24 #include "crypto/signature_creator.h" 25 26 namespace em = enterprise_management; 27 28 using content::BrowserThread; 29 30 namespace chromeos { 31 32 namespace { 33 34 scoped_refptr<OwnerKeyUtil>* g_owner_key_util_for_testing = NULL; 35 DeviceSettingsService* g_device_settings_service_for_testing = NULL; 36 37 std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy, 38 crypto::RSAPrivateKey* private_key) { 39 // Assemble the policy. 40 em::PolicyFetchResponse policy_response; 41 if (!policy->SerializeToString(policy_response.mutable_policy_data())) { 42 LOG(ERROR) << "Failed to encode policy payload."; 43 return std::string(); 44 } 45 46 // Generate the signature. 47 scoped_ptr<crypto::SignatureCreator> signature_creator( 48 crypto::SignatureCreator::Create(private_key)); 49 signature_creator->Update( 50 reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()), 51 policy_response.policy_data().size()); 52 std::vector<uint8> signature_bytes; 53 std::string policy_blob; 54 if (!signature_creator->Final(&signature_bytes)) { 55 LOG(ERROR) << "Failed to create policy signature."; 56 return std::string(); 57 } 58 59 policy_response.mutable_policy_data_signature()->assign( 60 reinterpret_cast<const char*>(vector_as_array(&signature_bytes)), 61 signature_bytes.size()); 62 return policy_response.SerializeAsString(); 63 } 64 65 void LoadPrivateKeyByPublicKey( 66 const scoped_refptr<OwnerKeyUtil>& owner_key_util, 67 const std::vector<uint8>& public_key, 68 const std::string& username_hash, 69 const base::Callback<void(scoped_ptr<crypto::RSAPrivateKey>)>& callback) { 70 crypto::EnsureNSSInit(); 71 crypto::ScopedPK11Slot slot = 72 crypto::GetPublicSlotForChromeOSUser(username_hash); 73 scoped_ptr<crypto::RSAPrivateKey> key( 74 owner_key_util->FindPrivateKeyInSlot(public_key, slot.get())); 75 BrowserThread::PostTask( 76 BrowserThread::UI, FROM_HERE, base::Bind(callback, base::Passed(&key))); 77 } 78 79 void LoadPrivateKey( 80 const scoped_refptr<OwnerKeyUtil>& owner_key_util, 81 const std::string username_hash, 82 const base::Callback<void(scoped_ptr<crypto::RSAPrivateKey>)>& callback) { 83 std::vector<uint8> public_key; 84 if (!owner_key_util->ImportPublicKey(&public_key)) { 85 scoped_ptr<crypto::RSAPrivateKey> result; 86 BrowserThread::PostTask(BrowserThread::UI, 87 FROM_HERE, 88 base::Bind(callback, base::Passed(&result))); 89 return; 90 } 91 bool rv = BrowserThread::PostTask(BrowserThread::IO, 92 FROM_HERE, 93 base::Bind(&LoadPrivateKeyByPublicKey, 94 owner_key_util, 95 public_key, 96 username_hash, 97 callback)); 98 if (!rv) { 99 // IO thread doesn't exists in unit tests, but it's safe to use NSS from 100 // BlockingPool in unit tests. 101 LoadPrivateKeyByPublicKey( 102 owner_key_util, public_key, username_hash, callback); 103 } 104 } 105 106 bool IsPrivateKeyExistAsyncHelper( 107 const scoped_refptr<OwnerKeyUtil>& owner_key_util) { 108 std::vector<uint8> public_key; 109 if (!owner_key_util->ImportPublicKey(&public_key)) 110 return false; 111 scoped_ptr<crypto::RSAPrivateKey> key( 112 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key)); 113 bool is_owner = key.get() != NULL; 114 return is_owner; 115 } 116 117 } // namespace 118 119 OwnerSettingsService::OwnerSettingsService(Profile* profile) 120 : profile_(profile), 121 owner_key_util_(OwnerKeyUtil::Create()), 122 waiting_for_profile_creation_(true), 123 waiting_for_tpm_token_(true), 124 weak_factory_(this) { 125 if (TPMTokenLoader::IsInitialized()) { 126 waiting_for_tpm_token_ = !TPMTokenLoader::Get()->IsTPMTokenReady(); 127 TPMTokenLoader::Get()->AddObserver(this); 128 } 129 130 if (DBusThreadManager::IsInitialized() && 131 DBusThreadManager::Get()->GetSessionManagerClient()) { 132 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); 133 } 134 135 registrar_.Add(this, 136 chrome::NOTIFICATION_PROFILE_CREATED, 137 content::Source<Profile>(profile_)); 138 } 139 140 OwnerSettingsService::~OwnerSettingsService() { 141 DCHECK(thread_checker_.CalledOnValidThread()); 142 if (TPMTokenLoader::IsInitialized()) 143 TPMTokenLoader::Get()->RemoveObserver(this); 144 145 if (DBusThreadManager::IsInitialized() && 146 DBusThreadManager::Get()->GetSessionManagerClient()) { 147 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); 148 } 149 } 150 151 bool OwnerSettingsService::IsOwner() { 152 DCHECK(thread_checker_.CalledOnValidThread()); 153 return private_key_ && private_key_->key(); 154 } 155 156 void OwnerSettingsService::IsOwnerAsync(const IsOwnerCallback& callback) { 157 DCHECK(thread_checker_.CalledOnValidThread()); 158 if (private_key_) { 159 base::MessageLoop::current()->PostTask(FROM_HERE, 160 base::Bind(callback, IsOwner())); 161 } else { 162 pending_is_owner_callbacks_.push_back(callback); 163 } 164 } 165 166 bool OwnerSettingsService::AssembleAndSignPolicyAsync( 167 scoped_ptr<enterprise_management::PolicyData> policy, 168 const AssembleAndSignPolicyCallback& callback) { 169 DCHECK(thread_checker_.CalledOnValidThread()); 170 if (!IsOwner()) 171 return false; 172 base::PostTaskAndReplyWithResult( 173 BrowserThread::GetBlockingPool(), 174 FROM_HERE, 175 base::Bind( 176 &AssembleAndSignPolicy, base::Passed(&policy), private_key_->key()), 177 callback); 178 return true; 179 } 180 181 void OwnerSettingsService::Observe( 182 int type, 183 const content::NotificationSource& source, 184 const content::NotificationDetails& details) { 185 DCHECK(thread_checker_.CalledOnValidThread()); 186 if (type != chrome::NOTIFICATION_PROFILE_CREATED) { 187 NOTREACHED(); 188 return; 189 } 190 191 Profile* profile = content::Source<Profile>(source).ptr(); 192 if (profile != profile_) { 193 NOTREACHED(); 194 return; 195 } 196 197 waiting_for_profile_creation_ = false; 198 ReloadPrivateKey(); 199 } 200 201 void OwnerSettingsService::OnTPMTokenReady() { 202 DCHECK(thread_checker_.CalledOnValidThread()); 203 waiting_for_tpm_token_ = false; 204 205 // TPMTokenLoader initializes the TPM and NSS database which is necessary to 206 // determine ownership. Force a reload once we know these are initialized. 207 ReloadPrivateKey(); 208 } 209 210 void OwnerSettingsService::OwnerKeySet(bool success) { 211 DCHECK(thread_checker_.CalledOnValidThread()); 212 if (success) 213 ReloadPrivateKey(); 214 } 215 216 // static 217 void OwnerSettingsService::IsPrivateKeyExistAsync( 218 const IsOwnerCallback& callback) { 219 scoped_refptr<OwnerKeyUtil> owner_key_util; 220 if (g_owner_key_util_for_testing) 221 owner_key_util = *g_owner_key_util_for_testing; 222 else 223 owner_key_util = OwnerKeyUtil::Create(); 224 scoped_refptr<base::TaskRunner> task_runner = 225 content::BrowserThread::GetBlockingPool() 226 ->GetTaskRunnerWithShutdownBehavior( 227 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 228 base::PostTaskAndReplyWithResult( 229 task_runner.get(), 230 FROM_HERE, 231 base::Bind(&IsPrivateKeyExistAsyncHelper, owner_key_util), 232 callback); 233 } 234 235 // static 236 void OwnerSettingsService::SetOwnerKeyUtilForTesting( 237 const scoped_refptr<OwnerKeyUtil>& owner_key_util) { 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 239 if (g_owner_key_util_for_testing) { 240 delete g_owner_key_util_for_testing; 241 g_owner_key_util_for_testing = NULL; 242 } 243 if (owner_key_util.get()) { 244 g_owner_key_util_for_testing = new scoped_refptr<OwnerKeyUtil>(); 245 *g_owner_key_util_for_testing = owner_key_util; 246 } 247 } 248 249 // static 250 void OwnerSettingsService::SetDeviceSettingsServiceForTesting( 251 DeviceSettingsService* device_settings_service) { 252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 253 g_device_settings_service_for_testing = device_settings_service; 254 } 255 256 void OwnerSettingsService::ReloadPrivateKey() { 257 DCHECK(thread_checker_.CalledOnValidThread()); 258 if (waiting_for_profile_creation_ || waiting_for_tpm_token_) 259 return; 260 scoped_refptr<base::TaskRunner> task_runner = 261 content::BrowserThread::GetBlockingPool() 262 ->GetTaskRunnerWithShutdownBehavior( 263 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 264 task_runner->PostTask( 265 FROM_HERE, 266 base::Bind(&LoadPrivateKey, 267 GetOwnerKeyUtil(), 268 ProfileHelper::GetUserIdHashFromProfile(profile_), 269 base::Bind(&OwnerSettingsService::OnPrivateKeyLoaded, 270 weak_factory_.GetWeakPtr()))); 271 } 272 273 void OwnerSettingsService::OnPrivateKeyLoaded( 274 scoped_ptr<crypto::RSAPrivateKey> private_key) { 275 DCHECK(thread_checker_.CalledOnValidThread()); 276 private_key_ = new PrivateKey(private_key.release()); 277 278 const std::string& user_id = profile_->GetProfileName(); 279 if (user_id == OwnerSettingsServiceFactory::GetInstance()->GetUsername()) 280 GetDeviceSettingsService()->InitOwner(user_id, weak_factory_.GetWeakPtr()); 281 282 std::vector<IsOwnerCallback> is_owner_callbacks; 283 is_owner_callbacks.swap(pending_is_owner_callbacks_); 284 const bool is_owner = IsOwner(); 285 for (std::vector<IsOwnerCallback>::iterator it(is_owner_callbacks.begin()); 286 it != is_owner_callbacks.end(); 287 ++it) { 288 it->Run(is_owner); 289 } 290 } 291 292 scoped_refptr<OwnerKeyUtil> OwnerSettingsService::GetOwnerKeyUtil() { 293 DCHECK(thread_checker_.CalledOnValidThread()); 294 if (g_owner_key_util_for_testing) 295 return *g_owner_key_util_for_testing; 296 return owner_key_util_; 297 } 298 299 DeviceSettingsService* OwnerSettingsService::GetDeviceSettingsService() { 300 DCHECK(thread_checker_.CalledOnValidThread()); 301 if (g_device_settings_service_for_testing) 302 return g_device_settings_service_for_testing; 303 if (DeviceSettingsService::IsInitialized()) 304 return DeviceSettingsService::Get(); 305 return NULL; 306 } 307 308 } // namespace chromeos 309