| // 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 "cose/timestamp_creator.h" | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include "absl/status/status.h" | |
| #include "absl/status/status_matchers.h" | |
| #include "absl/status/statusor.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/time/clock_interface.h" | |
| #include "absl/time/simulated_clock.h" | |
| #include "absl/time/time.h" | |
| #include "cose/sig_structure.h" | |
| #include "cose/simple_cms_parser.h" | |
| #include "crypto/default/hasher.h" | |
| #include "crypto/timestamp_write_handler.h" | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| #include "testing/create_test_crypto_write_handler.h" | |
| #include "testing/local_key_crypto_write_handler.h" | |
| #include "tsp/parsed_timestamp_token.h" | |
| #include "tsp/timestamp_verifier.h" | |
| #include "tsp/verified_timestamp.h" | |
| namespace credentio { | |
| namespace { | |
| constexpr absl::Time kTestTime = absl::FromUnixSeconds(1741403167); | |
| absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> CreateTimestampHandler( | |
| absl::Clock* clock) { | |
| return CreateTestCryptoWriteHandler({.clock = clock}); | |
| } | |
| absl::StatusOr<std::string> CreateTimestamp( | |
| TimestampCreator& creator, TimestampCreator::Options options, | |
| CoseSign1TaggedStructure cose_sign1) { | |
| absl::StatusOr<std::string> result = | |
| absl::InternalError("Callback not called"); | |
| // We pass a ref to this temporary struct to catch bugs where the | |
| // provided ref might be accessed after CreateTimestamp returns. | |
| CoseSign1TaggedStructure cose_sign1_copy = cose_sign1; | |
| creator.CreateTimestamp(cose_sign1_copy, std::move(options), | |
| [&](absl::StatusOr<std::string> cb_result) { | |
| result = std::move(cb_result); | |
| }); | |
| return result; | |
| } | |
| TEST(TimestampCreator, CreateTimestamp) { | |
| // Create a timestamp creator. | |
| absl::SimulatedClock clock; | |
| clock.SetTime(kTestTime); | |
| absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> timestamp_handler = | |
| CreateTimestampHandler(&clock); | |
| ABSL_ASSERT_OK(timestamp_handler); | |
| TimestampCreator timestamp_creator(timestamp_handler->get(), | |
| &DefaultHasherFactory()); | |
| // Create a timestamp. | |
| CoseSign1TaggedStructure cose_sign1{.protected_header = "def", | |
| .signature = "abc"}; | |
| absl::StatusOr<std::string> timestamp = | |
| CreateTimestamp(timestamp_creator, /*options=*/{}, cose_sign1); | |
| ABSL_ASSERT_OK(timestamp); | |
| // Verify the timestamp. | |
| TimestampVerifier verifier(/*tsa_roots=*/nullptr); | |
| SimpleCmsParser parser; | |
| absl::StatusOr<std::unique_ptr<ParsedTimestampToken>> parsed_token = | |
| parser.ParseTimestampToken(*timestamp); | |
| ABSL_ASSERT_OK(parsed_token); | |
| absl::StatusOr<VerifiedTimestamp> verified_timestamp = | |
| verifier.VerifyTimestampToken(**parsed_token); | |
| ABSL_ASSERT_OK(verified_timestamp); | |
| EXPECT_EQ(verified_timestamp->asserted_time(), kTestTime); | |
| } | |
| } // namespace | |
| } // namespace credentio |