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