| // |
| // Copyright (C) 2015 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #include <string> |
| |
| #include <brillo/bind_lambda.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "tpm_manager/client/tpm_nvram_binder_proxy.h" |
| #include "tpm_manager/client/tpm_ownership_binder_proxy.h" |
| #include "tpm_manager/common/mock_tpm_nvram_interface.h" |
| #include "tpm_manager/common/mock_tpm_ownership_interface.h" |
| #include "tpm_manager/common/tpm_manager_constants.h" |
| #include "tpm_manager/server/binder_service.h" |
| |
| using testing::_; |
| using testing::Invoke; |
| using testing::NiceMock; |
| using testing::Return; |
| using testing::StrictMock; |
| using testing::WithArgs; |
| |
| namespace tpm_manager { |
| |
| // A test fixture to exercise both proxy and service layers. Tpm*BinderProxy |
| // classes get coverage here and do not need additional unit tests. |
| class BinderServiceTest : public testing::Test { |
| public: |
| ~BinderServiceTest() override = default; |
| void SetUp() override { |
| binder_service_.reset( |
| new BinderService(&mock_nvram_service_, &mock_ownership_service_)); |
| binder_service_->InitForTesting(); |
| nvram_proxy_.reset( |
| new TpmNvramBinderProxy(binder_service_->GetITpmNvram())); |
| ownership_proxy_.reset( |
| new TpmOwnershipBinderProxy(binder_service_->GetITpmOwnership())); |
| } |
| |
| template <typename ResponseProtobufType> |
| base::Callback<void(const ResponseProtobufType&)> GetCallback( |
| ResponseProtobufType* proto) { |
| return base::Bind( |
| [](ResponseProtobufType* proto, const ResponseProtobufType& response) { |
| *proto = response; |
| }, |
| base::Unretained(proto)); |
| } |
| |
| protected: |
| StrictMock<MockTpmNvramInterface> mock_nvram_service_; |
| StrictMock<MockTpmOwnershipInterface> mock_ownership_service_; |
| std::unique_ptr<BinderService> binder_service_; |
| std::unique_ptr<TpmNvramBinderProxy> nvram_proxy_; |
| std::unique_ptr<TpmOwnershipBinderProxy> ownership_proxy_; |
| }; |
| |
| TEST_F(BinderServiceTest, CopyableCallback) { |
| EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _)) |
| .WillOnce(WithArgs<1>(Invoke( |
| [](const TpmOwnershipInterface::GetTpmStatusCallback& callback) { |
| // Copy the callback, then call the original. |
| GetTpmStatusReply reply; |
| base::Closure copy = base::Bind(callback, reply); |
| callback.Run(reply); |
| }))); |
| GetTpmStatusRequest request; |
| GetTpmStatusReply reply; |
| ownership_proxy_->GetTpmStatus(request, |
| GetCallback<GetTpmStatusReply>(&reply)); |
| } |
| |
| TEST_F(BinderServiceTest, GetTpmStatus) { |
| GetTpmStatusRequest request; |
| EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _)) |
| .WillOnce(Invoke( |
| [](const GetTpmStatusRequest& request, |
| const TpmOwnershipInterface::GetTpmStatusCallback& callback) { |
| GetTpmStatusReply reply; |
| reply.set_status(STATUS_SUCCESS); |
| reply.set_enabled(true); |
| reply.set_owned(true); |
| reply.set_dictionary_attack_counter(3); |
| reply.set_dictionary_attack_threshold(4); |
| reply.set_dictionary_attack_lockout_in_effect(true); |
| reply.set_dictionary_attack_lockout_seconds_remaining(5); |
| callback.Run(reply); |
| })); |
| GetTpmStatusReply reply; |
| ownership_proxy_->GetTpmStatus(request, |
| GetCallback<GetTpmStatusReply>(&reply)); |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_TRUE(reply.enabled()); |
| EXPECT_TRUE(reply.owned()); |
| EXPECT_EQ(3, reply.dictionary_attack_counter()); |
| EXPECT_EQ(4, reply.dictionary_attack_threshold()); |
| EXPECT_TRUE(reply.dictionary_attack_lockout_in_effect()); |
| EXPECT_EQ(5, reply.dictionary_attack_lockout_seconds_remaining()); |
| } |
| |
| TEST_F(BinderServiceTest, TakeOwnership) { |
| EXPECT_CALL(mock_ownership_service_, TakeOwnership(_, _)) |
| .WillOnce(Invoke( |
| [](const TakeOwnershipRequest& request, |
| const TpmOwnershipInterface::TakeOwnershipCallback& callback) { |
| TakeOwnershipReply reply; |
| reply.set_status(STATUS_SUCCESS); |
| callback.Run(reply); |
| })); |
| TakeOwnershipRequest request; |
| TakeOwnershipReply reply; |
| ownership_proxy_->TakeOwnership(request, |
| GetCallback<TakeOwnershipReply>(&reply)); |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| } |
| |
| TEST_F(BinderServiceTest, RemoveOwnerDependency) { |
| std::string owner_dependency("owner_dependency"); |
| RemoveOwnerDependencyRequest request; |
| request.set_owner_dependency(owner_dependency); |
| EXPECT_CALL(mock_ownership_service_, RemoveOwnerDependency(_, _)) |
| .WillOnce(Invoke([&owner_dependency]( |
| const RemoveOwnerDependencyRequest& request, |
| const TpmOwnershipInterface::RemoveOwnerDependencyCallback& |
| callback) { |
| EXPECT_TRUE(request.has_owner_dependency()); |
| EXPECT_EQ(owner_dependency, request.owner_dependency()); |
| RemoveOwnerDependencyReply reply; |
| reply.set_status(STATUS_SUCCESS); |
| callback.Run(reply); |
| })); |
| RemoveOwnerDependencyReply reply; |
| ownership_proxy_->RemoveOwnerDependency( |
| request, GetCallback<RemoveOwnerDependencyReply>(&reply)); |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| } |
| |
| TEST_F(BinderServiceTest, DefineSpace) { |
| uint32_t nvram_index = 5; |
| size_t nvram_length = 32; |
| DefineSpaceRequest request; |
| request.set_index(nvram_index); |
| request.set_size(nvram_length); |
| EXPECT_CALL(mock_nvram_service_, DefineSpace(_, _)) |
| .WillOnce(Invoke([nvram_index, nvram_length]( |
| const DefineSpaceRequest& request, |
| const TpmNvramInterface::DefineSpaceCallback& callback) { |
| EXPECT_TRUE(request.has_index()); |
| EXPECT_EQ(nvram_index, request.index()); |
| EXPECT_TRUE(request.has_size()); |
| EXPECT_EQ(nvram_length, request.size()); |
| DefineSpaceReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| callback.Run(reply); |
| })); |
| DefineSpaceReply reply; |
| nvram_proxy_->DefineSpace(request, GetCallback<DefineSpaceReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| } |
| |
| TEST_F(BinderServiceTest, DestroySpace) { |
| uint32_t nvram_index = 5; |
| DestroySpaceRequest request; |
| request.set_index(nvram_index); |
| EXPECT_CALL(mock_nvram_service_, DestroySpace(_, _)) |
| .WillOnce(Invoke([nvram_index]( |
| const DestroySpaceRequest& request, |
| const TpmNvramInterface::DestroySpaceCallback& callback) { |
| EXPECT_TRUE(request.has_index()); |
| EXPECT_EQ(nvram_index, request.index()); |
| DestroySpaceReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| callback.Run(reply); |
| })); |
| DestroySpaceReply reply; |
| nvram_proxy_->DestroySpace(request, GetCallback<DestroySpaceReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| } |
| |
| TEST_F(BinderServiceTest, WriteSpace) { |
| uint32_t nvram_index = 5; |
| std::string nvram_data("nvram_data"); |
| WriteSpaceRequest request; |
| request.set_index(nvram_index); |
| request.set_data(nvram_data); |
| EXPECT_CALL(mock_nvram_service_, WriteSpace(_, _)) |
| .WillOnce(Invoke([nvram_index, nvram_data]( |
| const WriteSpaceRequest& request, |
| const TpmNvramInterface::WriteSpaceCallback& callback) { |
| EXPECT_TRUE(request.has_index()); |
| EXPECT_EQ(nvram_index, request.index()); |
| EXPECT_TRUE(request.has_data()); |
| EXPECT_EQ(nvram_data, request.data()); |
| WriteSpaceReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| callback.Run(reply); |
| })); |
| WriteSpaceReply reply; |
| nvram_proxy_->WriteSpace(request, GetCallback<WriteSpaceReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| } |
| |
| TEST_F(BinderServiceTest, ReadSpace) { |
| uint32_t nvram_index = 5; |
| std::string nvram_data("nvram_data"); |
| ReadSpaceRequest request; |
| request.set_index(nvram_index); |
| EXPECT_CALL(mock_nvram_service_, ReadSpace(_, _)) |
| .WillOnce(Invoke([nvram_index, nvram_data]( |
| const ReadSpaceRequest& request, |
| const TpmNvramInterface::ReadSpaceCallback& callback) { |
| EXPECT_TRUE(request.has_index()); |
| EXPECT_EQ(nvram_index, request.index()); |
| ReadSpaceReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| reply.set_data(nvram_data); |
| callback.Run(reply); |
| })); |
| ReadSpaceReply reply; |
| nvram_proxy_->ReadSpace(request, GetCallback<ReadSpaceReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| EXPECT_TRUE(reply.has_data()); |
| EXPECT_EQ(nvram_data, reply.data()); |
| } |
| |
| TEST_F(BinderServiceTest, LockSpace) { |
| uint32_t nvram_index = 5; |
| LockSpaceRequest request; |
| request.set_index(nvram_index); |
| request.set_lock_read(true); |
| request.set_lock_write(true); |
| EXPECT_CALL(mock_nvram_service_, LockSpace(_, _)) |
| .WillOnce(Invoke( |
| [nvram_index](const LockSpaceRequest& request, |
| const TpmNvramInterface::LockSpaceCallback& callback) { |
| EXPECT_TRUE(request.has_index()); |
| EXPECT_EQ(nvram_index, request.index()); |
| EXPECT_TRUE(request.lock_read()); |
| EXPECT_TRUE(request.lock_write()); |
| LockSpaceReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| callback.Run(reply); |
| })); |
| LockSpaceReply reply; |
| nvram_proxy_->LockSpace(request, GetCallback<LockSpaceReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| } |
| |
| TEST_F(BinderServiceTest, ListSpaces) { |
| constexpr uint32_t nvram_index_list[] = {3, 4, 5}; |
| ListSpacesRequest request; |
| EXPECT_CALL(mock_nvram_service_, ListSpaces(_, _)) |
| .WillOnce(Invoke([nvram_index_list]( |
| const ListSpacesRequest& request, |
| const TpmNvramInterface::ListSpacesCallback& callback) { |
| ListSpacesReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| for (auto index : nvram_index_list) { |
| reply.add_index_list(index); |
| } |
| callback.Run(reply); |
| })); |
| ListSpacesReply reply; |
| nvram_proxy_->ListSpaces(request, GetCallback<ListSpacesReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| EXPECT_EQ(arraysize(nvram_index_list), reply.index_list_size()); |
| for (size_t i = 0; i < 3; i++) { |
| EXPECT_EQ(nvram_index_list[i], reply.index_list(i)); |
| } |
| } |
| |
| TEST_F(BinderServiceTest, GetSpaceInfo) { |
| uint32_t nvram_index = 5; |
| size_t nvram_size = 32; |
| GetSpaceInfoRequest request; |
| request.set_index(nvram_index); |
| EXPECT_CALL(mock_nvram_service_, GetSpaceInfo(_, _)) |
| .WillOnce(Invoke([nvram_index, nvram_size]( |
| const GetSpaceInfoRequest& request, |
| const TpmNvramInterface::GetSpaceInfoCallback& callback) { |
| EXPECT_TRUE(request.has_index()); |
| EXPECT_EQ(nvram_index, request.index()); |
| GetSpaceInfoReply reply; |
| reply.set_result(NVRAM_RESULT_SUCCESS); |
| reply.set_size(nvram_size); |
| reply.set_is_read_locked(true); |
| reply.set_is_write_locked(true); |
| callback.Run(reply); |
| })); |
| GetSpaceInfoReply reply; |
| nvram_proxy_->GetSpaceInfo(request, GetCallback<GetSpaceInfoReply>(&reply)); |
| EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result()); |
| EXPECT_TRUE(reply.has_size()); |
| EXPECT_EQ(nvram_size, reply.size()); |
| EXPECT_TRUE(reply.is_read_locked()); |
| EXPECT_TRUE(reply.is_write_locked()); |
| } |
| |
| } // namespace tpm_manager |