1 // Copyright 2013 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 "chromeos/dbus/fake_cryptohome_client.h" 6 7 #include "base/bind.h" 8 #include "base/location.h" 9 #include "base/message_loop/message_loop.h" 10 #include "crypto/nss_util.h" 11 #include "third_party/cros_system_api/dbus/service_constants.h" 12 13 namespace chromeos { 14 15 FakeCryptohomeClient::FakeCryptohomeClient() 16 : service_is_available_(true), 17 async_call_id_(1), 18 tpm_is_ready_counter_(0), 19 unmount_result_(true), 20 system_salt_(GetStubSystemSalt()), 21 locked_(false), 22 weak_ptr_factory_(this) {} 23 24 FakeCryptohomeClient::~FakeCryptohomeClient() {} 25 26 void FakeCryptohomeClient::Init(dbus::Bus* bus) { 27 } 28 29 void FakeCryptohomeClient::SetAsyncCallStatusHandlers( 30 const AsyncCallStatusHandler& handler, 31 const AsyncCallStatusWithDataHandler& data_handler) { 32 async_call_status_handler_ = handler; 33 async_call_status_data_handler_ = data_handler; 34 } 35 36 void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() { 37 async_call_status_handler_.Reset(); 38 async_call_status_data_handler_.Reset(); 39 } 40 41 void FakeCryptohomeClient::WaitForServiceToBeAvailable( 42 const WaitForServiceToBeAvailableCallback& callback) { 43 if (service_is_available_) { 44 base::MessageLoop::current()->PostTask(FROM_HERE, 45 base::Bind(callback, true)); 46 } else { 47 pending_wait_for_service_to_be_available_callbacks_.push_back(callback); 48 } 49 } 50 51 void FakeCryptohomeClient::IsMounted( 52 const BoolDBusMethodCallback& callback) { 53 base::MessageLoop::current()->PostTask( 54 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 55 } 56 57 bool FakeCryptohomeClient::Unmount(bool* success) { 58 *success = unmount_result_; 59 return true; 60 } 61 62 void FakeCryptohomeClient::AsyncCheckKey( 63 const std::string& username, 64 const std::string& key, 65 const AsyncMethodCallback& callback) { 66 ReturnAsyncMethodResult(callback, false); 67 } 68 69 void FakeCryptohomeClient::AsyncMigrateKey( 70 const std::string& username, 71 const std::string& from_key, 72 const std::string& to_key, 73 const AsyncMethodCallback& callback) { 74 ReturnAsyncMethodResult(callback, false); 75 } 76 77 void FakeCryptohomeClient::AsyncRemove( 78 const std::string& username, 79 const AsyncMethodCallback& callback) { 80 ReturnAsyncMethodResult(callback, false); 81 } 82 83 void FakeCryptohomeClient::GetSystemSalt( 84 const GetSystemSaltCallback& callback) { 85 base::MessageLoop::current()->PostTask( 86 FROM_HERE, 87 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, system_salt_)); 88 } 89 90 void FakeCryptohomeClient::GetSanitizedUsername( 91 const std::string& username, 92 const StringDBusMethodCallback& callback) { 93 // Even for stub implementation we have to return different values so that 94 // multi-profiles would work. 95 std::string sanitized_username = GetStubSanitizedUsername(username); 96 base::MessageLoop::current()->PostTask( 97 FROM_HERE, 98 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username)); 99 } 100 101 std::string FakeCryptohomeClient::BlockingGetSanitizedUsername( 102 const std::string& username) { 103 return GetStubSanitizedUsername(username); 104 } 105 106 void FakeCryptohomeClient::AsyncMount(const std::string& username, 107 const std::string& key, 108 int flags, 109 const AsyncMethodCallback& callback) { 110 ReturnAsyncMethodResult(callback, false); 111 } 112 113 void FakeCryptohomeClient::AsyncAddKey( 114 const std::string& username, 115 const std::string& key, 116 const std::string& new_key, 117 const AsyncMethodCallback& callback) { 118 ReturnAsyncMethodResult(callback, false); 119 } 120 121 void FakeCryptohomeClient::AsyncMountGuest( 122 const AsyncMethodCallback& callback) { 123 ReturnAsyncMethodResult(callback, false); 124 } 125 126 void FakeCryptohomeClient::AsyncMountPublic( 127 const std::string& public_mount_id, 128 int flags, 129 const AsyncMethodCallback& callback) { 130 ReturnAsyncMethodResult(callback, false); 131 } 132 133 void FakeCryptohomeClient::TpmIsReady( 134 const BoolDBusMethodCallback& callback) { 135 base::MessageLoop::current()->PostTask( 136 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 137 } 138 139 void FakeCryptohomeClient::TpmIsEnabled( 140 const BoolDBusMethodCallback& callback) { 141 base::MessageLoop::current()->PostTask( 142 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 143 } 144 145 bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) { 146 *enabled = true; 147 return true; 148 } 149 150 void FakeCryptohomeClient::TpmGetPassword( 151 const StringDBusMethodCallback& callback) { 152 const char kStubTpmPassword[] = "Stub-TPM-password"; 153 base::MessageLoop::current()->PostTask( 154 FROM_HERE, 155 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, 156 std::string(kStubTpmPassword))); 157 } 158 159 void FakeCryptohomeClient::TpmIsOwned( 160 const BoolDBusMethodCallback& callback) { 161 base::MessageLoop::current()->PostTask( 162 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 163 } 164 165 bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) { 166 *owned = true; 167 return true; 168 } 169 170 void FakeCryptohomeClient::TpmIsBeingOwned( 171 const BoolDBusMethodCallback& callback) { 172 base::MessageLoop::current()->PostTask( 173 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 174 } 175 176 bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) { 177 *owning = true; 178 return true; 179 } 180 181 void FakeCryptohomeClient::TpmCanAttemptOwnership( 182 const VoidDBusMethodCallback& callback) { 183 base::MessageLoop::current()->PostTask( 184 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS)); 185 } 186 187 void FakeCryptohomeClient::TpmClearStoredPassword( 188 const VoidDBusMethodCallback& callback) { 189 base::MessageLoop::current()->PostTask( 190 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS)); 191 } 192 193 bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() { 194 return true; 195 } 196 197 void FakeCryptohomeClient::Pkcs11IsTpmTokenReady( 198 const BoolDBusMethodCallback& callback) { 199 base::MessageLoop::current()->PostTask( 200 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 201 } 202 203 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo( 204 const Pkcs11GetTpmTokenInfoCallback& callback) { 205 const char kStubUserPin[] = "012345"; 206 const int kStubSlot = 0; 207 base::MessageLoop::current()->PostTask( 208 FROM_HERE, 209 base::Bind(callback, 210 DBUS_METHOD_CALL_SUCCESS, 211 std::string(crypto::kTestTPMTokenName), 212 std::string(kStubUserPin), 213 kStubSlot)); 214 } 215 216 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser( 217 const std::string& username, 218 const Pkcs11GetTpmTokenInfoCallback& callback) { 219 Pkcs11GetTpmTokenInfo(callback); 220 } 221 222 bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name, 223 std::vector<uint8>* value, 224 bool* successful) { 225 if (install_attrs_.find(name) != install_attrs_.end()) { 226 *value = install_attrs_[name]; 227 *successful = true; 228 } else { 229 value->clear(); 230 *successful = false; 231 } 232 return true; 233 } 234 235 bool FakeCryptohomeClient::InstallAttributesSet( 236 const std::string& name, 237 const std::vector<uint8>& value, 238 bool* successful) { 239 install_attrs_[name] = value; 240 *successful = true; 241 return true; 242 } 243 244 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) { 245 locked_ = true; 246 *successful = true; 247 return true; 248 } 249 250 void FakeCryptohomeClient::InstallAttributesIsReady( 251 const BoolDBusMethodCallback& callback) { 252 base::MessageLoop::current()->PostTask( 253 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 254 } 255 256 bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) { 257 *is_invalid = false; 258 return true; 259 } 260 261 bool FakeCryptohomeClient::InstallAttributesIsFirstInstall( 262 bool* is_first_install) { 263 *is_first_install = !locked_; 264 return true; 265 } 266 267 void FakeCryptohomeClient::TpmAttestationIsPrepared( 268 const BoolDBusMethodCallback& callback) { 269 base::MessageLoop::current()->PostTask( 270 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 271 } 272 273 void FakeCryptohomeClient::TpmAttestationIsEnrolled( 274 const BoolDBusMethodCallback& callback) { 275 base::MessageLoop::current()->PostTask( 276 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); 277 } 278 279 void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest( 280 const AsyncMethodCallback& callback) { 281 ReturnAsyncMethodResult(callback, true); 282 } 283 284 void FakeCryptohomeClient::AsyncTpmAttestationEnroll( 285 const std::string& pca_response, 286 const AsyncMethodCallback& callback) { 287 ReturnAsyncMethodResult(callback, false); 288 } 289 290 void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest( 291 attestation::AttestationCertificateProfile certificate_profile, 292 const std::string& user_id, 293 const std::string& request_origin, 294 const AsyncMethodCallback& callback) { 295 ReturnAsyncMethodResult(callback, true); 296 } 297 298 void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest( 299 const std::string& pca_response, 300 attestation::AttestationKeyType key_type, 301 const std::string& user_id, 302 const std::string& key_name, 303 const AsyncMethodCallback& callback) { 304 ReturnAsyncMethodResult(callback, true); 305 } 306 307 void FakeCryptohomeClient::TpmAttestationDoesKeyExist( 308 attestation::AttestationKeyType key_type, 309 const std::string& user_id, 310 const std::string& key_name, 311 const BoolDBusMethodCallback& callback) { 312 base::MessageLoop::current()->PostTask( 313 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false)); 314 } 315 316 void FakeCryptohomeClient::TpmAttestationGetCertificate( 317 attestation::AttestationKeyType key_type, 318 const std::string& user_id, 319 const std::string& key_name, 320 const DataMethodCallback& callback) { 321 base::MessageLoop::current()->PostTask( 322 FROM_HERE, 323 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string())); 324 } 325 326 void FakeCryptohomeClient::TpmAttestationGetPublicKey( 327 attestation::AttestationKeyType key_type, 328 const std::string& user_id, 329 const std::string& key_name, 330 const DataMethodCallback& callback) { 331 base::MessageLoop::current()->PostTask( 332 FROM_HERE, 333 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string())); 334 } 335 336 void FakeCryptohomeClient::TpmAttestationRegisterKey( 337 attestation::AttestationKeyType key_type, 338 const std::string& user_id, 339 const std::string& key_name, 340 const AsyncMethodCallback& callback) { 341 ReturnAsyncMethodResult(callback, true); 342 } 343 344 void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge( 345 attestation::AttestationKeyType key_type, 346 const std::string& user_id, 347 const std::string& key_name, 348 const std::string& domain, 349 const std::string& device_id, 350 attestation::AttestationChallengeOptions options, 351 const std::string& challenge, 352 const AsyncMethodCallback& callback) { 353 ReturnAsyncMethodResult(callback, true); 354 } 355 356 void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge( 357 attestation::AttestationKeyType key_type, 358 const std::string& user_id, 359 const std::string& key_name, 360 const std::string& challenge, 361 const AsyncMethodCallback& callback) { 362 ReturnAsyncMethodResult(callback, true); 363 } 364 365 void FakeCryptohomeClient::TpmAttestationGetKeyPayload( 366 attestation::AttestationKeyType key_type, 367 const std::string& user_id, 368 const std::string& key_name, 369 const DataMethodCallback& callback) { 370 base::MessageLoop::current()->PostTask( 371 FROM_HERE, 372 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string())); 373 } 374 375 void FakeCryptohomeClient::TpmAttestationSetKeyPayload( 376 attestation::AttestationKeyType key_type, 377 const std::string& user_id, 378 const std::string& key_name, 379 const std::string& payload, 380 const BoolDBusMethodCallback& callback) { 381 base::MessageLoop::current()->PostTask( 382 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false)); 383 } 384 385 void FakeCryptohomeClient::TpmAttestationDeleteKeys( 386 attestation::AttestationKeyType key_type, 387 const std::string& user_id, 388 const std::string& key_prefix, 389 const BoolDBusMethodCallback& callback) { 390 base::MessageLoop::current()->PostTask( 391 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false)); 392 } 393 394 void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) { 395 service_is_available_ = is_available; 396 if (is_available) { 397 std::vector<WaitForServiceToBeAvailableCallback> callbacks; 398 callbacks.swap(pending_wait_for_service_to_be_available_callbacks_); 399 for (size_t i = 0; i < callbacks.size(); ++i) 400 callbacks[i].Run(is_available); 401 } 402 } 403 404 // static 405 std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() { 406 const char kStubSystemSalt[] = "stub_system_salt"; 407 return std::vector<uint8>(kStubSystemSalt, 408 kStubSystemSalt + arraysize(kStubSystemSalt) - 1); 409 } 410 411 void FakeCryptohomeClient::ReturnAsyncMethodResult( 412 const AsyncMethodCallback& callback, 413 bool returns_data) { 414 base::MessageLoop::current()->PostTask( 415 FROM_HERE, 416 base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal, 417 weak_ptr_factory_.GetWeakPtr(), 418 callback, 419 returns_data)); 420 } 421 422 void FakeCryptohomeClient::ReturnAsyncMethodResultInternal( 423 const AsyncMethodCallback& callback, 424 bool returns_data) { 425 callback.Run(async_call_id_); 426 if (!returns_data && !async_call_status_handler_.is_null()) { 427 base::MessageLoop::current()->PostTask( 428 FROM_HERE, 429 base::Bind(async_call_status_handler_, 430 async_call_id_, 431 true, 432 cryptohome::MOUNT_ERROR_NONE)); 433 } else if (returns_data && !async_call_status_data_handler_.is_null()) { 434 base::MessageLoop::current()->PostTask( 435 FROM_HERE, 436 base::Bind(async_call_status_data_handler_, 437 async_call_id_, 438 true, 439 std::string())); 440 } 441 ++async_call_id_; 442 } 443 444 } // namespace chromeos 445