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