| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/dbus/cryptohome_client.h" |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/command_line.h" |
| #include "base/location.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/observer_list.h" |
| #include "base/optional.h" |
| #include "chromeos/chromeos_switches.h" |
| #include "chromeos/cryptohome/async_method_caller.h" |
| #include "chromeos/cryptohome/cryptohome_parameters.h" |
| #include "chromeos/dbus/blocking_method_caller.h" |
| #include "chromeos/dbus/cryptohome/key.pb.h" |
| #include "chromeos/dbus/cryptohome/rpc.pb.h" |
| #include "dbus/bus.h" |
| #include "dbus/message.h" |
| #include "dbus/object_path.h" |
| #include "dbus/object_proxy.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| namespace chromeos { |
| namespace { |
| |
| // This suffix is appended to cryptohome_id to get hash in stub implementation: |
| // stub_hash = "[cryptohome_id]-hash"; |
| static const char kUserIdStubHashSuffix[] = "-hash"; |
| |
| // Timeout for TPM operations. On slow machines it should be larger, than |
| // default DBus timeout. TPM operations can take up to 80 seconds, so limit |
| // is 2 minutes. |
| const int kTpmDBusTimeoutMs = 2 * 60 * 1000; |
| |
| void FillIdentificationProtobuf(const cryptohome::Identification& id, |
| cryptohome::AccountIdentifier* id_proto) { |
| id_proto->set_account_id(id.id()); |
| } |
| |
| // Values for the attestation server switch. |
| const char kAttestationServerDefault[] = "default"; |
| const char kAttestationServerTest[] = "test"; |
| |
| static attestation::VerifiedAccessType GetVerifiedAccessType() { |
| std::string value = |
| base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| chromeos::switches::kAttestationServer); |
| if (value.empty() || value == kAttestationServerDefault) { |
| return attestation::DEFAULT_VA; |
| } |
| if (value == kAttestationServerTest) { |
| return attestation::TEST_VA; |
| } |
| LOG(WARNING) << "Invalid Verified Access server value: " << value |
| << ". Using default."; |
| return attestation::DEFAULT_VA; |
| } |
| |
| // The CryptohomeClient implementation. |
| class CryptohomeClientImpl : public CryptohomeClient { |
| public: |
| CryptohomeClientImpl() : weak_ptr_factory_(this) {} |
| |
| // CryptohomeClient override. |
| void AddObserver(Observer* observer) override { |
| observer_list_.AddObserver(observer); |
| } |
| |
| // CryptohomeClient override. |
| void RemoveObserver(Observer* observer) override { |
| observer_list_.RemoveObserver(observer); |
| } |
| |
| // CryptohomeClient override. |
| void WaitForServiceToBeAvailable( |
| WaitForServiceToBeAvailableCallback callback) override { |
| proxy_->WaitForServiceToBeAvailable(std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void IsMounted(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeIsMounted); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void Unmount(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeUnmount); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncCheckKey(const cryptohome::Identification& cryptohome_id, |
| const std::string& key, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncCheckKey); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncMigrateKey(const cryptohome::Identification& cryptohome_id, |
| const std::string& from_key, |
| const std::string& to_key, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncMigrateKey); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(from_key); |
| writer.AppendString(to_key); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncRemove(const cryptohome::Identification& cryptohome_id, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncRemove); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void RenameCryptohome( |
| const cryptohome::Identification& cryptohome_id_from, |
| const cryptohome::Identification& cryptohome_id_to, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| const char* method_name = cryptohome::kCryptohomeRenameCryptohome; |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name); |
| |
| cryptohome::AccountIdentifier id_from_proto; |
| cryptohome::AccountIdentifier id_to_proto; |
| FillIdentificationProtobuf(cryptohome_id_from, &id_from_proto); |
| FillIdentificationProtobuf(cryptohome_id_to, &id_to_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_from_proto); |
| writer.AppendProtoAsArrayOfBytes(id_to_proto); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void GetAccountDiskUsage( |
| const cryptohome::Identification& account_id, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeGetAccountDiskUsage); |
| cryptohome::AccountIdentifier id; |
| FillIdentificationProtobuf(account_id, &id); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void GetSystemSalt( |
| DBusMethodCallback<std::vector<uint8_t>> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeGetSystemSalt); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnGetSystemSalt, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override, |
| void GetSanitizedUsername(const cryptohome::Identification& cryptohome_id, |
| DBusMethodCallback<std::string> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeGetSanitizedUsername); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnStringMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| std::string BlockingGetSanitizedUsername( |
| const cryptohome::Identification& cryptohome_id) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeGetSanitizedUsername); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| |
| std::unique_ptr<dbus::Response> response = |
| blocking_method_caller_->CallMethodAndBlock(&method_call); |
| |
| std::string sanitized_username; |
| if (response) { |
| dbus::MessageReader reader(response.get()); |
| reader.PopString(&sanitized_username); |
| } |
| |
| return sanitized_username; |
| } |
| |
| // CryptohomeClient override. |
| void AsyncMount(const cryptohome::Identification& cryptohome_id, |
| const std::string& key, |
| int flags, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncMount); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key); |
| writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING); |
| writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL); |
| // deprecated_tracked_subdirectories |
| writer.AppendArrayOfStrings(std::vector<std::string>()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncAddKey(const cryptohome::Identification& cryptohome_id, |
| const std::string& key, |
| const std::string& new_key, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncAddKey); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key); |
| writer.AppendString(new_key); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncMountGuest(AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncMountGuest); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmIsReady(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsReady); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void TpmIsEnabled(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsEnabled); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| // TODO(hashimoto): Remove this method. crbug.com/141006 |
| bool CallTpmIsEnabledAndBlock(bool* enabled) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsEnabled); |
| return CallBoolMethodAndBlock(&method_call, enabled); |
| } |
| |
| // CryptohomeClient override. |
| void TpmGetPassword(DBusMethodCallback<std::string> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmGetPassword); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnStringMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmIsOwned(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsOwned); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| // TODO(hashimoto): Remove this method. crbug.com/141012 |
| bool CallTpmIsOwnedAndBlock(bool* owned) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsOwned); |
| return CallBoolMethodAndBlock(&method_call, owned); |
| } |
| |
| // CryptohomeClient override. |
| void TpmIsBeingOwned(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsBeingOwned); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| // TODO(hashimoto): Remove this method. crbug.com/141011 |
| bool CallTpmIsBeingOwnedAndBlock(bool* owning) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsBeingOwned); |
| return CallBoolMethodAndBlock(&method_call, owning); |
| } |
| |
| // CryptohomeClient override. |
| void TpmCanAttemptOwnership(VoidDBusMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmCanAttemptOwnership); |
| CallVoidMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient overrides. |
| void TpmClearStoredPassword(VoidDBusMethodCallback callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmClearStoredPassword); |
| CallVoidMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| // TODO(hashimoto): Remove this method. crbug.com/141010 |
| bool CallTpmClearStoredPasswordAndBlock() override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmClearStoredPassword); |
| std::unique_ptr<dbus::Response> response( |
| blocking_method_caller_->CallMethodAndBlock(&method_call)); |
| return response.get() != NULL; |
| } |
| |
| // CryptohomeClient override. |
| void Pkcs11IsTpmTokenReady(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomePkcs11IsTpmTokenReady); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void Pkcs11GetTpmTokenInfo( |
| DBusMethodCallback<TpmTokenInfo> callback) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomePkcs11GetTpmTokenInfo); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnPkcs11GetTpmTokenInfo, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void Pkcs11GetTpmTokenInfoForUser( |
| const cryptohome::Identification& cryptohome_id, |
| DBusMethodCallback<TpmTokenInfo> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomePkcs11GetTpmTokenInfoForUser); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(cryptohome_id.id()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnPkcs11GetTpmTokenInfo, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| bool InstallAttributesGet(const std::string& name, |
| std::vector<uint8_t>* value, |
| bool* successful) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeInstallAttributesGet); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(name); |
| std::unique_ptr<dbus::Response> response( |
| blocking_method_caller_->CallMethodAndBlock(&method_call)); |
| if (!response.get()) |
| return false; |
| dbus::MessageReader reader(response.get()); |
| const uint8_t* bytes = NULL; |
| size_t length = 0; |
| if (!reader.PopArrayOfBytes(&bytes, &length) || |
| !reader.PopBool(successful)) |
| return false; |
| value->assign(bytes, bytes + length); |
| return true; |
| } |
| |
| // CryptohomeClient override. |
| bool InstallAttributesSet(const std::string& name, |
| const std::vector<uint8_t>& value, |
| bool* successful) override { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeInstallAttributesSet); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendString(name); |
| writer.AppendArrayOfBytes(value.data(), value.size()); |
| return CallBoolMethodAndBlock(&method_call, successful); |
| } |
| |
| // CryptohomeClient override. |
| bool InstallAttributesFinalize(bool* successful) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeInstallAttributesFinalize); |
| return CallBoolMethodAndBlock(&method_call, successful); |
| } |
| |
| // CryptohomeClient override. |
| void InstallAttributesIsReady(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeInstallAttributesIsReady); |
| return CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| bool InstallAttributesIsInvalid(bool* is_invalid) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeInstallAttributesIsInvalid); |
| return CallBoolMethodAndBlock(&method_call, is_invalid); |
| } |
| |
| // CryptohomeClient override. |
| bool InstallAttributesIsFirstInstall(bool* is_first_install) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeInstallAttributesIsFirstInstall); |
| return CallBoolMethodAndBlock(&method_call, is_first_install); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationIsPrepared(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsAttestationPrepared); |
| return CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationIsEnrolled(DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmIsAttestationEnrolled); |
| return CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncTpmAttestationCreateEnrollRequest( |
| attestation::PrivacyCAType pca_type, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncTpmAttestationCreateEnrollRequest); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendInt32(pca_type); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncTpmAttestationEnroll(attestation::PrivacyCAType pca_type, |
| const std::string& pca_response, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncTpmAttestationEnroll); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendInt32(pca_type); |
| writer.AppendArrayOfBytes( |
| reinterpret_cast<const uint8_t*>(pca_response.data()), |
| pca_response.size()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncTpmAttestationCreateCertRequest( |
| attestation::PrivacyCAType pca_type, |
| attestation::AttestationCertificateProfile certificate_profile, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& request_origin, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncTpmAttestationCreateCertRequest); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendInt32(pca_type); |
| writer.AppendInt32(certificate_profile); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(request_origin); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void AsyncTpmAttestationFinishCertRequest( |
| const std::string& pca_response, |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeAsyncTpmAttestationFinishCertRequest); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendArrayOfBytes( |
| reinterpret_cast<const uint8_t*>(pca_response.data()), |
| pca_response.size()); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationDoesKeyExist( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationDoesKeyExist); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationGetCertificate( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| DBusMethodCallback<TpmAttestationDataResult> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationGetCertificate); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnTpmAttestationDataMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationGetPublicKey( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| DBusMethodCallback<TpmAttestationDataResult> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationGetPublicKey); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnTpmAttestationDataMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationRegisterKey( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationRegisterKey); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationSignEnterpriseChallenge( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| const std::string& domain, |
| const std::string& device_id, |
| attestation::AttestationChallengeOptions options, |
| const std::string& challenge, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationSignEnterpriseVaChallenge); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendInt32(GetVerifiedAccessType()); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| writer.AppendString(domain); |
| writer.AppendArrayOfBytes( |
| reinterpret_cast<const uint8_t*>(device_id.data()), device_id.size()); |
| bool include_signed_public_key = |
| (options & attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY); |
| writer.AppendBool(include_signed_public_key); |
| writer.AppendArrayOfBytes( |
| reinterpret_cast<const uint8_t*>(challenge.data()), challenge.size()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationSignSimpleChallenge( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| const std::string& challenge, |
| AsyncMethodCallback callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationSignSimpleChallenge); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| writer.AppendArrayOfBytes( |
| reinterpret_cast<const uint8_t*>(challenge.data()), challenge.size()); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationGetKeyPayload( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| DBusMethodCallback<TpmAttestationDataResult> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationGetKeyPayload); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnTpmAttestationDataMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationSetKeyPayload( |
| attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_name, |
| const std::string& payload, |
| DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationSetKeyPayload); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_name); |
| writer.AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(payload.data()), |
| payload.size()); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void TpmAttestationDeleteKeys(attestation::AttestationKeyType key_type, |
| const cryptohome::Identification& cryptohome_id, |
| const std::string& key_prefix, |
| DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmAttestationDeleteKeys); |
| dbus::MessageWriter writer(&method_call); |
| bool is_user_specific = (key_type == attestation::KEY_USER); |
| writer.AppendBool(is_user_specific); |
| writer.AppendString(cryptohome_id.id()); |
| writer.AppendString(key_prefix); |
| CallBoolMethod(&method_call, std::move(callback)); |
| } |
| |
| // CryptohomeClient override. |
| void TpmGetVersion(DBusMethodCallback<TpmVersionInfo> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeTpmGetVersionStructured); |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnTpmGetVersion, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void GetKeyDataEx( |
| const cryptohome::Identification& id, |
| const cryptohome::AuthorizationRequest& auth, |
| const cryptohome::GetKeyDataRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(id, &id_proto); |
| |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeGetKeyDataEx); |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(auth); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void CheckKeyEx(const cryptohome::Identification& id, |
| const cryptohome::AuthorizationRequest& auth, |
| const cryptohome::CheckKeyRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| const char* method_name = cryptohome::kCryptohomeCheckKeyEx; |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| method_name); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(auth); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void MountEx(const cryptohome::Identification& id, |
| const cryptohome::AuthorizationRequest& auth, |
| const cryptohome::MountRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| const char* method_name = cryptohome::kCryptohomeMountEx; |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| method_name); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(auth); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void AddKeyEx(const cryptohome::Identification& id, |
| const cryptohome::AuthorizationRequest& auth, |
| const cryptohome::AddKeyRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| const char* method_name = cryptohome::kCryptohomeAddKeyEx; |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| method_name); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(auth); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void UpdateKeyEx( |
| const cryptohome::Identification& id, |
| const cryptohome::AuthorizationRequest& auth, |
| const cryptohome::UpdateKeyRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| const char* method_name = cryptohome::kCryptohomeUpdateKeyEx; |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| method_name); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(auth); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void RemoveKeyEx( |
| const cryptohome::Identification& id, |
| const cryptohome::AuthorizationRequest& auth, |
| const cryptohome::RemoveKeyRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| const char* method_name = cryptohome::kCryptohomeRemoveKeyEx; |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(auth); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void GetBootAttribute( |
| const cryptohome::GetBootAttributeRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| CallCryptohomeMethod(cryptohome::kCryptohomeGetBootAttribute, request, |
| std::move(callback)); |
| } |
| |
| void SetBootAttribute( |
| const cryptohome::SetBootAttributeRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| CallCryptohomeMethod(cryptohome::kCryptohomeSetBootAttribute, request, |
| std::move(callback)); |
| } |
| |
| void FlushAndSignBootAttributes( |
| const cryptohome::FlushAndSignBootAttributesRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| CallCryptohomeMethod(cryptohome::kCryptohomeFlushAndSignBootAttributes, |
| request, std::move(callback)); |
| } |
| |
| void RemoveFirmwareManagementParametersFromTpm( |
| const cryptohome::RemoveFirmwareManagementParametersRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| CallCryptohomeMethod( |
| cryptohome::kCryptohomeRemoveFirmwareManagementParameters, request, |
| std::move(callback)); |
| } |
| |
| void SetFirmwareManagementParametersInTpm( |
| const cryptohome::SetFirmwareManagementParametersRequest& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) override { |
| CallCryptohomeMethod(cryptohome::kCryptohomeSetFirmwareManagementParameters, |
| request, std::move(callback)); |
| } |
| |
| void MigrateToDircrypto(const cryptohome::Identification& cryptohome_id, |
| const cryptohome::MigrateToDircryptoRequest& request, |
| VoidDBusMethodCallback callback) override { |
| // TODO(bug758837,pmarko): Switch back to MigrateToDircrypto when its |
| // signature matches MigrateToDircryptoEx. |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeMigrateToDircryptoEx); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(cryptohome_id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| // The migration progress takes unpredicatable time depending on the |
| // user file size and the number. Setting the time limit to infinite. |
| proxy_->CallMethod( |
| &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| base::BindOnce(&CryptohomeClientImpl::OnVoidMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void NeedsDircryptoMigration(const cryptohome::Identification& cryptohome_id, |
| DBusMethodCallback<bool> callback) override { |
| dbus::MethodCall method_call( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kCryptohomeNeedsDircryptoMigration); |
| |
| cryptohome::AccountIdentifier id_proto; |
| FillIdentificationProtobuf(cryptohome_id, &id_proto); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(id_proto); |
| |
| proxy_->CallMethod( |
| &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| base::BindOnce(&CryptohomeClientImpl::OnBoolMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| protected: |
| void Init(dbus::Bus* bus) override { |
| proxy_ = bus->GetObjectProxy( |
| cryptohome::kCryptohomeServiceName, |
| dbus::ObjectPath(cryptohome::kCryptohomeServicePath)); |
| |
| blocking_method_caller_.reset(new BlockingMethodCaller(bus, proxy_)); |
| |
| proxy_->ConnectToSignal( |
| cryptohome::kCryptohomeInterface, cryptohome::kSignalAsyncCallStatus, |
| base::Bind(&CryptohomeClientImpl::AsyncCallStatusReceived, |
| weak_ptr_factory_.GetWeakPtr()), |
| base::Bind(&CryptohomeClientImpl::OnSignalConnected, |
| weak_ptr_factory_.GetWeakPtr())); |
| proxy_->ConnectToSignal( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kSignalAsyncCallStatusWithData, |
| base::Bind(&CryptohomeClientImpl::AsyncCallStatusWithDataReceived, |
| weak_ptr_factory_.GetWeakPtr()), |
| base::Bind(&CryptohomeClientImpl::OnSignalConnected, |
| weak_ptr_factory_.GetWeakPtr())); |
| proxy_->ConnectToSignal( |
| cryptohome::kCryptohomeInterface, cryptohome::kSignalLowDiskSpace, |
| base::Bind(&CryptohomeClientImpl::LowDiskSpaceReceived, |
| weak_ptr_factory_.GetWeakPtr()), |
| base::Bind(&CryptohomeClientImpl::OnSignalConnected, |
| weak_ptr_factory_.GetWeakPtr())); |
| proxy_->ConnectToSignal( |
| cryptohome::kCryptohomeInterface, |
| cryptohome::kSignalDircryptoMigrationProgress, |
| base::Bind(&CryptohomeClientImpl::DircryptoMigrationProgressReceived, |
| weak_ptr_factory_.GetWeakPtr()), |
| base::Bind(&CryptohomeClientImpl::OnSignalConnected, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| private: |
| // Handles the result of AsyncXXX methods. |
| void OnAsyncMethodCall(AsyncMethodCallback callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| int async_id = 0; |
| if (!reader.PopInt32(&async_id)) { |
| LOG(ERROR) << "Invalid response: " << response->ToString(); |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| std::move(callback).Run(async_id); |
| } |
| |
| // Handles the result of GetSystemSalt(). |
| void OnGetSystemSalt(DBusMethodCallback<std::vector<uint8_t>> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| const uint8_t* bytes = nullptr; |
| size_t length = 0; |
| if (!reader.PopArrayOfBytes(&bytes, &length)) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| std::move(callback).Run(std::vector<uint8_t>(bytes, bytes + length)); |
| } |
| |
| // Calls a method without result values. |
| void CallVoidMethod(dbus::MethodCall* method_call, |
| VoidDBusMethodCallback callback) { |
| proxy_->CallMethod( |
| method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnVoidMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| void OnVoidMethod(VoidDBusMethodCallback callback, dbus::Response* response) { |
| std::move(callback).Run(response != nullptr); |
| } |
| |
| // Calls a method with a bool value reult and block. |
| bool CallBoolMethodAndBlock(dbus::MethodCall* method_call, |
| bool* result) { |
| std::unique_ptr<dbus::Response> response( |
| blocking_method_caller_->CallMethodAndBlock(method_call)); |
| if (!response.get()) |
| return false; |
| dbus::MessageReader reader(response.get()); |
| return reader.PopBool(result); |
| } |
| |
| // Calls a method with a bool value result. |
| void CallBoolMethod(dbus::MethodCall* method_call, |
| DBusMethodCallback<bool> callback) { |
| proxy_->CallMethod( |
| method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBoolMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| // Handles responses for methods with a bool value result. |
| void OnBoolMethod(DBusMethodCallback<bool> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| bool result = false; |
| if (!reader.PopBool(&result)) { |
| LOG(ERROR) << "Invalid response: " << response->ToString(); |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| std::move(callback).Run(result); |
| } |
| |
| // Handles responses for methods with a string value result. |
| void OnStringMethod(DBusMethodCallback<std::string> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| std::string result; |
| if (!reader.PopString(&result)) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| std::move(callback).Run(std::move(result)); |
| } |
| |
| // Handles responses for methods with a bool result and data. |
| void OnTpmAttestationDataMethod( |
| DBusMethodCallback<TpmAttestationDataResult> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| TpmAttestationDataResult result; |
| const uint8_t* data_buffer = nullptr; |
| size_t data_length = 0; |
| if (!reader.PopArrayOfBytes(&data_buffer, &data_length) || |
| !reader.PopBool(&result.success)) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| result.data.assign(reinterpret_cast<const char*>(data_buffer), data_length); |
| std::move(callback).Run(std::move(result)); |
| } |
| |
| // Handles responses for methods with a BaseReply protobuf method. |
| void OnBaseReplyMethod(DBusMethodCallback<cryptohome::BaseReply> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| cryptohome::BaseReply result; |
| dbus::MessageReader reader(response); |
| if (!reader.PopArrayOfBytesAsProto(&result)) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| std::move(callback).Run(std::move(result)); |
| } |
| |
| // Handles responses for Pkcs11GetTpmTokenInfo and |
| // Pkcs11GetTpmTokenInfoForUser. |
| void OnPkcs11GetTpmTokenInfo(DBusMethodCallback<TpmTokenInfo> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| TpmTokenInfo token_info; |
| if (!reader.PopString(&token_info.label) || |
| !reader.PopString(&token_info.user_pin) || |
| !reader.PopInt32(&token_info.slot)) { |
| std::move(callback).Run(base::nullopt); |
| LOG(ERROR) << "Invalid response: " << response->ToString(); |
| return; |
| } |
| std::move(callback).Run(std::move(token_info)); |
| } |
| |
| // Handles responses for TpmGetVersion. |
| void OnTpmGetVersion(DBusMethodCallback<TpmVersionInfo> callback, |
| dbus::Response* response) { |
| if (!response) { |
| std::move(callback).Run(base::nullopt); |
| return; |
| } |
| dbus::MessageReader reader(response); |
| TpmVersionInfo version; |
| if (!reader.PopUint32(&version.family) || |
| !reader.PopUint64(&version.spec_level) || |
| !reader.PopUint32(&version.manufacturer) || |
| !reader.PopUint32(&version.tpm_model) || |
| !reader.PopUint64(&version.firmware_version) || |
| !reader.PopString(&version.vendor_specific)) { |
| std::move(callback).Run(base::nullopt); |
| LOG(ERROR) << "Invalid response: " << response->ToString(); |
| return; |
| } |
| std::move(callback).Run(std::move(version)); |
| } |
| |
| // Handles AsyncCallStatus signal. |
| void AsyncCallStatusReceived(dbus::Signal* signal) { |
| dbus::MessageReader reader(signal); |
| int async_id = 0; |
| bool return_status = false; |
| int return_code = 0; |
| if (!reader.PopInt32(&async_id) || |
| !reader.PopBool(&return_status) || |
| !reader.PopInt32(&return_code)) { |
| LOG(ERROR) << "Invalid signal: " << signal->ToString(); |
| return; |
| } |
| for (auto& observer : observer_list_) |
| observer.AsyncCallStatus(async_id, return_status, return_code); |
| } |
| |
| // Handles AsyncCallStatusWithData signal. |
| void AsyncCallStatusWithDataReceived(dbus::Signal* signal) { |
| dbus::MessageReader reader(signal); |
| int async_id = 0; |
| bool return_status = false; |
| const uint8_t* return_data_buffer = NULL; |
| size_t return_data_length = 0; |
| if (!reader.PopInt32(&async_id) || |
| !reader.PopBool(&return_status) || |
| !reader.PopArrayOfBytes(&return_data_buffer, &return_data_length)) { |
| LOG(ERROR) << "Invalid signal: " << signal->ToString(); |
| return; |
| } |
| std::string return_data(reinterpret_cast<const char*>(return_data_buffer), |
| return_data_length); |
| for (auto& observer : observer_list_) |
| observer.AsyncCallStatusWithData(async_id, return_status, return_data); |
| } |
| |
| // Handles LowDiskSpace signal. |
| void LowDiskSpaceReceived(dbus::Signal* signal) { |
| dbus::MessageReader reader(signal); |
| uint64_t disk_free_bytes = 0; |
| if (!reader.PopUint64(&disk_free_bytes)) { |
| LOG(ERROR) << "Invalid signal: " << signal->ToString(); |
| return; |
| } |
| for (auto& observer : observer_list_) |
| observer.LowDiskSpace(disk_free_bytes); |
| } |
| |
| // Handles DircryptoMigrationProgess signal. |
| void DircryptoMigrationProgressReceived(dbus::Signal* signal) { |
| dbus::MessageReader reader(signal); |
| int status = 0; |
| uint64_t current_bytes = 0, total_bytes = 0; |
| if (!reader.PopInt32(&status) || !reader.PopUint64(¤t_bytes) || |
| !reader.PopUint64(&total_bytes)) { |
| LOG(ERROR) << "Invalid signal: " << signal->ToString(); |
| return; |
| } |
| for (auto& observer : observer_list_) { |
| observer.DircryptoMigrationProgress( |
| static_cast<cryptohome::DircryptoMigrationStatus>(status), |
| current_bytes, total_bytes); |
| } |
| } |
| |
| // Handles the result of signal connection setup. |
| void OnSignalConnected(const std::string& interface, |
| const std::string& signal, |
| bool succeeded) { |
| LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " << |
| signal << " failed."; |
| } |
| |
| // Makes an asynchronous D-Bus call, using cryptohome interface. |method_name| |
| // is the name of the method to be called. |request| is the specific request |
| // for the method, including the data required to be sent. |callback| is |
| // invoked when the response is received. |
| void CallCryptohomeMethod( |
| const std::string& method_name, |
| const google::protobuf::MessageLite& request, |
| DBusMethodCallback<cryptohome::BaseReply> callback) { |
| dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name); |
| |
| dbus::MessageWriter writer(&method_call); |
| writer.AppendProtoAsArrayOfBytes(request); |
| |
| proxy_->CallMethod( |
| &method_call, kTpmDBusTimeoutMs, |
| base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, |
| weak_ptr_factory_.GetWeakPtr(), std::move(callback))); |
| } |
| |
| dbus::ObjectProxy* proxy_ = nullptr; |
| base::ObserverList<Observer> observer_list_; |
| std::unique_ptr<BlockingMethodCaller> blocking_method_caller_; |
| |
| // Note: This should remain the last member so it'll be destroyed and |
| // invalidate its weak pointers before any other members are destroyed. |
| base::WeakPtrFactory<CryptohomeClientImpl> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CryptohomeClientImpl); |
| }; |
| |
| } // namespace |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // CryptohomeClient |
| |
| CryptohomeClient::CryptohomeClient() = default; |
| |
| CryptohomeClient::~CryptohomeClient() = default; |
| |
| // static |
| CryptohomeClient* CryptohomeClient::Create() { |
| return new CryptohomeClientImpl(); |
| } |
| |
| // static |
| std::string CryptohomeClient::GetStubSanitizedUsername( |
| const cryptohome::Identification& cryptohome_id) { |
| return cryptohome_id.id() + kUserIdStubHashSuffix; |
| } |
| |
| } // namespace chromeos |