1 // Copyright 2014 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.
5 #include "chromeos/cryptohome/homedir_methods.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "chromeos/dbus/cryptohome/rpc.pb.h"
12 #include "chromeos/dbus/cryptohome_client.h"
13 #include "chromeos/dbus/dbus_method_call_status.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/dbus/mock_cryptohome_client.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::Invoke
;
21 using testing::WithArg
;
23 namespace cryptohome
{
27 MATCHER_P(EqualsProto
, expected_proto
, "") {
28 std::string expected_value
;
29 expected_proto
.SerializeToString(&expected_value
);
30 std::string actual_value
;
31 arg
.SerializeToString(&actual_value
);
32 return actual_value
== expected_value
;
37 const char kUserID
[] = "user@example.com";
38 const char kKeyLabel
[] = "key_label";
40 const int64 kKeyRevision
= 123;
41 const char kProviderData1Name
[] = "data_1";
42 const int64 kProviderData1Number
= 12345;
43 const char kProviderData2Name
[] = "data_2";
44 const char kProviderData2Bytes
[] = "data_2 bytes";
46 class HomedirMethodsTest
: public testing::Test
{
49 ~HomedirMethodsTest() override
;
52 void SetUp() override
;
53 void TearDown() override
;
55 void RunProtobufMethodCallback(
56 const chromeos::CryptohomeClient::ProtobufMethodCallback
& callback
);
58 void StoreGetKeyDataExResult(
60 MountError return_code
,
61 const std::vector
<KeyDefinition
>& key_definitions
);
64 chromeos::MockCryptohomeClient
* cryptohome_client_
;
66 // The reply that |cryptohome_client_| will make.
67 cryptohome::BaseReply cryptohome_reply_
;
69 // The results of the most recent |HomedirMethods| method call.
71 MountError return_code_
;
72 std::vector
<KeyDefinition
> key_definitions_
;
75 DISALLOW_COPY_AND_ASSIGN(HomedirMethodsTest
);
78 HomedirMethodsTest::HomedirMethodsTest() : cryptohome_client_(NULL
),
80 return_code_(MOUNT_ERROR_FATAL
) {
83 HomedirMethodsTest::~HomedirMethodsTest() {
86 void HomedirMethodsTest::SetUp() {
87 scoped_ptr
<chromeos::MockCryptohomeClient
> cryptohome_client(
88 new chromeos::MockCryptohomeClient
);
89 cryptohome_client_
= cryptohome_client
.get();
90 chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient(
91 cryptohome_client
.Pass());
92 HomedirMethods::Initialize();
95 void HomedirMethodsTest::TearDown() {
96 HomedirMethods::Shutdown();
97 chromeos::DBusThreadManager::Shutdown();
100 void HomedirMethodsTest::RunProtobufMethodCallback(
101 const chromeos::CryptohomeClient::ProtobufMethodCallback
& callback
) {
102 callback
.Run(chromeos::DBUS_METHOD_CALL_SUCCESS
,
107 void HomedirMethodsTest::StoreGetKeyDataExResult(
109 MountError return_code
,
110 const std::vector
<KeyDefinition
>& key_definitions
) {
112 return_code_
= return_code
;
113 key_definitions_
= key_definitions
;
116 // Verifies that the result of a GetKeyDataEx() call is correctly parsed.
117 TEST_F(HomedirMethodsTest
, GetKeyDataEx
) {
118 AccountIdentifier expected_id
;
119 expected_id
.set_email(kUserID
);
120 const cryptohome::AuthorizationRequest expected_auth
;
121 cryptohome::GetKeyDataRequest expected_request
;
122 expected_request
.mutable_key()->mutable_data()->set_label(kKeyLabel
);
124 EXPECT_CALL(*cryptohome_client_
,
125 GetKeyDataEx(EqualsProto(expected_id
),
126 EqualsProto(expected_auth
),
127 EqualsProto(expected_request
),
130 .WillOnce(WithArg
<3>(Invoke(
132 &HomedirMethodsTest::RunProtobufMethodCallback
)));
134 // Set up the reply that |cryptohome_client_| will make.
135 cryptohome::GetKeyDataReply
* reply
=
136 cryptohome_reply_
.MutableExtension(cryptohome::GetKeyDataReply::reply
);
137 KeyData
* key_data
= reply
->add_key_data();
138 key_data
->set_type(KeyData::KEY_TYPE_PASSWORD
);
139 key_data
->set_label(kKeyLabel
);
140 key_data
->mutable_privileges()->set_update(false);
141 key_data
->set_revision(kKeyRevision
);
142 key_data
->add_authorization_data()->set_type(
143 KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256
);
144 KeyProviderData
* data
= key_data
->mutable_provider_data();
145 KeyProviderData::Entry
* entry
= data
->add_entry();
146 entry
->set_name(kProviderData1Name
);
147 entry
->set_number(kProviderData1Number
);
148 entry
= data
->add_entry();
149 entry
->set_name(kProviderData2Name
);
150 entry
->set_bytes(kProviderData2Bytes
);
152 // Call GetKeyDataEx().
153 HomedirMethods::GetInstance()->GetKeyDataEx(
154 Identification(kUserID
),
156 base::Bind(&HomedirMethodsTest::StoreGetKeyDataExResult
,
157 base::Unretained(this)));
159 // Verify that the call was successful and the result was correctly parsed.
160 EXPECT_TRUE(success_
);
161 EXPECT_EQ(MOUNT_ERROR_NONE
, return_code_
);
162 ASSERT_EQ(1u, key_definitions_
.size());
163 const KeyDefinition
& key_definition
= key_definitions_
.front();
164 EXPECT_EQ(KeyDefinition::TYPE_PASSWORD
, key_definition
.type
);
165 EXPECT_EQ(PRIV_MOUNT
| PRIV_ADD
| PRIV_REMOVE
,
166 key_definition
.privileges
);
167 EXPECT_EQ(kKeyRevision
, key_definition
.revision
);
168 ASSERT_EQ(1u, key_definition
.authorization_data
.size());
169 EXPECT_EQ(KeyDefinition::AuthorizationData::TYPE_HMACSHA256
,
170 key_definition
.authorization_data
.front().type
);
171 ASSERT_EQ(2u, key_definition
.provider_data
.size());
172 const KeyDefinition::ProviderData
* provider_data
=
173 &key_definition
.provider_data
[0];
174 EXPECT_EQ(kProviderData1Name
, provider_data
->name
);
175 ASSERT_TRUE(provider_data
->number
);
176 EXPECT_EQ(kProviderData1Number
, *provider_data
->number
.get());
177 EXPECT_FALSE(provider_data
->bytes
);
178 provider_data
= &key_definition
.provider_data
[1];
179 EXPECT_EQ(kProviderData2Name
, provider_data
->name
);
180 EXPECT_FALSE(provider_data
->number
);
181 ASSERT_TRUE(provider_data
->bytes
);
182 EXPECT_EQ(kProviderData2Bytes
, *provider_data
->bytes
.get());
185 } // namespace cryptohome