1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <string>
18
19 #include <brillo/bind_lambda.h>
20 #include <brillo/dbus/dbus_object_test_helpers.h>
21 #include <dbus/mock_bus.h>
22 #include <dbus/mock_exported_object.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25
26 #include "tpm_manager/common/mock_tpm_nvram_interface.h"
27 #include "tpm_manager/common/mock_tpm_ownership_interface.h"
28 #include "tpm_manager/common/tpm_manager_constants.h"
29 #include "tpm_manager/common/tpm_nvram_dbus_interface.h"
30 #include "tpm_manager/common/tpm_ownership_dbus_interface.h"
31 #include "tpm_manager/server/dbus_service.h"
32
33 using testing::_;
34 using testing::Invoke;
35 using testing::NiceMock;
36 using testing::Return;
37 using testing::StrictMock;
38 using testing::WithArgs;
39
40 namespace tpm_manager {
41
42 class DBusServiceTest : public testing::Test {
43 public:
44 ~DBusServiceTest() override = default;
SetUp()45 void SetUp() override {
46 dbus::Bus::Options options;
47 mock_bus_ = new NiceMock<dbus::MockBus>(options);
48 dbus::ObjectPath path(kTpmManagerServicePath);
49 mock_exported_object_ = new NiceMock<dbus::MockExportedObject>(
50 mock_bus_.get(), path);
51 ON_CALL(*mock_bus_, GetExportedObject(path))
52 .WillByDefault(Return(mock_exported_object_.get()));
53 dbus_service_.reset(new DBusService(mock_bus_,
54 &mock_nvram_service_,
55 &mock_ownership_service_));
56 dbus_service_->Register(brillo::dbus_utils::AsyncEventSequencer::
57 GetDefaultCompletionAction());
58 }
59
60 template<typename RequestProtobufType, typename ReplyProtobufType>
ExecuteMethod(const std::string & method_name,const RequestProtobufType & request,ReplyProtobufType * reply,const std::string & interface)61 void ExecuteMethod(const std::string& method_name,
62 const RequestProtobufType& request,
63 ReplyProtobufType* reply,
64 const std::string& interface) {
65 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(method_name,
66 interface);
67 dbus::MessageWriter writer(call.get());
68 writer.AppendProtoAsArrayOfBytes(request);
69 auto response = brillo::dbus_utils::testing::CallMethod(
70 dbus_service_->dbus_object_, call.get());
71 dbus::MessageReader reader(response.get());
72 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(reply));
73 }
74
75 protected:
CreateMethodCall(const std::string & method_name,const std::string & interface)76 std::unique_ptr<dbus::MethodCall> CreateMethodCall(
77 const std::string& method_name, const std::string& interface) {
78 std::unique_ptr<dbus::MethodCall> call(new dbus::MethodCall(
79 interface, method_name));
80 call->SetSerial(1);
81 return call;
82 }
83
84 scoped_refptr<dbus::MockBus> mock_bus_;
85 scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
86 StrictMock<MockTpmNvramInterface> mock_nvram_service_;
87 StrictMock<MockTpmOwnershipInterface> mock_ownership_service_;
88 std::unique_ptr<DBusService> dbus_service_;
89 };
90
TEST_F(DBusServiceTest,CopyableCallback)91 TEST_F(DBusServiceTest, CopyableCallback) {
92 EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
93 .WillOnce(WithArgs<1>(Invoke([](
94 const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
95 // Copy the callback, then call the original.
96 GetTpmStatusReply reply;
97 base::Closure copy = base::Bind(callback, reply);
98 callback.Run(reply);
99 })));
100 GetTpmStatusRequest request;
101 GetTpmStatusReply reply;
102 ExecuteMethod(kGetTpmStatus, request, &reply, kTpmOwnershipInterface);
103 }
104
TEST_F(DBusServiceTest,GetTpmStatus)105 TEST_F(DBusServiceTest, GetTpmStatus) {
106 GetTpmStatusRequest request;
107 EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
108 .WillOnce(Invoke([](
109 const GetTpmStatusRequest& request,
110 const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
111 GetTpmStatusReply reply;
112 reply.set_status(STATUS_SUCCESS);
113 reply.set_enabled(true);
114 reply.set_owned(true);
115 reply.set_dictionary_attack_counter(3);
116 reply.set_dictionary_attack_threshold(4);
117 reply.set_dictionary_attack_lockout_in_effect(true);
118 reply.set_dictionary_attack_lockout_seconds_remaining(5);
119 callback.Run(reply);
120 }));
121 GetTpmStatusReply reply;
122 ExecuteMethod(kGetTpmStatus, request, &reply, kTpmOwnershipInterface);
123 EXPECT_EQ(STATUS_SUCCESS, reply.status());
124 EXPECT_TRUE(reply.enabled());
125 EXPECT_TRUE(reply.owned());
126 EXPECT_EQ(3, reply.dictionary_attack_counter());
127 EXPECT_EQ(4, reply.dictionary_attack_threshold());
128 EXPECT_TRUE(reply.dictionary_attack_lockout_in_effect());
129 EXPECT_EQ(5, reply.dictionary_attack_lockout_seconds_remaining());
130 }
131
TEST_F(DBusServiceTest,TakeOwnership)132 TEST_F(DBusServiceTest, TakeOwnership) {
133 EXPECT_CALL(mock_ownership_service_, TakeOwnership(_, _))
134 .WillOnce(Invoke([](
135 const TakeOwnershipRequest& request,
136 const TpmOwnershipInterface::TakeOwnershipCallback& callback) {
137 TakeOwnershipReply reply;
138 reply.set_status(STATUS_SUCCESS);
139 callback.Run(reply);
140 }));
141 TakeOwnershipRequest request;
142 TakeOwnershipReply reply;
143 ExecuteMethod(kTakeOwnership, request, &reply, kTpmOwnershipInterface);
144 EXPECT_EQ(STATUS_SUCCESS, reply.status());
145 }
146
TEST_F(DBusServiceTest,RemoveOwnerDependency)147 TEST_F(DBusServiceTest, RemoveOwnerDependency) {
148 std::string owner_dependency("owner_dependency");
149 RemoveOwnerDependencyRequest request;
150 request.set_owner_dependency(owner_dependency);
151 EXPECT_CALL(mock_ownership_service_, RemoveOwnerDependency(_, _))
152 .WillOnce(Invoke([&owner_dependency](
153 const RemoveOwnerDependencyRequest& request,
154 const TpmOwnershipInterface::RemoveOwnerDependencyCallback& callback)
155 {
156 EXPECT_TRUE(request.has_owner_dependency());
157 EXPECT_EQ(owner_dependency, request.owner_dependency());
158 RemoveOwnerDependencyReply reply;
159 reply.set_status(STATUS_SUCCESS);
160 callback.Run(reply);
161 }));
162 RemoveOwnerDependencyReply reply;
163 ExecuteMethod(kRemoveOwnerDependency,
164 request,
165 &reply,
166 kTpmOwnershipInterface);
167 EXPECT_EQ(STATUS_SUCCESS, reply.status());
168 }
169
TEST_F(DBusServiceTest,DefineNvram)170 TEST_F(DBusServiceTest, DefineNvram) {
171 uint32_t nvram_index = 5;
172 size_t nvram_length = 32;
173 DefineNvramRequest request;
174 request.set_index(nvram_index);
175 request.set_length(nvram_length);
176 EXPECT_CALL(mock_nvram_service_, DefineNvram(_, _))
177 .WillOnce(Invoke([nvram_index, nvram_length](
178 const DefineNvramRequest& request,
179 const TpmNvramInterface::DefineNvramCallback& callback) {
180 EXPECT_TRUE(request.has_index());
181 EXPECT_EQ(nvram_index, request.index());
182 EXPECT_TRUE(request.has_length());
183 EXPECT_EQ(nvram_length, request.length());
184 DefineNvramReply reply;
185 reply.set_status(STATUS_SUCCESS);
186 callback.Run(reply);
187 }));
188 DefineNvramReply reply;
189 ExecuteMethod(kDefineNvram, request, &reply, kTpmNvramInterface);
190 EXPECT_EQ(STATUS_SUCCESS, reply.status());
191 }
192
TEST_F(DBusServiceTest,DestroyNvram)193 TEST_F(DBusServiceTest, DestroyNvram) {
194 uint32_t nvram_index = 5;
195 DestroyNvramRequest request;
196 request.set_index(nvram_index);
197 EXPECT_CALL(mock_nvram_service_, DestroyNvram(_, _))
198 .WillOnce(Invoke([nvram_index](
199 const DestroyNvramRequest& request,
200 const TpmNvramInterface::DestroyNvramCallback& callback) {
201 EXPECT_TRUE(request.has_index());
202 EXPECT_EQ(nvram_index, request.index());
203 DestroyNvramReply reply;
204 reply.set_status(STATUS_SUCCESS);
205 callback.Run(reply);
206 }));
207 DestroyNvramReply reply;
208 ExecuteMethod(kDestroyNvram, request, &reply, kTpmNvramInterface);
209 EXPECT_EQ(STATUS_SUCCESS, reply.status());
210 }
211
TEST_F(DBusServiceTest,WriteNvram)212 TEST_F(DBusServiceTest, WriteNvram) {
213 uint32_t nvram_index = 5;
214 std::string nvram_data("nvram_data");
215 WriteNvramRequest request;
216 request.set_index(nvram_index);
217 request.set_data(nvram_data);
218 EXPECT_CALL(mock_nvram_service_, WriteNvram(_, _))
219 .WillOnce(Invoke([nvram_index, nvram_data](
220 const WriteNvramRequest& request,
221 const TpmNvramInterface::WriteNvramCallback& callback) {
222 EXPECT_TRUE(request.has_index());
223 EXPECT_EQ(nvram_index, request.index());
224 EXPECT_TRUE(request.has_data());
225 EXPECT_EQ(nvram_data, request.data());
226 WriteNvramReply reply;
227 reply.set_status(STATUS_SUCCESS);
228 callback.Run(reply);
229 }));
230 WriteNvramReply reply;
231 ExecuteMethod(kWriteNvram, request, &reply, kTpmNvramInterface);
232 EXPECT_EQ(STATUS_SUCCESS, reply.status());
233 }
234
TEST_F(DBusServiceTest,ReadNvram)235 TEST_F(DBusServiceTest, ReadNvram) {
236 uint32_t nvram_index = 5;
237 std::string nvram_data("nvram_data");
238 ReadNvramRequest request;
239 request.set_index(nvram_index);
240 EXPECT_CALL(mock_nvram_service_, ReadNvram(_, _))
241 .WillOnce(Invoke([nvram_index, nvram_data](
242 const ReadNvramRequest& request,
243 const TpmNvramInterface::ReadNvramCallback& callback) {
244 EXPECT_TRUE(request.has_index());
245 EXPECT_EQ(nvram_index, request.index());
246 ReadNvramReply reply;
247 reply.set_status(STATUS_SUCCESS);
248 reply.set_data(nvram_data);
249 callback.Run(reply);
250 }));
251 ReadNvramReply reply;
252 ExecuteMethod(kReadNvram, request, &reply, kTpmNvramInterface);
253 EXPECT_EQ(STATUS_SUCCESS, reply.status());
254 EXPECT_TRUE(reply.has_data());
255 EXPECT_EQ(nvram_data, reply.data());
256 }
257
TEST_F(DBusServiceTest,IsNvramDefined)258 TEST_F(DBusServiceTest, IsNvramDefined) {
259 uint32_t nvram_index = 5;
260 bool nvram_defined = true;
261 IsNvramDefinedRequest request;
262 request.set_index(nvram_index);
263 EXPECT_CALL(mock_nvram_service_, IsNvramDefined(_, _))
264 .WillOnce(Invoke([nvram_index, nvram_defined](
265 const IsNvramDefinedRequest& request,
266 const TpmNvramInterface::IsNvramDefinedCallback& callback) {
267 EXPECT_TRUE(request.has_index());
268 EXPECT_EQ(nvram_index, request.index());
269 IsNvramDefinedReply reply;
270 reply.set_status(STATUS_SUCCESS);
271 reply.set_is_defined(nvram_defined);
272 callback.Run(reply);
273 }));
274 IsNvramDefinedReply reply;
275 ExecuteMethod(kIsNvramDefined, request, &reply, kTpmNvramInterface);
276 EXPECT_EQ(STATUS_SUCCESS, reply.status());
277 EXPECT_TRUE(reply.has_is_defined());
278 EXPECT_EQ(nvram_defined, reply.is_defined());
279 }
280
TEST_F(DBusServiceTest,IsNvramLocked)281 TEST_F(DBusServiceTest, IsNvramLocked) {
282 uint32_t nvram_index = 5;
283 bool nvram_locked = true;
284 IsNvramLockedRequest request;
285 request.set_index(nvram_index);
286 EXPECT_CALL(mock_nvram_service_, IsNvramLocked(_, _))
287 .WillOnce(Invoke([nvram_index, nvram_locked](
288 const IsNvramLockedRequest& request,
289 const TpmNvramInterface::IsNvramLockedCallback& callback) {
290 EXPECT_TRUE(request.has_index());
291 EXPECT_EQ(nvram_index, request.index());
292 IsNvramLockedReply reply;
293 reply.set_status(STATUS_SUCCESS);
294 reply.set_is_locked(nvram_locked);
295 callback.Run(reply);
296 }));
297 IsNvramLockedReply reply;
298 ExecuteMethod(kIsNvramLocked, request, &reply, kTpmNvramInterface);
299 EXPECT_EQ(STATUS_SUCCESS, reply.status());
300 EXPECT_TRUE(reply.has_is_locked());
301 EXPECT_EQ(nvram_locked, reply.is_locked());
302 }
303
TEST_F(DBusServiceTest,GetNvramSize)304 TEST_F(DBusServiceTest, GetNvramSize) {
305 uint32_t nvram_index = 5;
306 size_t nvram_size = 32;
307 GetNvramSizeRequest request;
308 request.set_index(nvram_index);
309 EXPECT_CALL(mock_nvram_service_, GetNvramSize(_, _))
310 .WillOnce(Invoke([nvram_index, nvram_size](
311 const GetNvramSizeRequest& request,
312 const TpmNvramInterface::GetNvramSizeCallback& callback) {
313 EXPECT_TRUE(request.has_index());
314 EXPECT_EQ(nvram_index, request.index());
315 GetNvramSizeReply reply;
316 reply.set_status(STATUS_SUCCESS);
317 reply.set_size(nvram_size);
318 callback.Run(reply);
319 }));
320 GetNvramSizeReply reply;
321 ExecuteMethod(kGetNvramSize, request, &reply, kTpmNvramInterface);
322 EXPECT_EQ(STATUS_SUCCESS, reply.status());
323 EXPECT_TRUE(reply.has_size());
324 EXPECT_EQ(nvram_size, reply.size());
325 }
326
327 } // namespace tpm_manager
328