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 <dbus/mock_object_proxy.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 #include "attestation/client/dbus_proxy.h"
25
26 using testing::_;
27 using testing::Invoke;
28 using testing::StrictMock;
29 using testing::WithArgs;
30
31 namespace attestation {
32
33 class DBusProxyTest : public testing::Test {
34 public:
35 ~DBusProxyTest() override = default;
SetUp()36 void SetUp() override {
37 mock_object_proxy_ = new StrictMock<dbus::MockObjectProxy>(
38 nullptr, "", dbus::ObjectPath(""));
39 proxy_.set_object_proxy(mock_object_proxy_.get());
40 }
41
42 protected:
43 scoped_refptr<StrictMock<dbus::MockObjectProxy>> mock_object_proxy_;
44 DBusProxy proxy_;
45 };
46
TEST_F(DBusProxyTest,CreateGoogleAttestedKey)47 TEST_F(DBusProxyTest, CreateGoogleAttestedKey) {
48 auto fake_dbus_call = [](
49 dbus::MethodCall* method_call,
50 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
51 // Verify request protobuf.
52 dbus::MessageReader reader(method_call);
53 CreateGoogleAttestedKeyRequest request_proto;
54 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
55 EXPECT_EQ("label", request_proto.key_label());
56 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type());
57 EXPECT_EQ(KEY_USAGE_SIGN, request_proto.key_usage());
58 EXPECT_EQ(ENTERPRISE_MACHINE_CERTIFICATE,
59 request_proto.certificate_profile());
60 EXPECT_EQ("user", request_proto.username());
61 EXPECT_EQ("origin", request_proto.origin());
62 // Create reply protobuf.
63 auto response = dbus::Response::CreateEmpty();
64 dbus::MessageWriter writer(response.get());
65 CreateGoogleAttestedKeyReply reply_proto;
66 reply_proto.set_status(STATUS_SUCCESS);
67 reply_proto.set_certificate_chain("certificate");
68 reply_proto.set_server_error("server_error");
69 writer.AppendProtoAsArrayOfBytes(reply_proto);
70 response_callback.Run(response.release());
71 };
72 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
73 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
74
75 // Set expectations on the outputs.
76 int callback_count = 0;
77 auto callback = [&callback_count](const CreateGoogleAttestedKeyReply& reply) {
78 callback_count++;
79 EXPECT_EQ(STATUS_SUCCESS, reply.status());
80 EXPECT_EQ("certificate", reply.certificate_chain());
81 EXPECT_EQ("server_error", reply.server_error());
82 };
83 CreateGoogleAttestedKeyRequest request;
84 request.set_key_label("label");
85 request.set_key_type(KEY_TYPE_ECC);
86 request.set_key_usage(KEY_USAGE_SIGN);
87 request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
88 request.set_username("user");
89 request.set_origin("origin");
90 proxy_.CreateGoogleAttestedKey(request, base::Bind(callback));
91 EXPECT_EQ(1, callback_count);
92 }
93
TEST_F(DBusProxyTest,GetKeyInfo)94 TEST_F(DBusProxyTest, GetKeyInfo) {
95 auto fake_dbus_call = [](
96 dbus::MethodCall* method_call,
97 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
98 // Verify request protobuf.
99 dbus::MessageReader reader(method_call);
100 GetKeyInfoRequest request_proto;
101 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
102 EXPECT_EQ("label", request_proto.key_label());
103 EXPECT_EQ("username", request_proto.username());
104 // Create reply protobuf.
105 auto response = dbus::Response::CreateEmpty();
106 dbus::MessageWriter writer(response.get());
107 GetKeyInfoReply reply_proto;
108 reply_proto.set_status(STATUS_SUCCESS);
109 reply_proto.set_key_type(KEY_TYPE_ECC);
110 reply_proto.set_key_usage(KEY_USAGE_SIGN);
111 reply_proto.set_public_key("public_key");
112 reply_proto.set_certify_info("certify_info");
113 reply_proto.set_certify_info_signature("signature");
114 reply_proto.set_certificate("certificate");
115 writer.AppendProtoAsArrayOfBytes(reply_proto);
116 response_callback.Run(response.release());
117 };
118 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
119 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
120
121 // Set expectations on the outputs.
122 int callback_count = 0;
123 auto callback = [&callback_count](const GetKeyInfoReply& reply) {
124 callback_count++;
125 EXPECT_EQ(STATUS_SUCCESS, reply.status());
126 EXPECT_EQ(KEY_TYPE_ECC, reply.key_type());
127 EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage());
128 EXPECT_EQ("public_key", reply.public_key());
129 EXPECT_EQ("certify_info", reply.certify_info());
130 EXPECT_EQ("signature", reply.certify_info_signature());
131 EXPECT_EQ("certificate", reply.certificate());
132 };
133 GetKeyInfoRequest request;
134 request.set_key_label("label");
135 request.set_username("username");
136 proxy_.GetKeyInfo(request, base::Bind(callback));
137 EXPECT_EQ(1, callback_count);
138 }
139
TEST_F(DBusProxyTest,GetEndorsementInfo)140 TEST_F(DBusProxyTest, GetEndorsementInfo) {
141 auto fake_dbus_call = [](
142 dbus::MethodCall* method_call,
143 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
144 // Verify request protobuf.
145 dbus::MessageReader reader(method_call);
146 GetEndorsementInfoRequest request_proto;
147 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
148 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type());
149 // Create reply protobuf.
150 auto response = dbus::Response::CreateEmpty();
151 dbus::MessageWriter writer(response.get());
152 GetEndorsementInfoReply reply_proto;
153 reply_proto.set_status(STATUS_SUCCESS);
154 reply_proto.set_ek_public_key("public_key");
155 reply_proto.set_ek_certificate("certificate");
156 writer.AppendProtoAsArrayOfBytes(reply_proto);
157 response_callback.Run(response.release());
158 };
159 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
160 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
161
162 // Set expectations on the outputs.
163 int callback_count = 0;
164 auto callback = [&callback_count](const GetEndorsementInfoReply& reply) {
165 callback_count++;
166 EXPECT_EQ(STATUS_SUCCESS, reply.status());
167 EXPECT_EQ("public_key", reply.ek_public_key());
168 EXPECT_EQ("certificate", reply.ek_certificate());
169 };
170 GetEndorsementInfoRequest request;
171 request.set_key_type(KEY_TYPE_ECC);
172 proxy_.GetEndorsementInfo(request, base::Bind(callback));
173 EXPECT_EQ(1, callback_count);
174 }
175
TEST_F(DBusProxyTest,GetAttestationKeyInfo)176 TEST_F(DBusProxyTest, GetAttestationKeyInfo) {
177 auto fake_dbus_call = [](
178 dbus::MethodCall* method_call,
179 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
180 // Verify request protobuf.
181 dbus::MessageReader reader(method_call);
182 GetAttestationKeyInfoRequest request_proto;
183 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
184 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type());
185 // Create reply protobuf.
186 auto response = dbus::Response::CreateEmpty();
187 dbus::MessageWriter writer(response.get());
188 GetAttestationKeyInfoReply reply_proto;
189 reply_proto.set_status(STATUS_SUCCESS);
190 reply_proto.set_public_key("public_key");
191 reply_proto.set_public_key_tpm_format("public_key_tpm_format");
192 reply_proto.set_certificate("certificate");
193 reply_proto.mutable_pcr0_quote()->set_quote("pcr0");
194 reply_proto.mutable_pcr1_quote()->set_quote("pcr1");
195 writer.AppendProtoAsArrayOfBytes(reply_proto);
196 response_callback.Run(response.release());
197 };
198 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
199 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
200
201 // Set expectations on the outputs.
202 int callback_count = 0;
203 auto callback = [&callback_count](const GetAttestationKeyInfoReply& reply) {
204 callback_count++;
205 EXPECT_EQ(STATUS_SUCCESS, reply.status());
206 EXPECT_EQ("public_key", reply.public_key());
207 EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format());
208 EXPECT_EQ("certificate", reply.certificate());
209 EXPECT_EQ("pcr0", reply.pcr0_quote().quote());
210 EXPECT_EQ("pcr1", reply.pcr1_quote().quote());
211 };
212 GetAttestationKeyInfoRequest request;
213 request.set_key_type(KEY_TYPE_ECC);
214 proxy_.GetAttestationKeyInfo(request, base::Bind(callback));
215 EXPECT_EQ(1, callback_count);
216 }
217
TEST_F(DBusProxyTest,ActivateAttestationKey)218 TEST_F(DBusProxyTest, ActivateAttestationKey) {
219 auto fake_dbus_call = [](
220 dbus::MethodCall* method_call,
221 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
222 // Verify request protobuf.
223 dbus::MessageReader reader(method_call);
224 ActivateAttestationKeyRequest request_proto;
225 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
226 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type());
227 EXPECT_EQ("encrypted1",
228 request_proto.encrypted_certificate().asym_ca_contents());
229 EXPECT_EQ("encrypted2",
230 request_proto.encrypted_certificate().sym_ca_attestation());
231 EXPECT_TRUE(request_proto.save_certificate());
232 // Create reply protobuf.
233 auto response = dbus::Response::CreateEmpty();
234 dbus::MessageWriter writer(response.get());
235 ActivateAttestationKeyReply reply_proto;
236 reply_proto.set_status(STATUS_SUCCESS);
237 reply_proto.set_certificate("certificate");
238 writer.AppendProtoAsArrayOfBytes(reply_proto);
239 response_callback.Run(response.release());
240 };
241 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
242 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
243
244 // Set expectations on the outputs.
245 int callback_count = 0;
246 auto callback = [&callback_count](const ActivateAttestationKeyReply& reply) {
247 callback_count++;
248 EXPECT_EQ(STATUS_SUCCESS, reply.status());
249 EXPECT_EQ("certificate", reply.certificate());
250 };
251 ActivateAttestationKeyRequest request;
252 request.set_key_type(KEY_TYPE_ECC);
253 request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
254 request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
255 request.set_save_certificate(true);
256 proxy_.ActivateAttestationKey(request, base::Bind(callback));
257 EXPECT_EQ(1, callback_count);
258 }
259
TEST_F(DBusProxyTest,CreateCertifiableKey)260 TEST_F(DBusProxyTest, CreateCertifiableKey) {
261 auto fake_dbus_call = [](
262 dbus::MethodCall* method_call,
263 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
264 // Verify request protobuf.
265 dbus::MessageReader reader(method_call);
266 CreateCertifiableKeyRequest request_proto;
267 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
268 EXPECT_EQ("label", request_proto.key_label());
269 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type());
270 EXPECT_EQ(KEY_USAGE_SIGN, request_proto.key_usage());
271 EXPECT_EQ("user", request_proto.username());
272 // Create reply protobuf.
273 auto response = dbus::Response::CreateEmpty();
274 dbus::MessageWriter writer(response.get());
275 CreateCertifiableKeyReply reply_proto;
276 reply_proto.set_status(STATUS_SUCCESS);
277 reply_proto.set_public_key("public_key");
278 reply_proto.set_certify_info("certify_info");
279 reply_proto.set_certify_info_signature("signature");
280 writer.AppendProtoAsArrayOfBytes(reply_proto);
281 response_callback.Run(response.release());
282 };
283 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
284 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
285
286 // Set expectations on the outputs.
287 int callback_count = 0;
288 auto callback = [&callback_count](const CreateCertifiableKeyReply& reply) {
289 callback_count++;
290 EXPECT_EQ(STATUS_SUCCESS, reply.status());
291 EXPECT_EQ("public_key", reply.public_key());
292 EXPECT_EQ("certify_info", reply.certify_info());
293 EXPECT_EQ("signature", reply.certify_info_signature());
294 };
295 CreateCertifiableKeyRequest request;
296 request.set_key_label("label");
297 request.set_key_type(KEY_TYPE_ECC);
298 request.set_key_usage(KEY_USAGE_SIGN);
299 request.set_username("user");
300 proxy_.CreateCertifiableKey(request, base::Bind(callback));
301 EXPECT_EQ(1, callback_count);
302 }
303
TEST_F(DBusProxyTest,Decrypt)304 TEST_F(DBusProxyTest, Decrypt) {
305 auto fake_dbus_call = [](
306 dbus::MethodCall* method_call,
307 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
308 // Verify request protobuf.
309 dbus::MessageReader reader(method_call);
310 DecryptRequest request_proto;
311 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
312 EXPECT_EQ("label", request_proto.key_label());
313 EXPECT_EQ("user", request_proto.username());
314 EXPECT_EQ("data", request_proto.encrypted_data());
315 // Create reply protobuf.
316 scoped_ptr<dbus::Response> response = dbus::Response::CreateEmpty();
317 dbus::MessageWriter writer(response.get());
318 DecryptReply reply_proto;
319 reply_proto.set_status(STATUS_SUCCESS);
320 reply_proto.set_decrypted_data("data");
321 writer.AppendProtoAsArrayOfBytes(reply_proto);
322 response_callback.Run(response.release());
323 };
324 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
325 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
326
327 // Set expectations on the outputs.
328 int callback_count = 0;
329 auto callback = [&callback_count](const DecryptReply& reply) {
330 callback_count++;
331 EXPECT_EQ(STATUS_SUCCESS, reply.status());
332 EXPECT_EQ("data", reply.decrypted_data());
333 };
334 DecryptRequest request;
335 request.set_key_label("label");
336 request.set_username("user");
337 request.set_encrypted_data("data");
338 proxy_.Decrypt(request, base::Bind(callback));
339 EXPECT_EQ(1, callback_count);
340 }
341
TEST_F(DBusProxyTest,Sign)342 TEST_F(DBusProxyTest, Sign) {
343 auto fake_dbus_call = [](
344 dbus::MethodCall* method_call,
345 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
346 // Verify request protobuf.
347 dbus::MessageReader reader(method_call);
348 SignRequest request_proto;
349 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
350 EXPECT_EQ("label", request_proto.key_label());
351 EXPECT_EQ("user", request_proto.username());
352 EXPECT_EQ("data", request_proto.data_to_sign());
353 // Create reply protobuf.
354 auto response = dbus::Response::CreateEmpty();
355 dbus::MessageWriter writer(response.get());
356 SignReply reply_proto;
357 reply_proto.set_status(STATUS_SUCCESS);
358 reply_proto.set_signature("signature");
359 writer.AppendProtoAsArrayOfBytes(reply_proto);
360 response_callback.Run(response.release());
361 };
362 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
363 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
364
365 // Set expectations on the outputs.
366 int callback_count = 0;
367 auto callback = [&callback_count](const SignReply& reply) {
368 callback_count++;
369 EXPECT_EQ(STATUS_SUCCESS, reply.status());
370 EXPECT_EQ("signature", reply.signature());
371 };
372 SignRequest request;
373 request.set_key_label("label");
374 request.set_username("user");
375 request.set_data_to_sign("data");
376 proxy_.Sign(request, base::Bind(callback));
377 EXPECT_EQ(1, callback_count);
378 }
379
TEST_F(DBusProxyTest,RegisterKeyWithChapsToken)380 TEST_F(DBusProxyTest, RegisterKeyWithChapsToken) {
381 auto fake_dbus_call = [](
382 dbus::MethodCall* method_call,
383 const dbus::MockObjectProxy::ResponseCallback& response_callback) {
384 // Verify request protobuf.
385 dbus::MessageReader reader(method_call);
386 RegisterKeyWithChapsTokenRequest request_proto;
387 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto));
388 EXPECT_EQ("label", request_proto.key_label());
389 EXPECT_EQ("user", request_proto.username());
390 // Create reply protobuf.
391 auto response = dbus::Response::CreateEmpty();
392 dbus::MessageWriter writer(response.get());
393 RegisterKeyWithChapsTokenReply reply_proto;
394 reply_proto.set_status(STATUS_SUCCESS);
395 writer.AppendProtoAsArrayOfBytes(reply_proto);
396 response_callback.Run(response.release());
397 };
398 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _))
399 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));
400
401 // Set expectations on the outputs.
402 int callback_count = 0;
403 auto callback =
404 [&callback_count](const RegisterKeyWithChapsTokenReply& reply) {
405 callback_count++;
406 EXPECT_EQ(STATUS_SUCCESS, reply.status());
407 };
408 RegisterKeyWithChapsTokenRequest request;
409 request.set_key_label("label");
410 request.set_username("user");
411 proxy_.RegisterKeyWithChapsToken(request, base::Bind(callback));
412 EXPECT_EQ(1, callback_count);
413 }
414
415 } // namespace attestation
416