1 //
2 // Copyright (C) 2014 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 "attestation/common/dbus_interface.h"
27 #include "attestation/common/mock_attestation_interface.h"
28 #include "attestation/server/dbus_service.h"
29
30 using testing::_;
31 using testing::Invoke;
32 using testing::NiceMock;
33 using testing::Return;
34 using testing::StrictMock;
35 using testing::WithArgs;
36
37 namespace attestation {
38
39 class DBusServiceTest : public testing::Test {
40 public:
41 ~DBusServiceTest() override = default;
SetUp()42 void SetUp() override {
43 dbus::Bus::Options options;
44 mock_bus_ = new NiceMock<dbus::MockBus>(options);
45 dbus::ObjectPath path(kAttestationServicePath);
46 mock_exported_object_ =
47 new NiceMock<dbus::MockExportedObject>(mock_bus_.get(), path);
48 ON_CALL(*mock_bus_, GetExportedObject(path))
49 .WillByDefault(Return(mock_exported_object_.get()));
50 dbus_service_.reset(new DBusService(mock_bus_, &mock_service_));
51 dbus_service_->Register(
52 brillo::dbus_utils::AsyncEventSequencer::GetDefaultCompletionAction());
53 }
54
CallMethod(dbus::MethodCall * method_call)55 std::unique_ptr<dbus::Response> CallMethod(dbus::MethodCall* method_call) {
56 return brillo::dbus_utils::testing::CallMethod(dbus_service_->dbus_object_,
57 method_call);
58 }
59
CreateMethodCall(const std::string & method_name)60 std::unique_ptr<dbus::MethodCall> CreateMethodCall(
61 const std::string& method_name) {
62 std::unique_ptr<dbus::MethodCall> call(
63 new dbus::MethodCall(kAttestationInterface, method_name));
64 call->SetSerial(1);
65 return call;
66 }
67
68 protected:
69 scoped_refptr<dbus::MockBus> mock_bus_;
70 scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
71 StrictMock<MockAttestationInterface> mock_service_;
72 std::unique_ptr<DBusService> dbus_service_;
73 };
74
TEST_F(DBusServiceTest,CreateGoogleAttestedKey)75 TEST_F(DBusServiceTest, CreateGoogleAttestedKey) {
76 CreateGoogleAttestedKeyRequest request;
77 request.set_key_label("label");
78 request.set_key_type(KEY_TYPE_ECC);
79 request.set_key_usage(KEY_USAGE_SIGN);
80 request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
81 request.set_username("username");
82 request.set_origin("origin");
83 EXPECT_CALL(mock_service_, CreateGoogleAttestedKey(_, _))
84 .WillOnce(
85 Invoke([](const CreateGoogleAttestedKeyRequest& request,
86 const AttestationInterface::CreateGoogleAttestedKeyCallback&
87 callback) {
88 EXPECT_EQ("label", request.key_label());
89 EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
90 EXPECT_EQ(KEY_USAGE_SIGN, request.key_usage());
91 EXPECT_EQ(ENTERPRISE_MACHINE_CERTIFICATE,
92 request.certificate_profile());
93 EXPECT_EQ("username", request.username());
94 EXPECT_EQ("origin", request.origin());
95 CreateGoogleAttestedKeyReply reply;
96 reply.set_status(STATUS_SUCCESS);
97 reply.set_certificate_chain("certificate");
98 reply.set_server_error("server_error");
99 callback.Run(reply);
100 }));
101 std::unique_ptr<dbus::MethodCall> call =
102 CreateMethodCall(kCreateGoogleAttestedKey);
103 dbus::MessageWriter writer(call.get());
104 writer.AppendProtoAsArrayOfBytes(request);
105 auto response = CallMethod(call.get());
106 dbus::MessageReader reader(response.get());
107 CreateGoogleAttestedKeyReply reply;
108 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
109 EXPECT_EQ(STATUS_SUCCESS, reply.status());
110 EXPECT_EQ("certificate", reply.certificate_chain());
111 EXPECT_EQ("server_error", reply.server_error());
112 }
113
TEST_F(DBusServiceTest,CopyableCallback)114 TEST_F(DBusServiceTest, CopyableCallback) {
115 EXPECT_CALL(mock_service_, CreateGoogleAttestedKey(_, _))
116 .WillOnce(WithArgs<1>(
117 Invoke([](const AttestationInterface::CreateGoogleAttestedKeyCallback&
118 callback) {
119 // Copy the callback, then call the original.
120 CreateGoogleAttestedKeyReply reply;
121 base::Closure copy = base::Bind(callback, reply);
122 callback.Run(reply);
123 })));
124 std::unique_ptr<dbus::MethodCall> call =
125 CreateMethodCall(kCreateGoogleAttestedKey);
126 CreateGoogleAttestedKeyRequest request;
127 dbus::MessageWriter writer(call.get());
128 writer.AppendProtoAsArrayOfBytes(request);
129 auto response = CallMethod(call.get());
130 dbus::MessageReader reader(response.get());
131 CreateGoogleAttestedKeyReply reply;
132 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
133 }
134
TEST_F(DBusServiceTest,GetKeyInfo)135 TEST_F(DBusServiceTest, GetKeyInfo) {
136 GetKeyInfoRequest request;
137 request.set_key_label("label");
138 request.set_username("username");
139 EXPECT_CALL(mock_service_, GetKeyInfo(_, _))
140 .WillOnce(
141 Invoke([](const GetKeyInfoRequest& request,
142 const AttestationInterface::GetKeyInfoCallback& callback) {
143 EXPECT_EQ("label", request.key_label());
144 EXPECT_EQ("username", request.username());
145 GetKeyInfoReply reply;
146 reply.set_status(STATUS_SUCCESS);
147 reply.set_key_type(KEY_TYPE_ECC);
148 reply.set_key_usage(KEY_USAGE_SIGN);
149 reply.set_public_key("public_key");
150 reply.set_certify_info("certify");
151 reply.set_certify_info_signature("signature");
152 reply.set_certificate("certificate");
153 callback.Run(reply);
154 }));
155 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kGetKeyInfo);
156 dbus::MessageWriter writer(call.get());
157 writer.AppendProtoAsArrayOfBytes(request);
158 auto response = CallMethod(call.get());
159 dbus::MessageReader reader(response.get());
160 GetKeyInfoReply reply;
161 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
162 EXPECT_EQ(STATUS_SUCCESS, reply.status());
163 EXPECT_EQ(KEY_TYPE_ECC, reply.key_type());
164 EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage());
165 EXPECT_EQ("public_key", reply.public_key());
166 EXPECT_EQ("certify", reply.certify_info());
167 EXPECT_EQ("signature", reply.certify_info_signature());
168 EXPECT_EQ("certificate", reply.certificate());
169 }
170
TEST_F(DBusServiceTest,GetEndorsementInfo)171 TEST_F(DBusServiceTest, GetEndorsementInfo) {
172 GetEndorsementInfoRequest request;
173 request.set_key_type(KEY_TYPE_ECC);
174 EXPECT_CALL(mock_service_, GetEndorsementInfo(_, _))
175 .WillOnce(Invoke(
176 [](const GetEndorsementInfoRequest& request,
177 const AttestationInterface::GetEndorsementInfoCallback& callback) {
178 EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
179 GetEndorsementInfoReply reply;
180 reply.set_status(STATUS_SUCCESS);
181 reply.set_ek_public_key("public_key");
182 reply.set_ek_certificate("certificate");
183 callback.Run(reply);
184 }));
185 std::unique_ptr<dbus::MethodCall> call =
186 CreateMethodCall(kGetEndorsementInfo);
187 dbus::MessageWriter writer(call.get());
188 writer.AppendProtoAsArrayOfBytes(request);
189 auto response = CallMethod(call.get());
190 dbus::MessageReader reader(response.get());
191 GetEndorsementInfoReply reply;
192 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
193 EXPECT_EQ(STATUS_SUCCESS, reply.status());
194 EXPECT_EQ("public_key", reply.ek_public_key());
195 EXPECT_EQ("certificate", reply.ek_certificate());
196 }
197
TEST_F(DBusServiceTest,GetAttestationKeyInfo)198 TEST_F(DBusServiceTest, GetAttestationKeyInfo) {
199 GetAttestationKeyInfoRequest request;
200 request.set_key_type(KEY_TYPE_ECC);
201 EXPECT_CALL(mock_service_, GetAttestationKeyInfo(_, _))
202 .WillOnce(Invoke([](
203 const GetAttestationKeyInfoRequest& request,
204 const AttestationInterface::GetAttestationKeyInfoCallback& callback) {
205 EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
206 GetAttestationKeyInfoReply reply;
207 reply.set_status(STATUS_SUCCESS);
208 reply.set_public_key("public_key");
209 reply.set_public_key_tpm_format("public_key_tpm_format");
210 reply.set_certificate("certificate");
211 reply.mutable_pcr0_quote()->set_quote("pcr0");
212 reply.mutable_pcr1_quote()->set_quote("pcr1");
213 callback.Run(reply);
214 }));
215 std::unique_ptr<dbus::MethodCall> call =
216 CreateMethodCall(kGetAttestationKeyInfo);
217 dbus::MessageWriter writer(call.get());
218 writer.AppendProtoAsArrayOfBytes(request);
219 auto response = CallMethod(call.get());
220 dbus::MessageReader reader(response.get());
221 GetAttestationKeyInfoReply reply;
222 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
223 EXPECT_EQ(STATUS_SUCCESS, reply.status());
224 EXPECT_EQ("public_key", reply.public_key());
225 EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format());
226 EXPECT_EQ("certificate", reply.certificate());
227 EXPECT_EQ("pcr0", reply.pcr0_quote().quote());
228 EXPECT_EQ("pcr1", reply.pcr1_quote().quote());
229 }
230
TEST_F(DBusServiceTest,ActivateAttestationKey)231 TEST_F(DBusServiceTest, ActivateAttestationKey) {
232 ActivateAttestationKeyRequest request;
233 request.set_key_type(KEY_TYPE_ECC);
234 request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
235 request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
236 request.set_save_certificate(true);
237 EXPECT_CALL(mock_service_, ActivateAttestationKey(_, _))
238 .WillOnce(
239 Invoke([](const ActivateAttestationKeyRequest& request,
240 const AttestationInterface::ActivateAttestationKeyCallback&
241 callback) {
242 EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
243 EXPECT_EQ("encrypted1",
244 request.encrypted_certificate().asym_ca_contents());
245 EXPECT_EQ("encrypted2",
246 request.encrypted_certificate().sym_ca_attestation());
247 EXPECT_TRUE(request.save_certificate());
248 ActivateAttestationKeyReply reply;
249 reply.set_status(STATUS_SUCCESS);
250 reply.set_certificate("certificate");
251 callback.Run(reply);
252 }));
253 std::unique_ptr<dbus::MethodCall> call =
254 CreateMethodCall(kActivateAttestationKey);
255 dbus::MessageWriter writer(call.get());
256 writer.AppendProtoAsArrayOfBytes(request);
257 auto response = CallMethod(call.get());
258 dbus::MessageReader reader(response.get());
259 ActivateAttestationKeyReply reply;
260 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
261 EXPECT_EQ(STATUS_SUCCESS, reply.status());
262 EXPECT_EQ("certificate", reply.certificate());
263 }
264
TEST_F(DBusServiceTest,CreateCertifiableKey)265 TEST_F(DBusServiceTest, CreateCertifiableKey) {
266 CreateCertifiableKeyRequest request;
267 request.set_key_label("label");
268 request.set_key_type(KEY_TYPE_ECC);
269 request.set_key_usage(KEY_USAGE_SIGN);
270 request.set_username("user");
271 EXPECT_CALL(mock_service_, CreateCertifiableKey(_, _))
272 .WillOnce(Invoke([](
273 const CreateCertifiableKeyRequest& request,
274 const AttestationInterface::CreateCertifiableKeyCallback& callback) {
275 EXPECT_EQ("label", request.key_label());
276 EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
277 EXPECT_EQ(KEY_USAGE_SIGN, request.key_usage());
278 EXPECT_EQ("user", request.username());
279 CreateCertifiableKeyReply reply;
280 reply.set_status(STATUS_SUCCESS);
281 reply.set_public_key("public_key");
282 reply.set_certify_info("certify_info");
283 reply.set_certify_info_signature("signature");
284 callback.Run(reply);
285 }));
286 std::unique_ptr<dbus::MethodCall> call =
287 CreateMethodCall(kCreateCertifiableKey);
288 dbus::MessageWriter writer(call.get());
289 writer.AppendProtoAsArrayOfBytes(request);
290 auto response = CallMethod(call.get());
291 dbus::MessageReader reader(response.get());
292 CreateCertifiableKeyReply reply;
293 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
294 EXPECT_EQ(STATUS_SUCCESS, reply.status());
295 EXPECT_EQ("public_key", reply.public_key());
296 EXPECT_EQ("certify_info", reply.certify_info());
297 EXPECT_EQ("signature", reply.certify_info_signature());
298 }
299
TEST_F(DBusServiceTest,Decrypt)300 TEST_F(DBusServiceTest, Decrypt) {
301 DecryptRequest request;
302 request.set_key_label("label");
303 request.set_username("user");
304 request.set_encrypted_data("data");
305 EXPECT_CALL(mock_service_, Decrypt(_, _))
306 .WillOnce(
307 Invoke([](const DecryptRequest& request,
308 const AttestationInterface::DecryptCallback& callback) {
309 EXPECT_EQ("label", request.key_label());
310 EXPECT_EQ("user", request.username());
311 EXPECT_EQ("data", request.encrypted_data());
312 DecryptReply reply;
313 reply.set_status(STATUS_SUCCESS);
314 reply.set_decrypted_data("data");
315 callback.Run(reply);
316 }));
317 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kDecrypt);
318 dbus::MessageWriter writer(call.get());
319 writer.AppendProtoAsArrayOfBytes(request);
320 auto response = CallMethod(call.get());
321 dbus::MessageReader reader(response.get());
322 DecryptReply reply;
323 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
324 EXPECT_EQ(STATUS_SUCCESS, reply.status());
325 EXPECT_EQ("data", reply.decrypted_data());
326 }
327
TEST_F(DBusServiceTest,Sign)328 TEST_F(DBusServiceTest, Sign) {
329 SignRequest request;
330 request.set_key_label("label");
331 request.set_username("user");
332 request.set_data_to_sign("data");
333 EXPECT_CALL(mock_service_, Sign(_, _))
334 .WillOnce(Invoke([](const SignRequest& request,
335 const AttestationInterface::SignCallback& callback) {
336 EXPECT_EQ("label", request.key_label());
337 EXPECT_EQ("user", request.username());
338 EXPECT_EQ("data", request.data_to_sign());
339 SignReply reply;
340 reply.set_status(STATUS_SUCCESS);
341 reply.set_signature("signature");
342 callback.Run(reply);
343 }));
344 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kSign);
345 dbus::MessageWriter writer(call.get());
346 writer.AppendProtoAsArrayOfBytes(request);
347 auto response = CallMethod(call.get());
348 dbus::MessageReader reader(response.get());
349 SignReply reply;
350 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
351 EXPECT_EQ(STATUS_SUCCESS, reply.status());
352 EXPECT_EQ("signature", reply.signature());
353 }
354
TEST_F(DBusServiceTest,RegisterKeyWithChapsToken)355 TEST_F(DBusServiceTest, RegisterKeyWithChapsToken) {
356 RegisterKeyWithChapsTokenRequest request;
357 request.set_key_label("label");
358 request.set_username("user");
359 EXPECT_CALL(mock_service_, RegisterKeyWithChapsToken(_, _))
360 .WillOnce(Invoke(
361 [](const RegisterKeyWithChapsTokenRequest& request,
362 const AttestationInterface::RegisterKeyWithChapsTokenCallback&
363 callback) {
364 EXPECT_EQ("label", request.key_label());
365 EXPECT_EQ("user", request.username());
366 RegisterKeyWithChapsTokenReply reply;
367 reply.set_status(STATUS_SUCCESS);
368 callback.Run(reply);
369 }));
370 std::unique_ptr<dbus::MethodCall> call =
371 CreateMethodCall(kRegisterKeyWithChapsToken);
372 dbus::MessageWriter writer(call.get());
373 writer.AppendProtoAsArrayOfBytes(request);
374 auto response = CallMethod(call.get());
375 dbus::MessageReader reader(response.get());
376 RegisterKeyWithChapsTokenReply reply;
377 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
378 EXPECT_EQ(STATUS_SUCCESS, reply.status());
379 }
380
381 } // namespace attestation
382