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