dbus_service_test.cc revision ff2783e1bf1f26cb1173c821cbfa70c5f1cee954
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
30using testing::_;
31using testing::Invoke;
32using testing::NiceMock;
33using testing::Return;
34using testing::StrictMock;
35using testing::WithArgs;
36
37namespace attestation {
38
39class DBusServiceTest : public testing::Test {
40 public:
41  ~DBusServiceTest() override = default;
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_ = new NiceMock<dbus::MockExportedObject>(
47        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(brillo::dbus_utils::AsyncEventSequencer::
52                                GetDefaultCompletionAction());
53  }
54
55  std::unique_ptr<dbus::Response> CallMethod(dbus::MethodCall* method_call) {
56    return brillo::dbus_utils::testing::CallMethod(
57        dbus_service_->dbus_object_, method_call);
58  }
59
60  std::unique_ptr<dbus::MethodCall> CreateMethodCall(
61      const std::string& method_name) {
62    std::unique_ptr<dbus::MethodCall> call(new dbus::MethodCall(
63        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
75TEST_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(Invoke([](
85          const CreateGoogleAttestedKeyRequest& request,
86          const AttestationInterface::
87              CreateGoogleAttestedKeyCallback& 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 = CreateMethodCall(
102      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
114TEST_F(DBusServiceTest, CopyableCallback) {
115  EXPECT_CALL(mock_service_, CreateGoogleAttestedKey(_, _))
116      .WillOnce(WithArgs<1>(Invoke([](const AttestationInterface::
117          CreateGoogleAttestedKeyCallback& callback) {
118        // Copy the callback, then call the original.
119        CreateGoogleAttestedKeyReply reply;
120        base::Closure copy = base::Bind(callback, reply);
121        callback.Run(reply);
122      })));
123  std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(
124      kCreateGoogleAttestedKey);
125  CreateGoogleAttestedKeyRequest request;
126  dbus::MessageWriter writer(call.get());
127  writer.AppendProtoAsArrayOfBytes(request);
128  auto response = CallMethod(call.get());
129  dbus::MessageReader reader(response.get());
130  CreateGoogleAttestedKeyReply reply;
131  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
132}
133
134TEST_F(DBusServiceTest, GetKeyInfo) {
135  GetKeyInfoRequest request;
136  request.set_key_label("label");
137  request.set_username("username");
138  EXPECT_CALL(mock_service_, GetKeyInfo(_, _))
139      .WillOnce(Invoke([](
140          const GetKeyInfoRequest& request,
141          const AttestationInterface::GetKeyInfoCallback& callback) {
142        EXPECT_EQ("label", request.key_label());
143        EXPECT_EQ("username", request.username());
144        GetKeyInfoReply reply;
145        reply.set_status(STATUS_SUCCESS);
146        reply.set_key_type(KEY_TYPE_ECC);
147        reply.set_key_usage(KEY_USAGE_SIGN);
148        reply.set_public_key("public_key");
149        reply.set_certify_info("certify");
150        reply.set_certify_info_signature("signature");
151        reply.set_certificate("certificate");
152        callback.Run(reply);
153      }));
154  std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kGetKeyInfo);
155  dbus::MessageWriter writer(call.get());
156  writer.AppendProtoAsArrayOfBytes(request);
157  auto response = CallMethod(call.get());
158  dbus::MessageReader reader(response.get());
159  GetKeyInfoReply reply;
160  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
161  EXPECT_EQ(STATUS_SUCCESS, reply.status());
162  EXPECT_EQ(KEY_TYPE_ECC, reply.key_type());
163  EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage());
164  EXPECT_EQ("public_key", reply.public_key());
165  EXPECT_EQ("certify", reply.certify_info());
166  EXPECT_EQ("signature", reply.certify_info_signature());
167  EXPECT_EQ("certificate", reply.certificate());
168}
169
170TEST_F(DBusServiceTest, GetEndorsementInfo) {
171  GetEndorsementInfoRequest request;
172  request.set_key_type(KEY_TYPE_ECC);
173  EXPECT_CALL(mock_service_, GetEndorsementInfo(_, _))
174      .WillOnce(Invoke([](
175          const GetEndorsementInfoRequest& request,
176          const AttestationInterface::GetEndorsementInfoCallback& callback) {
177        EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
178        GetEndorsementInfoReply reply;
179        reply.set_status(STATUS_SUCCESS);
180        reply.set_ek_public_key("public_key");
181        reply.set_ek_certificate("certificate");
182        callback.Run(reply);
183      }));
184  std::unique_ptr<dbus::MethodCall> call =
185      CreateMethodCall(kGetEndorsementInfo);
186  dbus::MessageWriter writer(call.get());
187  writer.AppendProtoAsArrayOfBytes(request);
188  auto response = CallMethod(call.get());
189  dbus::MessageReader reader(response.get());
190  GetEndorsementInfoReply reply;
191  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
192  EXPECT_EQ(STATUS_SUCCESS, reply.status());
193  EXPECT_EQ("public_key", reply.ek_public_key());
194  EXPECT_EQ("certificate", reply.ek_certificate());
195}
196
197TEST_F(DBusServiceTest, GetAttestationKeyInfo) {
198  GetAttestationKeyInfoRequest request;
199  request.set_key_type(KEY_TYPE_ECC);
200  EXPECT_CALL(mock_service_, GetAttestationKeyInfo(_, _))
201      .WillOnce(Invoke([](
202          const GetAttestationKeyInfoRequest& request,
203          const AttestationInterface::GetAttestationKeyInfoCallback& callback) {
204        EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
205        GetAttestationKeyInfoReply reply;
206        reply.set_status(STATUS_SUCCESS);
207        reply.set_public_key("public_key");
208        reply.set_public_key_tpm_format("public_key_tpm_format");
209        reply.set_certificate("certificate");
210        reply.mutable_pcr0_quote()->set_quote("pcr0");
211        reply.mutable_pcr1_quote()->set_quote("pcr1");
212        callback.Run(reply);
213      }));
214  std::unique_ptr<dbus::MethodCall> call =
215      CreateMethodCall(kGetAttestationKeyInfo);
216  dbus::MessageWriter writer(call.get());
217  writer.AppendProtoAsArrayOfBytes(request);
218  auto response = CallMethod(call.get());
219  dbus::MessageReader reader(response.get());
220  GetAttestationKeyInfoReply reply;
221  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
222  EXPECT_EQ(STATUS_SUCCESS, reply.status());
223  EXPECT_EQ("public_key", reply.public_key());
224  EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format());
225  EXPECT_EQ("certificate", reply.certificate());
226  EXPECT_EQ("pcr0", reply.pcr0_quote().quote());
227  EXPECT_EQ("pcr1", reply.pcr1_quote().quote());
228}
229
230TEST_F(DBusServiceTest, ActivateAttestationKey) {
231  ActivateAttestationKeyRequest request;
232  request.set_key_type(KEY_TYPE_ECC);
233  request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
234  request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
235  request.set_save_certificate(true);
236  EXPECT_CALL(mock_service_, ActivateAttestationKey(_, _))
237      .WillOnce(Invoke([](
238          const ActivateAttestationKeyRequest& request,
239          const AttestationInterface::ActivateAttestationKeyCallback&
240              callback) {
241        EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
242        EXPECT_EQ("encrypted1",
243                  request.encrypted_certificate().asym_ca_contents());
244        EXPECT_EQ("encrypted2",
245                  request.encrypted_certificate().sym_ca_attestation());
246        EXPECT_TRUE(request.save_certificate());
247        ActivateAttestationKeyReply reply;
248        reply.set_status(STATUS_SUCCESS);
249        reply.set_certificate("certificate");
250        callback.Run(reply);
251      }));
252  std::unique_ptr<dbus::MethodCall> call =
253      CreateMethodCall(kActivateAttestationKey);
254  dbus::MessageWriter writer(call.get());
255  writer.AppendProtoAsArrayOfBytes(request);
256  auto response = CallMethod(call.get());
257  dbus::MessageReader reader(response.get());
258  ActivateAttestationKeyReply reply;
259  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
260  EXPECT_EQ(STATUS_SUCCESS, reply.status());
261  EXPECT_EQ("certificate", reply.certificate());
262}
263
264TEST_F(DBusServiceTest, CreateCertifiableKey) {
265  CreateCertifiableKeyRequest request;
266  request.set_key_label("label");
267  request.set_key_type(KEY_TYPE_ECC);
268  request.set_key_usage(KEY_USAGE_SIGN);
269  request.set_username("user");
270  EXPECT_CALL(mock_service_, CreateCertifiableKey(_, _))
271      .WillOnce(Invoke([](
272          const CreateCertifiableKeyRequest& request,
273          const AttestationInterface::CreateCertifiableKeyCallback& callback) {
274        EXPECT_EQ("label", request.key_label());
275        EXPECT_EQ(KEY_TYPE_ECC, request.key_type());
276        EXPECT_EQ(KEY_USAGE_SIGN, request.key_usage());
277        EXPECT_EQ("user", request.username());
278        CreateCertifiableKeyReply reply;
279        reply.set_status(STATUS_SUCCESS);
280        reply.set_public_key("public_key");
281        reply.set_certify_info("certify_info");
282        reply.set_certify_info_signature("signature");
283        callback.Run(reply);
284      }));
285  std::unique_ptr<dbus::MethodCall> call =
286      CreateMethodCall(kCreateCertifiableKey);
287  dbus::MessageWriter writer(call.get());
288  writer.AppendProtoAsArrayOfBytes(request);
289  auto response = CallMethod(call.get());
290  dbus::MessageReader reader(response.get());
291  CreateCertifiableKeyReply reply;
292  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
293  EXPECT_EQ(STATUS_SUCCESS, reply.status());
294  EXPECT_EQ("public_key", reply.public_key());
295  EXPECT_EQ("certify_info", reply.certify_info());
296  EXPECT_EQ("signature", reply.certify_info_signature());
297}
298
299TEST_F(DBusServiceTest, Decrypt) {
300  DecryptRequest request;
301  request.set_key_label("label");
302  request.set_username("user");
303  request.set_encrypted_data("data");
304  EXPECT_CALL(mock_service_, Decrypt(_, _))
305      .WillOnce(Invoke([](
306          const DecryptRequest& request,
307          const AttestationInterface::DecryptCallback& callback) {
308        EXPECT_EQ("label", request.key_label());
309        EXPECT_EQ("user", request.username());
310        EXPECT_EQ("data", request.encrypted_data());
311        DecryptReply reply;
312        reply.set_status(STATUS_SUCCESS);
313        reply.set_decrypted_data("data");
314        callback.Run(reply);
315      }));
316  std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kDecrypt);
317  dbus::MessageWriter writer(call.get());
318  writer.AppendProtoAsArrayOfBytes(request);
319  auto response = CallMethod(call.get());
320  dbus::MessageReader reader(response.get());
321  DecryptReply reply;
322  EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
323  EXPECT_EQ(STATUS_SUCCESS, reply.status());
324  EXPECT_EQ("data", reply.decrypted_data());
325}
326
327TEST_F(DBusServiceTest, Sign) {
328  SignRequest request;
329  request.set_key_label("label");
330  request.set_username("user");
331  request.set_data_to_sign("data");
332  EXPECT_CALL(mock_service_, Sign(_, _))
333      .WillOnce(Invoke([](
334          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
355TEST_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
382}  // namespace attestation
383