summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chromeos/chromeos.gyp1
-rw-r--r--chromeos/cryptohome/system_salt_getter.cc17
-rw-r--r--chromeos/cryptohome/system_salt_getter.h7
-rw-r--r--chromeos/cryptohome/system_salt_getter_unittest.cc65
-rw-r--r--chromeos/dbus/cryptohome_client.cc6
-rw-r--r--chromeos/dbus/cryptohome_client.h7
-rw-r--r--chromeos/dbus/fake_cryptohome_client.cc23
-rw-r--r--chromeos/dbus/fake_cryptohome_client.h10
-rw-r--r--chromeos/dbus/mock_cryptohome_client.h2
9 files changed, 133 insertions, 5 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index c7ce72d..2415173 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -465,6 +465,7 @@
'app_mode/kiosk_oem_manifest_parser_unittest.cc',
'attestation/attestation_flow_unittest.cc',
'audio/cras_audio_handler_unittest.cc',
+ 'cryptohome/system_salt_getter_unittest.cc',
'dbus/blocking_method_caller_unittest.cc',
'dbus/cros_disks_client_unittest.cc',
'dbus/gsm_sms_client_unittest.cc',
diff --git a/chromeos/cryptohome/system_salt_getter.cc b/chromeos/cryptohome/system_salt_getter.cc
index c139041..f299f0f 100644
--- a/chromeos/cryptohome/system_salt_getter.cc
+++ b/chromeos/cryptohome/system_salt_getter.cc
@@ -19,7 +19,7 @@ SystemSaltGetter* g_system_salt_getter = NULL;
} // namespace
-SystemSaltGetter::SystemSaltGetter() {
+SystemSaltGetter::SystemSaltGetter() : weak_ptr_factory_(this) {
}
SystemSaltGetter::~SystemSaltGetter() {
@@ -27,9 +27,10 @@ SystemSaltGetter::~SystemSaltGetter() {
void SystemSaltGetter::GetSystemSalt(
const GetSystemSaltCallback& callback) {
- // TODO(hashimoto): Stop using GetSystemSaltSynt(). crbug.com/141009
- base::MessageLoopProxy::current()->PostTask(
- FROM_HERE, base::Bind(callback, GetSystemSaltSync()));
+ DBusThreadManager::Get()->GetCryptohomeClient()->WaitForServiceToBeAvailable(
+ base::Bind(&SystemSaltGetter::GetSystemSaltInternal,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
}
std::string SystemSaltGetter::GetSystemSaltSync() {
@@ -41,6 +42,14 @@ std::string SystemSaltGetter::GetCachedSystemSalt() {
return system_salt_;
}
+void SystemSaltGetter::GetSystemSaltInternal(
+ const GetSystemSaltCallback& callback,
+ bool service_is_available) {
+ LOG_IF(ERROR, !service_is_available) << "WaitForServiceToBeAvailable failed.";
+ // TODO(hashimoto): Stop using GetSystemSaltSync(). crbug.com/141009
+ callback.Run(GetSystemSaltSync());
+}
+
void SystemSaltGetter::LoadSystemSalt() {
if (!system_salt_.empty())
return;
diff --git a/chromeos/cryptohome/system_salt_getter.h b/chromeos/cryptohome/system_salt_getter.h
index d154ff2..a47b617 100644
--- a/chromeos/cryptohome/system_salt_getter.h
+++ b/chromeos/cryptohome/system_salt_getter.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/memory/weak_ptr.h"
#include "chromeos/chromeos_export.h"
namespace chromeos {
@@ -49,11 +50,17 @@ class CHROMEOS_EXPORT SystemSaltGetter {
~SystemSaltGetter();
private:
+ // Used to implement GetSystemSalt().
+ void GetSystemSaltInternal(const GetSystemSaltCallback& callback,
+ bool service_is_available);
+
// Loads the system salt from cryptohome and caches it.
void LoadSystemSalt();
std::string system_salt_;
+ base::WeakPtrFactory<SystemSaltGetter> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(SystemSaltGetter);
};
diff --git a/chromeos/cryptohome/system_salt_getter_unittest.cc b/chromeos/cryptohome/system_salt_getter_unittest.cc
new file mode 100644
index 0000000..84403e4
--- /dev/null
+++ b/chromeos/cryptohome/system_salt_getter_unittest.cc
@@ -0,0 +1,65 @@
+// Copyright 2013 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/cryptohome/system_salt_getter.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "chromeos/dbus/fake_cryptohome_client.h"
+#include "chromeos/dbus/fake_dbus_thread_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace {
+
+// Used as a GetSystemSaltCallback.
+void CopySystemSalt(std::string* out_system_salt,
+ const std::string& system_salt) {
+ *out_system_salt = system_salt;
+}
+
+class SystemSaltGetterTest : public testing::Test {
+ protected:
+ SystemSaltGetterTest() : fake_cryptohome_client_(NULL) {}
+
+ virtual void SetUp() OVERRIDE {
+ FakeDBusThreadManager* dbus_thread_manager = new FakeDBusThreadManager;
+ fake_cryptohome_client_ = dbus_thread_manager->fake_cryptohome_client();
+ DBusThreadManager::InitializeForTesting(dbus_thread_manager);
+
+ EXPECT_FALSE(SystemSaltGetter::IsInitialized());
+ SystemSaltGetter::Initialize();
+ ASSERT_TRUE(SystemSaltGetter::IsInitialized());
+ ASSERT_TRUE(SystemSaltGetter::Get());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ SystemSaltGetter::Shutdown();
+ DBusThreadManager::Shutdown();
+ }
+
+ base::MessageLoopForUI message_loop_;
+ FakeCryptohomeClient* fake_cryptohome_client_;
+};
+
+TEST_F(SystemSaltGetterTest, GetSystemSalt) {
+ // Try to get system salt before the service becomes available.
+ fake_cryptohome_client_->SetServiceIsAvailable(false);
+ std::string system_salt;
+ SystemSaltGetter::Get()->GetSystemSalt(
+ base::Bind(&CopySystemSalt, &system_salt));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(system_salt.empty()); // System salt is not returned yet.
+
+ // Service becomes available.
+ fake_cryptohome_client_->SetServiceIsAvailable(true);
+ const std::string expected_system_salt =
+ SystemSaltGetter::ConvertRawSaltToHexString(
+ FakeCryptohomeClient::GetStubSystemSalt());
+ EXPECT_EQ(expected_system_salt, system_salt); // System salt is returned.
+}
+
+} // namespace
+} // namespace chromeos
diff --git a/chromeos/dbus/cryptohome_client.cc b/chromeos/dbus/cryptohome_client.cc
index 79a6561..ca2d48a 100644
--- a/chromeos/dbus/cryptohome_client.cc
+++ b/chromeos/dbus/cryptohome_client.cc
@@ -45,6 +45,12 @@ class CryptohomeClientImpl : public CryptohomeClient {
}
// CryptohomeClient override.
+ virtual void WaitForServiceToBeAvailable(
+ const WaitForServiceToBeAvailableCallback& callback) OVERRIDE {
+ proxy_->WaitForServiceToBeAvailable(callback);
+ }
+
+ // CryptohomeClient override.
virtual void IsMounted(const BoolDBusMethodCallback& callback) OVERRIDE {
dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
cryptohome::kCryptohomeIsMounted);
diff --git a/chromeos/dbus/cryptohome_client.h b/chromeos/dbus/cryptohome_client.h
index cc4b9d7..036cf64 100644
--- a/chromeos/dbus/cryptohome_client.h
+++ b/chromeos/dbus/cryptohome_client.h
@@ -35,6 +35,9 @@ class CHROMEOS_EXPORT CryptohomeClient : public DBusClient {
AsyncCallStatusWithDataHandler;
// A callback to handle responses of AsyncXXX methods.
typedef base::Callback<void(int async_id)> AsyncMethodCallback;
+ // A callback for WaitForServiceToBeAvailable().
+ typedef base::Callback<void(bool service_is_ready)>
+ WaitForServiceToBeAvailableCallback;
// A callback to handle responses of Pkcs11GetTpmTokenInfo method. The result
// of the D-Bus call is in |call_status|. On success, |label| holds the
// PKCS #11 token label. This is not useful in practice to identify a token
@@ -73,6 +76,10 @@ class CHROMEOS_EXPORT CryptohomeClient : public DBusClient {
// Resets AsyncCallStatus signal handlers.
virtual void ResetAsyncCallStatusHandlers() = 0;
+ // Runs the callback as soon as the service becomes available.
+ virtual void WaitForServiceToBeAvailable(
+ const WaitForServiceToBeAvailableCallback& callback) = 0;
+
// Calls IsMounted method and returns true when the call succeeds.
virtual void IsMounted(const BoolDBusMethodCallback& callback) = 0;
diff --git a/chromeos/dbus/fake_cryptohome_client.cc b/chromeos/dbus/fake_cryptohome_client.cc
index 7b40854..d23be71 100644
--- a/chromeos/dbus/fake_cryptohome_client.cc
+++ b/chromeos/dbus/fake_cryptohome_client.cc
@@ -13,7 +13,8 @@
namespace chromeos {
FakeCryptohomeClient::FakeCryptohomeClient()
- : async_call_id_(1),
+ : service_is_available_(true),
+ async_call_id_(1),
tpm_is_ready_counter_(0),
unmount_result_(true),
locked_(false),
@@ -36,6 +37,16 @@ void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
async_call_status_data_handler_.Reset();
}
+void FakeCryptohomeClient::WaitForServiceToBeAvailable(
+ const WaitForServiceToBeAvailableCallback& callback) {
+ if (service_is_available_) {
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(callback, true));
+ } else {
+ pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
+ }
+}
+
void FakeCryptohomeClient::IsMounted(
const BoolDBusMethodCallback& callback) {
base::MessageLoop::current()->PostTask(
@@ -368,6 +379,16 @@ void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
}
+void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
+ service_is_available_ = is_available;
+ if (is_available) {
+ std::vector<WaitForServiceToBeAvailableCallback> callbacks;
+ callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
+ for (size_t i = 0; i < callbacks.size(); ++i)
+ callbacks[i].Run(is_available);
+ }
+}
+
// static
std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
const char kStubSystemSalt[] = "stub_system_salt";
diff --git a/chromeos/dbus/fake_cryptohome_client.h b/chromeos/dbus/fake_cryptohome_client.h
index 4f045ec..3c960e8 100644
--- a/chromeos/dbus/fake_cryptohome_client.h
+++ b/chromeos/dbus/fake_cryptohome_client.h
@@ -23,6 +23,8 @@ class CHROMEOS_EXPORT FakeCryptohomeClient : public CryptohomeClient {
const AsyncCallStatusHandler& handler,
const AsyncCallStatusWithDataHandler& data_handler) OVERRIDE;
virtual void ResetAsyncCallStatusHandlers() OVERRIDE;
+ virtual void WaitForServiceToBeAvailable(
+ const WaitForServiceToBeAvailableCallback& callback) OVERRIDE;
virtual void IsMounted(const BoolDBusMethodCallback& callback) OVERRIDE;
virtual bool Unmount(bool* success) OVERRIDE;
virtual void AsyncCheckKey(const std::string& username,
@@ -151,6 +153,10 @@ class CHROMEOS_EXPORT FakeCryptohomeClient : public CryptohomeClient {
const std::string& payload,
const BoolDBusMethodCallback& callback) OVERRIDE;
+ // Changes the behavior of WaitForServiceToBeAvailable(). This method runs
+ // pending callbacks if is_available is true.
+ void SetServiceIsAvailable(bool is_available);
+
// Sets the unmount result of Unmount() call.
void set_unmount_result(bool result) {
unmount_result_= result;
@@ -169,12 +175,16 @@ class CHROMEOS_EXPORT FakeCryptohomeClient : public CryptohomeClient {
void ReturnAsyncMethodResultInternal(const AsyncMethodCallback& callback,
bool returns_data);
+ bool service_is_available_;
int async_call_id_;
AsyncCallStatusHandler async_call_status_handler_;
AsyncCallStatusWithDataHandler async_call_status_data_handler_;
int tpm_is_ready_counter_;
bool unmount_result_;
+ std::vector<WaitForServiceToBeAvailableCallback>
+ pending_wait_for_service_to_be_available_callbacks_;
+
// A stub store for InstallAttributes, mapping an attribute name to the
// associated data blob. Used to implement InstallAttributesSet and -Get.
std::map<std::string, std::vector<uint8> > install_attrs_;
diff --git a/chromeos/dbus/mock_cryptohome_client.h b/chromeos/dbus/mock_cryptohome_client.h
index 8cb4c6b..cdb1ad8 100644
--- a/chromeos/dbus/mock_cryptohome_client.h
+++ b/chromeos/dbus/mock_cryptohome_client.h
@@ -22,6 +22,8 @@ class MockCryptohomeClient : public CryptohomeClient {
void(const AsyncCallStatusHandler& handler,
const AsyncCallStatusWithDataHandler& data_handler));
MOCK_METHOD0(ResetAsyncCallStatusHandlers, void());
+ MOCK_METHOD1(WaitForServiceToBeAvailable,
+ void(const WaitForServiceToBeAvailableCallback& callback));
MOCK_METHOD1(IsMounted, void(const BoolDBusMethodCallback& callback));
MOCK_METHOD1(Unmount, bool(bool* success));
MOCK_METHOD3(AsyncCheckKey,