Home | History | Annotate | Download | only in dbus
      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