Home | History | Annotate | Download | only in server
      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;
     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_ =
     50         new NiceMock<dbus::MockExportedObject>(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_, &mock_nvram_service_,
     54                                         &mock_ownership_service_));
     55     scoped_refptr<brillo::dbus_utils::AsyncEventSequencer> sequencer(
     56         new brillo::dbus_utils::AsyncEventSequencer());
     57     dbus_service_->RegisterDBusObjectsAsync(sequencer.get());
     58   }
     59 
     60   template <typename RequestProtobufType, typename ReplyProtobufType>
     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 =
     66         CreateMethodCall(method_name, 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:
     76   std::unique_ptr<dbus::MethodCall> CreateMethodCall(
     77       const std::string& method_name,
     78       const std::string& interface) {
     79     std::unique_ptr<dbus::MethodCall> call(
     80         new dbus::MethodCall(interface, method_name));
     81     call->SetSerial(1);
     82     return call;
     83   }
     84 
     85   scoped_refptr<dbus::MockBus> mock_bus_;
     86   scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
     87   StrictMock<MockTpmNvramInterface> mock_nvram_service_;
     88   StrictMock<MockTpmOwnershipInterface> mock_ownership_service_;
     89   std::unique_ptr<DBusService> dbus_service_;
     90 };
     91 
     92 TEST_F(DBusServiceTest, CopyableCallback) {
     93   EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
     94       .WillOnce(WithArgs<1>(Invoke(
     95           [](const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
     96             // Copy the callback, then call the original.
     97             GetTpmStatusReply reply;
     98             base::Closure copy = base::Bind(callback, reply);
     99             callback.Run(reply);
    100           })));
    101   GetTpmStatusRequest request;
    102   GetTpmStatusReply reply;
    103   ExecuteMethod(kGetTpmStatus, request, &reply, kTpmOwnershipInterface);
    104 }
    105 
    106 TEST_F(DBusServiceTest, GetTpmStatus) {
    107   GetTpmStatusRequest request;
    108   EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
    109       .WillOnce(Invoke(
    110           [](const GetTpmStatusRequest& request,
    111              const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
    112             GetTpmStatusReply reply;
    113             reply.set_status(STATUS_SUCCESS);
    114             reply.set_enabled(true);
    115             reply.set_owned(true);
    116             reply.set_dictionary_attack_counter(3);
    117             reply.set_dictionary_attack_threshold(4);
    118             reply.set_dictionary_attack_lockout_in_effect(true);
    119             reply.set_dictionary_attack_lockout_seconds_remaining(5);
    120             callback.Run(reply);
    121           }));
    122   GetTpmStatusReply reply;
    123   ExecuteMethod(kGetTpmStatus, request, &reply, kTpmOwnershipInterface);
    124   EXPECT_EQ(STATUS_SUCCESS, reply.status());
    125   EXPECT_TRUE(reply.enabled());
    126   EXPECT_TRUE(reply.owned());
    127   EXPECT_EQ(3, reply.dictionary_attack_counter());
    128   EXPECT_EQ(4, reply.dictionary_attack_threshold());
    129   EXPECT_TRUE(reply.dictionary_attack_lockout_in_effect());
    130   EXPECT_EQ(5, reply.dictionary_attack_lockout_seconds_remaining());
    131 }
    132 
    133 TEST_F(DBusServiceTest, TakeOwnership) {
    134   EXPECT_CALL(mock_ownership_service_, TakeOwnership(_, _))
    135       .WillOnce(Invoke(
    136           [](const TakeOwnershipRequest& request,
    137              const TpmOwnershipInterface::TakeOwnershipCallback& callback) {
    138             TakeOwnershipReply reply;
    139             reply.set_status(STATUS_SUCCESS);
    140             callback.Run(reply);
    141           }));
    142   TakeOwnershipRequest request;
    143   TakeOwnershipReply reply;
    144   ExecuteMethod(kTakeOwnership, request, &reply, kTpmOwnershipInterface);
    145   EXPECT_EQ(STATUS_SUCCESS, reply.status());
    146 }
    147 
    148 TEST_F(DBusServiceTest, RemoveOwnerDependency) {
    149   std::string owner_dependency("owner_dependency");
    150   RemoveOwnerDependencyRequest request;
    151   request.set_owner_dependency(owner_dependency);
    152   EXPECT_CALL(mock_ownership_service_, RemoveOwnerDependency(_, _))
    153       .WillOnce(Invoke([&owner_dependency](
    154           const RemoveOwnerDependencyRequest& request,
    155           const TpmOwnershipInterface::RemoveOwnerDependencyCallback&
    156               callback) {
    157         EXPECT_TRUE(request.has_owner_dependency());
    158         EXPECT_EQ(owner_dependency, request.owner_dependency());
    159         RemoveOwnerDependencyReply reply;
    160         reply.set_status(STATUS_SUCCESS);
    161         callback.Run(reply);
    162       }));
    163   RemoveOwnerDependencyReply reply;
    164   ExecuteMethod(kRemoveOwnerDependency, request, &reply,
    165                 kTpmOwnershipInterface);
    166   EXPECT_EQ(STATUS_SUCCESS, reply.status());
    167 }
    168 
    169 TEST_F(DBusServiceTest, DefineSpace) {
    170   uint32_t nvram_index = 5;
    171   size_t nvram_length = 32;
    172   DefineSpaceRequest request;
    173   request.set_index(nvram_index);
    174   request.set_size(nvram_length);
    175   EXPECT_CALL(mock_nvram_service_, DefineSpace(_, _))
    176       .WillOnce(Invoke([nvram_index, nvram_length](
    177           const DefineSpaceRequest& request,
    178           const TpmNvramInterface::DefineSpaceCallback& callback) {
    179         EXPECT_TRUE(request.has_index());
    180         EXPECT_EQ(nvram_index, request.index());
    181         EXPECT_TRUE(request.has_size());
    182         EXPECT_EQ(nvram_length, request.size());
    183         DefineSpaceReply reply;
    184         reply.set_result(NVRAM_RESULT_SUCCESS);
    185         callback.Run(reply);
    186       }));
    187   DefineSpaceReply reply;
    188   ExecuteMethod(kDefineSpace, request, &reply, kTpmNvramInterface);
    189   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    190 }
    191 
    192 TEST_F(DBusServiceTest, DestroySpace) {
    193   uint32_t nvram_index = 5;
    194   DestroySpaceRequest request;
    195   request.set_index(nvram_index);
    196   EXPECT_CALL(mock_nvram_service_, DestroySpace(_, _))
    197       .WillOnce(Invoke([nvram_index](
    198           const DestroySpaceRequest& request,
    199           const TpmNvramInterface::DestroySpaceCallback& callback) {
    200         EXPECT_TRUE(request.has_index());
    201         EXPECT_EQ(nvram_index, request.index());
    202         DestroySpaceReply reply;
    203         reply.set_result(NVRAM_RESULT_SUCCESS);
    204         callback.Run(reply);
    205       }));
    206   DestroySpaceReply reply;
    207   ExecuteMethod(kDestroySpace, request, &reply, kTpmNvramInterface);
    208   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    209 }
    210 
    211 TEST_F(DBusServiceTest, WriteSpace) {
    212   uint32_t nvram_index = 5;
    213   std::string nvram_data("nvram_data");
    214   WriteSpaceRequest request;
    215   request.set_index(nvram_index);
    216   request.set_data(nvram_data);
    217   EXPECT_CALL(mock_nvram_service_, WriteSpace(_, _))
    218       .WillOnce(Invoke([nvram_index, nvram_data](
    219           const WriteSpaceRequest& request,
    220           const TpmNvramInterface::WriteSpaceCallback& callback) {
    221         EXPECT_TRUE(request.has_index());
    222         EXPECT_EQ(nvram_index, request.index());
    223         EXPECT_TRUE(request.has_data());
    224         EXPECT_EQ(nvram_data, request.data());
    225         WriteSpaceReply reply;
    226         reply.set_result(NVRAM_RESULT_SUCCESS);
    227         callback.Run(reply);
    228       }));
    229   WriteSpaceReply reply;
    230   ExecuteMethod(kWriteSpace, request, &reply, kTpmNvramInterface);
    231   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    232 }
    233 
    234 TEST_F(DBusServiceTest, ReadSpace) {
    235   uint32_t nvram_index = 5;
    236   std::string nvram_data("nvram_data");
    237   ReadSpaceRequest request;
    238   request.set_index(nvram_index);
    239   EXPECT_CALL(mock_nvram_service_, ReadSpace(_, _))
    240       .WillOnce(Invoke([nvram_index, nvram_data](
    241           const ReadSpaceRequest& request,
    242           const TpmNvramInterface::ReadSpaceCallback& callback) {
    243         EXPECT_TRUE(request.has_index());
    244         EXPECT_EQ(nvram_index, request.index());
    245         ReadSpaceReply reply;
    246         reply.set_result(NVRAM_RESULT_SUCCESS);
    247         reply.set_data(nvram_data);
    248         callback.Run(reply);
    249       }));
    250   ReadSpaceReply reply;
    251   ExecuteMethod(kReadSpace, request, &reply, kTpmNvramInterface);
    252   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    253   EXPECT_TRUE(reply.has_data());
    254   EXPECT_EQ(nvram_data, reply.data());
    255 }
    256 
    257 TEST_F(DBusServiceTest, LockSpace) {
    258   uint32_t nvram_index = 5;
    259   LockSpaceRequest request;
    260   request.set_index(nvram_index);
    261   request.set_lock_read(true);
    262   request.set_lock_write(true);
    263   EXPECT_CALL(mock_nvram_service_, LockSpace(_, _))
    264       .WillOnce(Invoke(
    265           [nvram_index](const LockSpaceRequest& request,
    266                         const TpmNvramInterface::LockSpaceCallback& callback) {
    267             EXPECT_TRUE(request.has_index());
    268             EXPECT_EQ(nvram_index, request.index());
    269             EXPECT_TRUE(request.lock_read());
    270             EXPECT_TRUE(request.lock_write());
    271             LockSpaceReply reply;
    272             reply.set_result(NVRAM_RESULT_SUCCESS);
    273             callback.Run(reply);
    274           }));
    275   LockSpaceReply reply;
    276   ExecuteMethod(kLockSpace, request, &reply, kTpmNvramInterface);
    277   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    278 }
    279 
    280 TEST_F(DBusServiceTest, ListSpaces) {
    281   constexpr uint32_t nvram_index_list[] = {3, 4, 5};
    282   ListSpacesRequest request;
    283   EXPECT_CALL(mock_nvram_service_, ListSpaces(_, _))
    284       .WillOnce(Invoke([nvram_index_list](
    285           const ListSpacesRequest& request,
    286           const TpmNvramInterface::ListSpacesCallback& callback) {
    287         ListSpacesReply reply;
    288         reply.set_result(NVRAM_RESULT_SUCCESS);
    289         for (auto index : nvram_index_list) {
    290           reply.add_index_list(index);
    291         }
    292         callback.Run(reply);
    293       }));
    294   ListSpacesReply reply;
    295   ExecuteMethod(kListSpaces, request, &reply, kTpmNvramInterface);
    296   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    297   EXPECT_EQ(arraysize(nvram_index_list), reply.index_list_size());
    298   for (size_t i = 0; i < 3; i++) {
    299     EXPECT_EQ(nvram_index_list[i], reply.index_list(i));
    300   }
    301 }
    302 
    303 TEST_F(DBusServiceTest, GetSpaceInfo) {
    304   uint32_t nvram_index = 5;
    305   size_t nvram_size = 32;
    306   GetSpaceInfoRequest request;
    307   request.set_index(nvram_index);
    308   EXPECT_CALL(mock_nvram_service_, GetSpaceInfo(_, _))
    309       .WillOnce(Invoke([nvram_index, nvram_size](
    310           const GetSpaceInfoRequest& request,
    311           const TpmNvramInterface::GetSpaceInfoCallback& callback) {
    312         EXPECT_TRUE(request.has_index());
    313         EXPECT_EQ(nvram_index, request.index());
    314         GetSpaceInfoReply reply;
    315         reply.set_result(NVRAM_RESULT_SUCCESS);
    316         reply.set_size(nvram_size);
    317         reply.set_is_read_locked(true);
    318         reply.set_is_write_locked(true);
    319         callback.Run(reply);
    320       }));
    321   GetSpaceInfoReply reply;
    322   ExecuteMethod(kGetSpaceInfo, request, &reply, kTpmNvramInterface);
    323   EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
    324   EXPECT_TRUE(reply.has_size());
    325   EXPECT_EQ(nvram_size, reply.size());
    326   EXPECT_TRUE(reply.is_read_locked());
    327   EXPECT_TRUE(reply.is_write_locked());
    328 }
    329 
    330 }  // namespace tpm_manager
    331