Home | History | Annotate | Download | only in dbus
      1 // Copyright (c) 2012 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/cryptohome_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/location.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "chromeos/cryptohome/async_method_caller.h"
     12 #include "chromeos/dbus/blocking_method_caller.h"
     13 #include "dbus/bus.h"
     14 #include "dbus/message.h"
     15 #include "dbus/object_path.h"
     16 #include "dbus/object_proxy.h"
     17 #include "third_party/cros_system_api/dbus/service_constants.h"
     18 
     19 namespace chromeos {
     20 
     21 namespace {
     22 
     23 // This suffix is appended to user_id to get hash in stub implementation:
     24 // stub_hash = "[user_id]-hash";
     25 static const char kUserIdStubHashSuffix[] = "-hash";
     26 
     27 // The CryptohomeClient implementation.
     28 class CryptohomeClientImpl : public CryptohomeClient {
     29  public:
     30   CryptohomeClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {}
     31 
     32   // CryptohomeClient override.
     33   virtual void SetAsyncCallStatusHandlers(
     34       const AsyncCallStatusHandler& handler,
     35       const AsyncCallStatusWithDataHandler& data_handler) OVERRIDE {
     36     async_call_status_handler_ = handler;
     37     async_call_status_data_handler_ = data_handler;
     38   }
     39 
     40   // CryptohomeClient override.
     41   virtual void ResetAsyncCallStatusHandlers() OVERRIDE {
     42     async_call_status_handler_.Reset();
     43     async_call_status_data_handler_.Reset();
     44   }
     45 
     46   // CryptohomeClient override.
     47   virtual void WaitForServiceToBeAvailable(
     48       const WaitForServiceToBeAvailableCallback& callback) OVERRIDE {
     49     proxy_->WaitForServiceToBeAvailable(callback);
     50   }
     51 
     52   // CryptohomeClient override.
     53   virtual void IsMounted(const BoolDBusMethodCallback& callback) OVERRIDE {
     54     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
     55                                  cryptohome::kCryptohomeIsMounted);
     56     CallBoolMethod(&method_call, callback);
     57   }
     58 
     59   // CryptohomeClient override.
     60   virtual bool Unmount(bool *success) OVERRIDE {
     61     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
     62                                  cryptohome::kCryptohomeUnmount);
     63     return CallBoolMethodAndBlock(&method_call, success);
     64   }
     65 
     66   // CryptohomeClient override.
     67   virtual void AsyncCheckKey(const std::string& username,
     68                              const std::string& key,
     69                              const AsyncMethodCallback& callback) OVERRIDE {
     70     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
     71                                  cryptohome::kCryptohomeAsyncCheckKey);
     72     dbus::MessageWriter writer(&method_call);
     73     writer.AppendString(username);
     74     writer.AppendString(key);
     75     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
     76                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
     77                                   weak_ptr_factory_.GetWeakPtr(),
     78                                   callback));
     79   }
     80 
     81   // CryptohomeClient override.
     82   virtual void AsyncMigrateKey(const std::string& username,
     83                                const std::string& from_key,
     84                                const std::string& to_key,
     85                                const AsyncMethodCallback& callback) OVERRIDE {
     86     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
     87                                  cryptohome::kCryptohomeAsyncMigrateKey);
     88     dbus::MessageWriter writer(&method_call);
     89     writer.AppendString(username);
     90     writer.AppendString(from_key);
     91     writer.AppendString(to_key);
     92     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
     93                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
     94                                   weak_ptr_factory_.GetWeakPtr(),
     95                                   callback));
     96   }
     97 
     98   // CryptohomeClient override.
     99   virtual void AsyncRemove(const std::string& username,
    100                            const AsyncMethodCallback& callback) OVERRIDE {
    101     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    102                                  cryptohome::kCryptohomeAsyncRemove);
    103     dbus::MessageWriter writer(&method_call);
    104     writer.AppendString(username);
    105     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    106                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    107                                   weak_ptr_factory_.GetWeakPtr(),
    108                                   callback));
    109   }
    110 
    111   // CryptohomeClient override.
    112   virtual void GetSystemSalt(const GetSystemSaltCallback& callback) OVERRIDE {
    113     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    114                                  cryptohome::kCryptohomeGetSystemSalt);
    115     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    116                        base::Bind(&CryptohomeClientImpl::OnGetSystemSalt,
    117                                   weak_ptr_factory_.GetWeakPtr(),
    118                                   callback));
    119   }
    120 
    121   // CryptohomeClient override,
    122   virtual void GetSanitizedUsername(
    123       const std::string& username,
    124       const StringDBusMethodCallback& callback) OVERRIDE {
    125     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    126                                  cryptohome::kCryptohomeGetSanitizedUsername);
    127     dbus::MessageWriter writer(&method_call);
    128     writer.AppendString(username);
    129     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    130                        base::Bind(&CryptohomeClientImpl::OnStringMethod,
    131                                   weak_ptr_factory_.GetWeakPtr(),
    132                                   callback));
    133   }
    134 
    135   // CryptohomeClient override.
    136   virtual std::string BlockingGetSanitizedUsername(
    137       const std::string& username) OVERRIDE {
    138     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    139                                  cryptohome::kCryptohomeGetSanitizedUsername);
    140     dbus::MessageWriter writer(&method_call);
    141     writer.AppendString(username);
    142 
    143     scoped_ptr<dbus::Response> response =
    144         blocking_method_caller_->CallMethodAndBlock(&method_call);
    145 
    146     std::string sanitized_username;
    147     if (response) {
    148       dbus::MessageReader reader(response.get());
    149       reader.PopString(&sanitized_username);
    150     }
    151 
    152     return sanitized_username;
    153   }
    154 
    155   // CryptohomeClient override.
    156   virtual void AsyncMount(const std::string& username,
    157                           const std::string& key,
    158                           int flags,
    159                           const AsyncMethodCallback& callback) OVERRIDE {
    160     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    161                                  cryptohome::kCryptohomeAsyncMount);
    162     dbus::MessageWriter writer(&method_call);
    163     writer.AppendString(username);
    164     writer.AppendString(key);
    165     writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING);
    166     writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL);
    167     // deprecated_tracked_subdirectories
    168     writer.AppendArrayOfStrings(std::vector<std::string>());
    169     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    170                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    171                                   weak_ptr_factory_.GetWeakPtr(),
    172                                   callback));
    173   }
    174 
    175   // CryptohomeClient override.
    176   virtual void AsyncAddKey(const std::string& username,
    177                            const std::string& key,
    178                            const std::string& new_key,
    179                            const AsyncMethodCallback& callback) OVERRIDE {
    180     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    181                                  cryptohome::kCryptohomeAsyncAddKey);
    182     dbus::MessageWriter writer(&method_call);
    183     writer.AppendString(username);
    184     writer.AppendString(key);
    185     writer.AppendString(new_key);
    186     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    187                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    188                                   weak_ptr_factory_.GetWeakPtr(),
    189                                   callback));
    190   }
    191 
    192   // CryptohomeClient override.
    193   virtual void AsyncMountGuest(const AsyncMethodCallback& callback) OVERRIDE {
    194     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    195                                  cryptohome::kCryptohomeAsyncMountGuest);
    196     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    197                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    198                                   weak_ptr_factory_.GetWeakPtr(),
    199                                   callback));
    200   }
    201 
    202   // CryptohomeClient override.
    203   virtual void AsyncMountPublic(const std::string& public_mount_id,
    204                                 int flags,
    205                                 const AsyncMethodCallback& callback) OVERRIDE {
    206     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    207                                  cryptohome::kCryptohomeAsyncMountPublic);
    208     dbus::MessageWriter writer(&method_call);
    209     writer.AppendString(public_mount_id);
    210     writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING);
    211     writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL);
    212     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    213                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    214                                   weak_ptr_factory_.GetWeakPtr(),
    215                                   callback));
    216   }
    217 
    218   // CryptohomeClient override.
    219   virtual void TpmIsReady(const BoolDBusMethodCallback& callback) OVERRIDE {
    220     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    221                                  cryptohome::kCryptohomeTpmIsReady);
    222     CallBoolMethod(&method_call, callback);
    223   }
    224 
    225   // CryptohomeClient override.
    226   virtual void TpmIsEnabled(const BoolDBusMethodCallback& callback) OVERRIDE {
    227     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    228                                  cryptohome::kCryptohomeTpmIsEnabled);
    229     CallBoolMethod(&method_call, callback);
    230   }
    231 
    232   // CryptohomeClient override.
    233   // TODO(hashimoto): Remove this method. crbug.com/141006
    234   virtual bool CallTpmIsEnabledAndBlock(bool* enabled) OVERRIDE {
    235     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    236                                  cryptohome::kCryptohomeTpmIsEnabled);
    237     return CallBoolMethodAndBlock(&method_call, enabled);
    238   }
    239 
    240   // CryptohomeClient override.
    241   virtual void TpmGetPassword(
    242       const StringDBusMethodCallback& callback) OVERRIDE {
    243     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    244                                  cryptohome::kCryptohomeTpmGetPassword);
    245     proxy_->CallMethod(
    246         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    247         base::Bind(&CryptohomeClientImpl::OnStringMethod,
    248                    weak_ptr_factory_.GetWeakPtr(),
    249                    callback));
    250   }
    251 
    252   // CryptohomeClient override.
    253   virtual void TpmIsOwned(const BoolDBusMethodCallback& callback) OVERRIDE {
    254     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    255                                  cryptohome::kCryptohomeTpmIsOwned);
    256     CallBoolMethod(&method_call, callback);
    257   }
    258 
    259   // CryptohomeClient override.
    260   // TODO(hashimoto): Remove this method. crbug.com/141012
    261   virtual bool CallTpmIsOwnedAndBlock(bool* owned) OVERRIDE {
    262     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    263                                  cryptohome::kCryptohomeTpmIsOwned);
    264     return CallBoolMethodAndBlock(&method_call, owned);
    265   }
    266 
    267   // CryptohomeClient override.
    268   virtual void TpmIsBeingOwned(const BoolDBusMethodCallback& callback)
    269       OVERRIDE {
    270     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    271                                  cryptohome::kCryptohomeTpmIsBeingOwned);
    272     CallBoolMethod(&method_call, callback);
    273   }
    274 
    275   // CryptohomeClient override.
    276   // TODO(hashimoto): Remove this method. crbug.com/141011
    277   virtual bool CallTpmIsBeingOwnedAndBlock(bool* owning) OVERRIDE {
    278     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    279                                  cryptohome::kCryptohomeTpmIsBeingOwned);
    280     return CallBoolMethodAndBlock(&method_call, owning);
    281   }
    282 
    283   // CryptohomeClient override.
    284   virtual void TpmCanAttemptOwnership(
    285       const VoidDBusMethodCallback& callback) OVERRIDE {
    286     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    287                                  cryptohome::kCryptohomeTpmCanAttemptOwnership);
    288     CallVoidMethod(&method_call, callback);
    289   }
    290 
    291   // CryptohomeClient overrides.
    292   virtual void TpmClearStoredPassword(const VoidDBusMethodCallback& callback)
    293       OVERRIDE {
    294     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    295                                  cryptohome::kCryptohomeTpmClearStoredPassword);
    296     CallVoidMethod(&method_call, callback);
    297   }
    298 
    299   // CryptohomeClient override.
    300   // TODO(hashimoto): Remove this method. crbug.com/141010
    301   virtual bool CallTpmClearStoredPasswordAndBlock() OVERRIDE {
    302     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    303                                  cryptohome::kCryptohomeTpmClearStoredPassword);
    304     scoped_ptr<dbus::Response> response(
    305         blocking_method_caller_->CallMethodAndBlock(&method_call));
    306     return response.get() != NULL;
    307   }
    308 
    309   // CryptohomeClient override.
    310   virtual void Pkcs11IsTpmTokenReady(const BoolDBusMethodCallback& callback)
    311       OVERRIDE {
    312     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    313                                  cryptohome::kCryptohomePkcs11IsTpmTokenReady);
    314     CallBoolMethod(&method_call, callback);
    315   }
    316 
    317   // CryptohomeClient override.
    318   virtual void Pkcs11GetTpmTokenInfo(
    319       const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE {
    320     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    321                                  cryptohome::kCryptohomePkcs11GetTpmTokenInfo);
    322     proxy_->CallMethod(
    323         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    324         base::Bind(
    325             &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfo,
    326             weak_ptr_factory_.GetWeakPtr(),
    327             callback));
    328   }
    329 
    330   // CryptohomeClient override.
    331   virtual void Pkcs11GetTpmTokenInfoForUser(
    332       const std::string& user_email,
    333       const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE {
    334     dbus::MethodCall method_call(
    335         cryptohome::kCryptohomeInterface,
    336         cryptohome::kCryptohomePkcs11GetTpmTokenInfoForUser);
    337     dbus::MessageWriter writer(&method_call);
    338     writer.AppendString(user_email);
    339     proxy_->CallMethod(
    340         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    341         base::Bind(
    342             &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfoForUser,
    343             weak_ptr_factory_.GetWeakPtr(),
    344             callback));
    345   }
    346 
    347   // CryptohomeClient override.
    348   virtual bool InstallAttributesGet(const std::string& name,
    349                                     std::vector<uint8>* value,
    350                                     bool* successful) OVERRIDE {
    351     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    352                                  cryptohome::kCryptohomeInstallAttributesGet);
    353     dbus::MessageWriter writer(&method_call);
    354     writer.AppendString(name);
    355     scoped_ptr<dbus::Response> response(
    356         blocking_method_caller_->CallMethodAndBlock(&method_call));
    357     if (!response.get())
    358       return false;
    359     dbus::MessageReader reader(response.get());
    360     uint8* bytes = NULL;
    361     size_t length = 0;
    362     if (!reader.PopArrayOfBytes(&bytes, &length) ||
    363         !reader.PopBool(successful))
    364       return false;
    365     value->assign(bytes, bytes + length);
    366     return true;
    367   }
    368 
    369   // CryptohomeClient override.
    370   virtual bool InstallAttributesSet(const std::string& name,
    371                                     const std::vector<uint8>& value,
    372                                     bool* successful) OVERRIDE {
    373     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
    374                                  cryptohome::kCryptohomeInstallAttributesSet);
    375     dbus::MessageWriter writer(&method_call);
    376     writer.AppendString(name);
    377     writer.AppendArrayOfBytes(value.data(), value.size());
    378     return CallBoolMethodAndBlock(&method_call, successful);
    379   }
    380 
    381   // CryptohomeClient override.
    382   virtual bool InstallAttributesFinalize(bool* successful) OVERRIDE {
    383     dbus::MethodCall method_call(
    384         cryptohome::kCryptohomeInterface,
    385         cryptohome::kCryptohomeInstallAttributesFinalize);
    386     return CallBoolMethodAndBlock(&method_call, successful);
    387   }
    388 
    389   // CryptohomeClient override.
    390   virtual void InstallAttributesIsReady(const BoolDBusMethodCallback& callback)
    391       OVERRIDE {
    392     dbus::MethodCall method_call(
    393         cryptohome::kCryptohomeInterface,
    394         cryptohome::kCryptohomeInstallAttributesIsReady);
    395     return CallBoolMethod(&method_call, callback);
    396   }
    397 
    398   // CryptohomeClient override.
    399   virtual bool InstallAttributesIsInvalid(bool* is_invalid) OVERRIDE {
    400     dbus::MethodCall method_call(
    401         cryptohome::kCryptohomeInterface,
    402         cryptohome::kCryptohomeInstallAttributesIsInvalid);
    403     return CallBoolMethodAndBlock(&method_call, is_invalid);
    404   }
    405 
    406   // CryptohomeClient override.
    407   virtual bool InstallAttributesIsFirstInstall(
    408       bool* is_first_install) OVERRIDE {
    409     dbus::MethodCall method_call(
    410         cryptohome::kCryptohomeInterface,
    411         cryptohome::kCryptohomeInstallAttributesIsFirstInstall);
    412     return CallBoolMethodAndBlock(&method_call, is_first_install);
    413   }
    414 
    415   // CryptohomeClient override.
    416   virtual void TpmAttestationIsPrepared(
    417         const BoolDBusMethodCallback& callback) OVERRIDE {
    418     dbus::MethodCall method_call(
    419         cryptohome::kCryptohomeInterface,
    420         cryptohome::kCryptohomeTpmIsAttestationPrepared);
    421     return CallBoolMethod(&method_call, callback);
    422   }
    423 
    424   // CryptohomeClient override.
    425   virtual void TpmAttestationIsEnrolled(
    426         const BoolDBusMethodCallback& callback) OVERRIDE {
    427     dbus::MethodCall method_call(
    428         cryptohome::kCryptohomeInterface,
    429         cryptohome::kCryptohomeTpmIsAttestationEnrolled);
    430     return CallBoolMethod(&method_call, callback);
    431   }
    432 
    433   // CryptohomeClient override.
    434   virtual void AsyncTpmAttestationCreateEnrollRequest(
    435       const AsyncMethodCallback& callback) OVERRIDE {
    436     dbus::MethodCall method_call(
    437         cryptohome::kCryptohomeInterface,
    438         cryptohome::kCryptohomeAsyncTpmAttestationCreateEnrollRequest);
    439     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    440                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    441                                   weak_ptr_factory_.GetWeakPtr(),
    442                                   callback));
    443   }
    444 
    445   // CryptohomeClient override.
    446   virtual void AsyncTpmAttestationEnroll(
    447       const std::string& pca_response,
    448       const AsyncMethodCallback& callback) OVERRIDE {
    449     dbus::MethodCall method_call(
    450         cryptohome::kCryptohomeInterface,
    451         cryptohome::kCryptohomeAsyncTpmAttestationEnroll);
    452     dbus::MessageWriter writer(&method_call);
    453     writer.AppendArrayOfBytes(
    454         reinterpret_cast<const uint8*>(pca_response.data()),
    455         pca_response.size());
    456     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    457                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    458                                   weak_ptr_factory_.GetWeakPtr(),
    459                                   callback));
    460   }
    461 
    462   // CryptohomeClient override.
    463   virtual void AsyncTpmAttestationCreateCertRequest(
    464       attestation::AttestationCertificateProfile certificate_profile,
    465       const std::string& user_id,
    466       const std::string& request_origin,
    467       const AsyncMethodCallback& callback) OVERRIDE {
    468     dbus::MethodCall method_call(
    469         cryptohome::kCryptohomeInterface,
    470         cryptohome::kCryptohomeAsyncTpmAttestationCreateCertRequestByProfile);
    471     dbus::MessageWriter writer(&method_call);
    472     writer.AppendInt32(certificate_profile);
    473     writer.AppendString(user_id);
    474     writer.AppendString(request_origin);
    475     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    476                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    477                                   weak_ptr_factory_.GetWeakPtr(),
    478                                   callback));
    479   }
    480 
    481   // CryptohomeClient override.
    482   virtual void AsyncTpmAttestationFinishCertRequest(
    483       const std::string& pca_response,
    484       attestation::AttestationKeyType key_type,
    485       const std::string& user_id,
    486       const std::string& key_name,
    487       const AsyncMethodCallback& callback) OVERRIDE {
    488     dbus::MethodCall method_call(
    489         cryptohome::kCryptohomeInterface,
    490         cryptohome::kCryptohomeAsyncTpmAttestationFinishCertRequest);
    491     dbus::MessageWriter writer(&method_call);
    492     writer.AppendArrayOfBytes(
    493         reinterpret_cast<const uint8*>(pca_response.data()),
    494         pca_response.size());
    495     bool is_user_specific = (key_type == attestation::KEY_USER);
    496     writer.AppendBool(is_user_specific);
    497     writer.AppendString(user_id);
    498     writer.AppendString(key_name);
    499     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    500                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    501                                   weak_ptr_factory_.GetWeakPtr(),
    502                                   callback));
    503   }
    504 
    505   // CryptohomeClient override.
    506   virtual void TpmAttestationDoesKeyExist(
    507       attestation::AttestationKeyType key_type,
    508       const std::string& user_id,
    509       const std::string& key_name,
    510       const BoolDBusMethodCallback& callback) OVERRIDE {
    511     dbus::MethodCall method_call(
    512         cryptohome::kCryptohomeInterface,
    513         cryptohome::kCryptohomeTpmAttestationDoesKeyExist);
    514     dbus::MessageWriter writer(&method_call);
    515     bool is_user_specific = (key_type == attestation::KEY_USER);
    516     writer.AppendBool(is_user_specific);
    517     writer.AppendString(user_id);
    518     writer.AppendString(key_name);
    519     CallBoolMethod(&method_call, callback);
    520   }
    521 
    522   // CryptohomeClient override.
    523   virtual void TpmAttestationGetCertificate(
    524       attestation::AttestationKeyType key_type,
    525       const std::string& user_id,
    526       const std::string& key_name,
    527       const DataMethodCallback& callback) OVERRIDE {
    528     dbus::MethodCall method_call(
    529         cryptohome::kCryptohomeInterface,
    530         cryptohome::kCryptohomeTpmAttestationGetCertificate);
    531     dbus::MessageWriter writer(&method_call);
    532     bool is_user_specific = (key_type == attestation::KEY_USER);
    533     writer.AppendBool(is_user_specific);
    534     writer.AppendString(user_id);
    535     writer.AppendString(key_name);
    536     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    537                        base::Bind(&CryptohomeClientImpl::OnDataMethod,
    538                                   weak_ptr_factory_.GetWeakPtr(),
    539                                   callback));
    540   }
    541 
    542   // CryptohomeClient override.
    543   virtual void TpmAttestationGetPublicKey(
    544       attestation::AttestationKeyType key_type,
    545       const std::string& user_id,
    546       const std::string& key_name,
    547       const DataMethodCallback& callback) OVERRIDE {
    548     dbus::MethodCall method_call(
    549         cryptohome::kCryptohomeInterface,
    550         cryptohome::kCryptohomeTpmAttestationGetPublicKey);
    551     dbus::MessageWriter writer(&method_call);
    552     bool is_user_specific = (key_type == attestation::KEY_USER);
    553     writer.AppendBool(is_user_specific);
    554     writer.AppendString(user_id);
    555     writer.AppendString(key_name);
    556     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    557                        base::Bind(&CryptohomeClientImpl::OnDataMethod,
    558                                   weak_ptr_factory_.GetWeakPtr(),
    559                                   callback));
    560   }
    561 
    562   // CryptohomeClient override.
    563   virtual void TpmAttestationRegisterKey(
    564       attestation::AttestationKeyType key_type,
    565       const std::string& user_id,
    566       const std::string& key_name,
    567       const AsyncMethodCallback& callback) OVERRIDE {
    568     dbus::MethodCall method_call(
    569         cryptohome::kCryptohomeInterface,
    570         cryptohome::kCryptohomeTpmAttestationRegisterKey);
    571     dbus::MessageWriter writer(&method_call);
    572     bool is_user_specific = (key_type == attestation::KEY_USER);
    573     writer.AppendBool(is_user_specific);
    574     writer.AppendString(user_id);
    575     writer.AppendString(key_name);
    576     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    577                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    578                                   weak_ptr_factory_.GetWeakPtr(),
    579                                   callback));
    580   }
    581 
    582   // CryptohomeClient override.
    583   virtual void TpmAttestationSignEnterpriseChallenge(
    584       attestation::AttestationKeyType key_type,
    585       const std::string& user_id,
    586       const std::string& key_name,
    587       const std::string& domain,
    588       const std::string& device_id,
    589       attestation::AttestationChallengeOptions options,
    590       const std::string& challenge,
    591       const AsyncMethodCallback& callback) OVERRIDE {
    592     dbus::MethodCall method_call(
    593         cryptohome::kCryptohomeInterface,
    594         cryptohome::kCryptohomeTpmAttestationSignEnterpriseChallenge);
    595     dbus::MessageWriter writer(&method_call);
    596     bool is_user_specific = (key_type == attestation::KEY_USER);
    597     writer.AppendBool(is_user_specific);
    598     writer.AppendString(user_id);
    599     writer.AppendString(key_name);
    600     writer.AppendString(domain);
    601     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(device_id.data()),
    602                               device_id.size());
    603     bool include_signed_public_key =
    604         (options & attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY);
    605     writer.AppendBool(include_signed_public_key);
    606     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(challenge.data()),
    607                               challenge.size());
    608     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    609                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    610                                   weak_ptr_factory_.GetWeakPtr(),
    611                                   callback));
    612   }
    613 
    614   // CryptohomeClient override.
    615   virtual void TpmAttestationSignSimpleChallenge(
    616       attestation::AttestationKeyType key_type,
    617       const std::string& user_id,
    618       const std::string& key_name,
    619       const std::string& challenge,
    620       const AsyncMethodCallback& callback) OVERRIDE {
    621     dbus::MethodCall method_call(
    622         cryptohome::kCryptohomeInterface,
    623         cryptohome::kCryptohomeTpmAttestationSignSimpleChallenge);
    624     dbus::MessageWriter writer(&method_call);
    625     bool is_user_specific = (key_type == attestation::KEY_USER);
    626     writer.AppendBool(is_user_specific);
    627     writer.AppendString(user_id);
    628     writer.AppendString(key_name);
    629     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(challenge.data()),
    630                               challenge.size());
    631     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    632                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
    633                                   weak_ptr_factory_.GetWeakPtr(),
    634                                   callback));
    635   }
    636 
    637   // CryptohomeClient override.
    638   virtual void TpmAttestationGetKeyPayload(
    639       attestation::AttestationKeyType key_type,
    640       const std::string& user_id,
    641       const std::string& key_name,
    642       const DataMethodCallback& callback) OVERRIDE {
    643     dbus::MethodCall method_call(
    644         cryptohome::kCryptohomeInterface,
    645         cryptohome::kCryptohomeTpmAttestationGetKeyPayload);
    646     dbus::MessageWriter writer(&method_call);
    647     bool is_user_specific = (key_type == attestation::KEY_USER);
    648     writer.AppendBool(is_user_specific);
    649     writer.AppendString(user_id);
    650     writer.AppendString(key_name);
    651     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    652                        base::Bind(&CryptohomeClientImpl::OnDataMethod,
    653                                   weak_ptr_factory_.GetWeakPtr(),
    654                                   callback));
    655   }
    656 
    657   // CryptohomeClient override.
    658   virtual void TpmAttestationSetKeyPayload(
    659       attestation::AttestationKeyType key_type,
    660       const std::string& user_id,
    661       const std::string& key_name,
    662       const std::string& payload,
    663       const BoolDBusMethodCallback& callback) OVERRIDE {
    664     dbus::MethodCall method_call(
    665         cryptohome::kCryptohomeInterface,
    666         cryptohome::kCryptohomeTpmAttestationSetKeyPayload);
    667     dbus::MessageWriter writer(&method_call);
    668     bool is_user_specific = (key_type == attestation::KEY_USER);
    669     writer.AppendBool(is_user_specific);
    670     writer.AppendString(user_id);
    671     writer.AppendString(key_name);
    672     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(payload.data()),
    673                               payload.size());
    674     CallBoolMethod(&method_call, callback);
    675   }
    676 
    677   // CryptohomeClient override.
    678   virtual void TpmAttestationDeleteKeys(
    679       attestation::AttestationKeyType key_type,
    680       const std::string& user_id,
    681       const std::string& key_prefix,
    682       const BoolDBusMethodCallback& callback) OVERRIDE {
    683     dbus::MethodCall method_call(
    684         cryptohome::kCryptohomeInterface,
    685         cryptohome::kCryptohomeTpmAttestationDeleteKeys);
    686     dbus::MessageWriter writer(&method_call);
    687     bool is_user_specific = (key_type == attestation::KEY_USER);
    688     writer.AppendBool(is_user_specific);
    689     writer.AppendString(user_id);
    690     writer.AppendString(key_prefix);
    691     CallBoolMethod(&method_call, callback);
    692   }
    693 
    694  protected:
    695   virtual void Init(dbus::Bus* bus) OVERRIDE {
    696     proxy_ = bus->GetObjectProxy(
    697         cryptohome::kCryptohomeServiceName,
    698         dbus::ObjectPath(cryptohome::kCryptohomeServicePath));
    699 
    700     blocking_method_caller_.reset(new BlockingMethodCaller(bus, proxy_));
    701 
    702     proxy_->ConnectToSignal(cryptohome::kCryptohomeInterface,
    703                             cryptohome::kSignalAsyncCallStatus,
    704                             base::Bind(&CryptohomeClientImpl::OnAsyncCallStatus,
    705                                        weak_ptr_factory_.GetWeakPtr()),
    706                             base::Bind(&CryptohomeClientImpl::OnSignalConnected,
    707                                        weak_ptr_factory_.GetWeakPtr()));
    708     proxy_->ConnectToSignal(
    709         cryptohome::kCryptohomeInterface,
    710         cryptohome::kSignalAsyncCallStatusWithData,
    711         base::Bind(&CryptohomeClientImpl::OnAsyncCallStatusWithData,
    712                    weak_ptr_factory_.GetWeakPtr()),
    713         base::Bind(&CryptohomeClientImpl::OnSignalConnected,
    714                    weak_ptr_factory_.GetWeakPtr()));
    715   }
    716 
    717  private:
    718   // Handles the result of AsyncXXX methods.
    719   void OnAsyncMethodCall(const AsyncMethodCallback& callback,
    720                          dbus::Response* response) {
    721     if (!response)
    722       return;
    723     dbus::MessageReader reader(response);
    724     int async_id = 0;
    725     if (!reader.PopInt32(&async_id)) {
    726       LOG(ERROR) << "Invalid response: " << response->ToString();
    727       return;
    728     }
    729     callback.Run(async_id);
    730   }
    731 
    732   // Handles the result of GetSystemSalt().
    733   void OnGetSystemSalt(const GetSystemSaltCallback& callback,
    734                        dbus::Response* response) {
    735     if (!response) {
    736       callback.Run(DBUS_METHOD_CALL_FAILURE, std::vector<uint8>());
    737       return;
    738     }
    739     dbus::MessageReader reader(response);
    740     uint8* bytes = NULL;
    741     size_t length = 0;
    742     if (!reader.PopArrayOfBytes(&bytes, &length)) {
    743       callback.Run(DBUS_METHOD_CALL_FAILURE, std::vector<uint8>());
    744       return;
    745     }
    746     callback.Run(DBUS_METHOD_CALL_SUCCESS,
    747                  std::vector<uint8>(bytes, bytes + length));
    748   }
    749 
    750   // Calls a method without result values.
    751   void CallVoidMethod(dbus::MethodCall* method_call,
    752                       const VoidDBusMethodCallback& callback) {
    753     proxy_->CallMethod(method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    754                        base::Bind(&CryptohomeClientImpl::OnVoidMethod,
    755                                   weak_ptr_factory_.GetWeakPtr(),
    756                                   callback));
    757   }
    758 
    759   void OnVoidMethod(const VoidDBusMethodCallback& callback,
    760                     dbus::Response* response) {
    761     if (!response) {
    762       callback.Run(DBUS_METHOD_CALL_FAILURE);
    763       return;
    764     }
    765     callback.Run(DBUS_METHOD_CALL_SUCCESS);
    766   }
    767 
    768   // Calls a method with a bool value reult and block.
    769   bool CallBoolMethodAndBlock(dbus::MethodCall* method_call,
    770                               bool* result) {
    771     scoped_ptr<dbus::Response> response(
    772         blocking_method_caller_->CallMethodAndBlock(method_call));
    773     if (!response.get())
    774       return false;
    775     dbus::MessageReader reader(response.get());
    776     return reader.PopBool(result);
    777   }
    778 
    779   // Calls a method with a bool value result.
    780   void CallBoolMethod(dbus::MethodCall* method_call,
    781                       const BoolDBusMethodCallback& callback) {
    782     proxy_->CallMethod(method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    783                        base::Bind(
    784                            &CryptohomeClientImpl::OnBoolMethod,
    785                            weak_ptr_factory_.GetWeakPtr(),
    786                            callback));
    787   }
    788 
    789   // Handles responses for methods with a bool value result.
    790   void OnBoolMethod(const BoolDBusMethodCallback& callback,
    791                     dbus::Response* response) {
    792     if (!response) {
    793       callback.Run(DBUS_METHOD_CALL_FAILURE, false);
    794       return;
    795     }
    796     dbus::MessageReader reader(response);
    797     bool result = false;
    798     if (!reader.PopBool(&result)) {
    799       callback.Run(DBUS_METHOD_CALL_FAILURE, false);
    800       LOG(ERROR) << "Invalid response: " << response->ToString();
    801       return;
    802     }
    803     callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
    804   }
    805 
    806   // Handles responses for methods with a string value result.
    807   void OnStringMethod(const StringDBusMethodCallback& callback,
    808                       dbus::Response* response) {
    809     if (!response) {
    810       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
    811       return;
    812     }
    813     dbus::MessageReader reader(response);
    814     std::string result;
    815     if (!reader.PopString(&result)) {
    816       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
    817       return;
    818     }
    819     callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
    820   }
    821 
    822   // Handles responses for methods with a bool result and data.
    823   void OnDataMethod(const DataMethodCallback& callback,
    824                     dbus::Response* response) {
    825     if (!response) {
    826       callback.Run(DBUS_METHOD_CALL_FAILURE, false, std::string());
    827       return;
    828     }
    829     dbus::MessageReader reader(response);
    830     uint8* data_buffer = NULL;
    831     size_t data_length = 0;
    832     bool result = false;
    833     if (!reader.PopArrayOfBytes(&data_buffer, &data_length) ||
    834         !reader.PopBool(&result)) {
    835       callback.Run(DBUS_METHOD_CALL_FAILURE, false, std::string());
    836       return;
    837     }
    838     std::string data(reinterpret_cast<char*>(data_buffer), data_length);
    839     callback.Run(DBUS_METHOD_CALL_SUCCESS, result, data);
    840   }
    841 
    842   // Handles responses for Pkcs11GetTpmTokenInfo.
    843   void OnPkcs11GetTpmTokenInfo(const Pkcs11GetTpmTokenInfoCallback& callback,
    844                                dbus::Response* response) {
    845     if (!response) {
    846       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
    847       return;
    848     }
    849     dbus::MessageReader reader(response);
    850     std::string label;
    851     std::string user_pin;
    852     if (!reader.PopString(&label) || !reader.PopString(&user_pin)) {
    853       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
    854       LOG(ERROR) << "Invalid response: " << response->ToString();
    855       return;
    856     }
    857     const int kDefaultSlot = 0;
    858     callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, kDefaultSlot);
    859   }
    860 
    861   // Handles responses for Pkcs11GetTpmTokenInfoForUser.
    862   void OnPkcs11GetTpmTokenInfoForUser(
    863       const Pkcs11GetTpmTokenInfoCallback& callback,
    864       dbus::Response* response) {
    865     if (!response) {
    866       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
    867       return;
    868     }
    869     dbus::MessageReader reader(response);
    870     std::string label;
    871     std::string user_pin;
    872     int slot = 0;
    873     if (!reader.PopString(&label) || !reader.PopString(&user_pin) ||
    874         !reader.PopInt32(&slot)) {
    875       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
    876       LOG(ERROR) << "Invalid response: " << response->ToString();
    877       return;
    878     }
    879     callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, slot);
    880   }
    881 
    882   // Handles AsyncCallStatus signal.
    883   void OnAsyncCallStatus(dbus::Signal* signal) {
    884     dbus::MessageReader reader(signal);
    885     int async_id = 0;
    886     bool return_status = false;
    887     int return_code = 0;
    888     if (!reader.PopInt32(&async_id) ||
    889         !reader.PopBool(&return_status) ||
    890         !reader.PopInt32(&return_code)) {
    891       LOG(ERROR) << "Invalid signal: " << signal->ToString();
    892       return;
    893     }
    894     if (!async_call_status_handler_.is_null())
    895       async_call_status_handler_.Run(async_id, return_status, return_code);
    896   }
    897 
    898   // Handles AsyncCallStatusWithData signal.
    899   void OnAsyncCallStatusWithData(dbus::Signal* signal) {
    900     dbus::MessageReader reader(signal);
    901     int async_id = 0;
    902     bool return_status = false;
    903     uint8* return_data_buffer = NULL;
    904     size_t return_data_length = 0;
    905     if (!reader.PopInt32(&async_id) ||
    906         !reader.PopBool(&return_status) ||
    907         !reader.PopArrayOfBytes(&return_data_buffer, &return_data_length)) {
    908       LOG(ERROR) << "Invalid signal: " << signal->ToString();
    909       return;
    910     }
    911     if (!async_call_status_data_handler_.is_null()) {
    912       std::string return_data(reinterpret_cast<char*>(return_data_buffer),
    913                               return_data_length);
    914       async_call_status_data_handler_.Run(async_id, return_status, return_data);
    915     }
    916   }
    917 
    918   // Handles the result of signal connection setup.
    919   void OnSignalConnected(const std::string& interface,
    920                          const std::string& signal,
    921                          bool succeeded) {
    922     LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
    923         signal << " failed.";
    924   }
    925 
    926   dbus::ObjectProxy* proxy_;
    927   scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
    928   AsyncCallStatusHandler async_call_status_handler_;
    929   AsyncCallStatusWithDataHandler async_call_status_data_handler_;
    930 
    931   // Note: This should remain the last member so it'll be destroyed and
    932   // invalidate its weak pointers before any other members are destroyed.
    933   base::WeakPtrFactory<CryptohomeClientImpl> weak_ptr_factory_;
    934 
    935   DISALLOW_COPY_AND_ASSIGN(CryptohomeClientImpl);
    936 };
    937 
    938 }  // namespace
    939 
    940 ////////////////////////////////////////////////////////////////////////////////
    941 // CryptohomeClient
    942 
    943 CryptohomeClient::CryptohomeClient() {}
    944 
    945 CryptohomeClient::~CryptohomeClient() {}
    946 
    947 // static
    948 CryptohomeClient* CryptohomeClient::Create() {
    949   return new CryptohomeClientImpl();
    950 }
    951 
    952 // static
    953 std::string CryptohomeClient::GetStubSanitizedUsername(
    954     const std::string& username) {
    955   return username + kUserIdStubHashSuffix;
    956 }
    957 
    958 }  // namespace chromeos
    959