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