| // Copyright 2026 Google LLC | |
| // | |
| // 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 | |
| // | |
| // https://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 "crypto/templated_crypto_write_handler.h" | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include "absl/status/status_matchers.h" | |
| #include "absl/status/statusor.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/synchronization/notification.h" | |
| #include "absl/time/simulated_clock.h" | |
| #include "absl/time/time.h" | |
| #include "crypto/algorithms.h" | |
| #include "crypto/crypto_write_handler.h" | |
| #include "crypto/default/hasher.h" | |
| #include "crypto/hash.h" | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| #include "testing/create_test_crypto_write_handler.h" | |
| namespace credentio { | |
| namespace { | |
| using ::testing::ElementsAreArray; | |
| using ::testing::IsEmpty; | |
| absl::StatusOr<std::string> GetTimestamp(CryptoWriteHandler& handler, | |
| HashAlgorithm hash_algorithm, | |
| absl::string_view hashed_message) { | |
| absl::Notification done; | |
| absl::StatusOr<std::string> result; | |
| handler.CreateTimestamp(hash_algorithm, std::string(hashed_message), | |
| /*options=*/{}, | |
| [&result, &done](absl::StatusOr<std::string> res) { | |
| result = std::move(res); | |
| done.Notify(); | |
| }); | |
| done.WaitForNotification(); | |
| return result; | |
| } | |
| TEST(TemplatedCryptoWriteHandlerTest, Create) { | |
| absl::StatusOr<std::unique_ptr<CryptoWriteHandler>> sign_handler = | |
| CreateTestCryptoWriteHandler({}); | |
| ABSL_ASSERT_OK(sign_handler); | |
| TemplatedCryptoWriteHandler mock_handler(sign_handler->get()); | |
| const FixedKeySigner& signer = (*sign_handler)->GetSigner(); | |
| EXPECT_EQ(signer.algorithm(), mock_handler.GetSigner().algorithm()); | |
| EXPECT_EQ(signer.max_signature_byte_size(), | |
| mock_handler.GetSigner().max_signature_byte_size()); | |
| EXPECT_THAT(signer.certificate_chain(), | |
| ElementsAreArray(mock_handler.GetSigner().certificate_chain())); | |
| EXPECT_THAT(signer.ocsp_responses(), | |
| ElementsAreArray(mock_handler.GetSigner().ocsp_responses())); | |
| absl::StatusOr<SignResponse> real_signature = signer.Sign("to_be_signed"); | |
| ABSL_ASSERT_OK(real_signature); | |
| absl::StatusOr<SignResponse> mock_signature = | |
| mock_handler.GetSigner().Sign("to_be_signed"); | |
| ABSL_ASSERT_OK(mock_signature); | |
| EXPECT_EQ(mock_signature->signature.size(), signer.max_signature_byte_size()); | |
| absl::StatusOr<std::unique_ptr<Hasher>> hasher = | |
| CreateHasher(HashAlgorithm::kSha384); | |
| ABSL_ASSERT_OK(hasher); | |
| (*hasher)->Update(real_signature->signature); | |
| std::string hashed_message = (*hasher)->Digest(); | |
| absl::StatusOr<std::string> mock_timestamp = | |
| GetTimestamp(mock_handler, HashAlgorithm::kSha384, hashed_message); | |
| ABSL_ASSERT_OK(mock_timestamp); | |
| EXPECT_EQ(mock_timestamp->size(), | |
| (*sign_handler)->max_timestamp_byte_size(HashAlgorithm::kSha384)); | |
| } | |
| TEST(TemplatedCryptoWriteHandlerTest, OcspExpired) { | |
| absl::SimulatedClock clock; | |
| absl::StatusOr<std::unique_ptr<CryptoWriteHandler>> sign_handler = | |
| CreateTestCryptoWriteHandler({.clock = &clock}); | |
| ABSL_ASSERT_OK(sign_handler); | |
| TemplatedCryptoWriteHandler mock_handler(sign_handler->get()); | |
| clock.AdvanceTime(absl::Hours(24 * 365)); | |
| EXPECT_THAT(mock_handler.GetSigner().ocsp_responses(), IsEmpty()); | |
| } | |
| } // namespace | |
| } // namespace credentio |