| // |
| // 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 <memory> |
| #include <string> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "attestation/common/mock_crypto_utility.h" |
| #include "attestation/server/database_impl.h" |
| |
| using testing::_; |
| using testing::Invoke; |
| using testing::NiceMock; |
| using testing::Return; |
| using testing::WithArgs; |
| |
| namespace { |
| |
| const char kFakeCredential[] = "1234"; |
| |
| } // namespace |
| |
| namespace attestation { |
| |
| class DatabaseImplTest : public testing::Test, public DatabaseIO { |
| public: |
| ~DatabaseImplTest() override = default; |
| void SetUp() override { |
| database_.reset(new DatabaseImpl(&mock_crypto_utility_)); |
| database_->set_io(this); |
| InitializeFakeData(); |
| database_->Initialize(); |
| } |
| |
| // Fake DatabaseIO::Read. |
| bool Read(std::string* data) override { |
| if (fake_persistent_data_readable_) { |
| *data = fake_persistent_data_; |
| } |
| return fake_persistent_data_readable_; |
| } |
| |
| // Fake DatabaseIO::Write. |
| bool Write(const std::string& data) override { |
| if (fake_persistent_data_writable_) { |
| fake_persistent_data_ = data; |
| } |
| return fake_persistent_data_writable_; |
| } |
| |
| // Fake DatabaseIO::Watch. |
| void Watch(const base::Closure& callback) override { |
| fake_watch_callback_ = callback; |
| } |
| |
| // Initializes fake_persistent_data_ with a default value. |
| void InitializeFakeData() { |
| AttestationDatabase proto; |
| proto.mutable_credentials()->set_conformance_credential(kFakeCredential); |
| proto.SerializeToString(&fake_persistent_data_); |
| } |
| |
| protected: |
| std::string fake_persistent_data_; |
| bool fake_persistent_data_readable_{true}; |
| bool fake_persistent_data_writable_{true}; |
| base::Closure fake_watch_callback_; |
| NiceMock<MockCryptoUtility> mock_crypto_utility_; |
| std::unique_ptr<DatabaseImpl> database_; |
| }; |
| |
| TEST_F(DatabaseImplTest, ReadSuccess) { |
| database_->GetMutableProtobuf()->Clear(); |
| EXPECT_TRUE(database_->Reload()); |
| EXPECT_EQ(std::string(kFakeCredential), |
| database_->GetProtobuf().credentials().conformance_credential()); |
| } |
| |
| TEST_F(DatabaseImplTest, ReadFailure) { |
| fake_persistent_data_readable_ = false; |
| database_->GetMutableProtobuf()->Clear(); |
| EXPECT_FALSE(database_->Reload()); |
| EXPECT_FALSE(database_->GetProtobuf().has_credentials()); |
| } |
| |
| TEST_F(DatabaseImplTest, DecryptFailure) { |
| EXPECT_CALL(mock_crypto_utility_, DecryptData(_, _, _)) |
| .WillRepeatedly(Return(false)); |
| database_->GetMutableProtobuf()->Clear(); |
| EXPECT_FALSE(database_->Reload()); |
| EXPECT_FALSE(database_->GetProtobuf().has_credentials()); |
| } |
| |
| TEST_F(DatabaseImplTest, WriteSuccess) { |
| database_->GetMutableProtobuf() |
| ->mutable_credentials() |
| ->set_platform_credential("test"); |
| std::string expected_data; |
| database_->GetProtobuf().SerializeToString(&expected_data); |
| EXPECT_TRUE(database_->SaveChanges()); |
| EXPECT_EQ(expected_data, fake_persistent_data_); |
| } |
| |
| TEST_F(DatabaseImplTest, WriteFailure) { |
| fake_persistent_data_writable_ = false; |
| database_->GetMutableProtobuf() |
| ->mutable_credentials() |
| ->set_platform_credential("test"); |
| EXPECT_FALSE(database_->SaveChanges()); |
| } |
| |
| TEST_F(DatabaseImplTest, EncryptFailure) { |
| EXPECT_CALL(mock_crypto_utility_, EncryptData(_, _, _, _)) |
| .WillRepeatedly(Return(false)); |
| database_->GetMutableProtobuf() |
| ->mutable_credentials() |
| ->set_platform_credential("test"); |
| EXPECT_FALSE(database_->SaveChanges()); |
| } |
| |
| TEST_F(DatabaseImplTest, IgnoreLegacyEncryptJunk) { |
| // Legacy encryption scheme appended a SHA-1 hash before encrypting. |
| fake_persistent_data_ += std::string(20, 'A'); |
| EXPECT_EQ(std::string(kFakeCredential), |
| database_->GetProtobuf().credentials().conformance_credential()); |
| } |
| |
| TEST_F(DatabaseImplTest, Reload) { |
| AttestationDatabase proto; |
| proto.mutable_credentials()->set_platform_credential(kFakeCredential); |
| proto.SerializeToString(&fake_persistent_data_); |
| EXPECT_EQ(std::string(), |
| database_->GetProtobuf().credentials().platform_credential()); |
| EXPECT_TRUE(database_->Reload()); |
| EXPECT_EQ(std::string(kFakeCredential), |
| database_->GetProtobuf().credentials().platform_credential()); |
| } |
| |
| TEST_F(DatabaseImplTest, AutoReload) { |
| AttestationDatabase proto; |
| proto.mutable_credentials()->set_platform_credential(kFakeCredential); |
| proto.SerializeToString(&fake_persistent_data_); |
| EXPECT_EQ(std::string(), |
| database_->GetProtobuf().credentials().platform_credential()); |
| fake_watch_callback_.Run(); |
| EXPECT_EQ(std::string(kFakeCredential), |
| database_->GetProtobuf().credentials().platform_credential()); |
| } |
| |
| } // namespace attestation |