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