| // 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 <optional> | |
| #include <string> | |
| #include <utility> | |
| #include "absl/functional/any_invocable.h" | |
| #include "absl/status/status_macros.h" | |
| #include "absl/status/statusor.h" | |
| #include "absl/strings/string_view.h" | |
| #include "async/async_context.h" | |
| #include "cose/sig_structure.h" | |
| #include "cppbor/cppbor.h" | |
| #include "crypto/hash.h" | |
| #include "crypto/timestamp_write_handler.h" | |
| namespace credentio { | |
| namespace { | |
| absl::StatusOr<std::string> MessageImprintForTimestamp( | |
| const HasherFactory& hasher_factory, absl::string_view body_protected, | |
| absl::string_view message) { | |
| // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_obtaining_the_time_stamp | |
| std::string encoded_message = EncodeSig1Structure({ | |
| .context = "CounterSignature", | |
| .body_protected = std::string(body_protected), | |
| .external_aad = "", | |
| .payload = std::string(message), | |
| }); | |
| ABSL_ASSIGN_OR_RETURN(auto hasher, hasher_factory.Create()); | |
| hasher->Update(encoded_message); | |
| return hasher->Digest(); | |
| } | |
| } // namespace | |
| void TimestampCreator::CreateTimestamp( | |
| const CoseSign1TaggedStructure& cose_sign1, Options options, | |
| absl::AnyInvocable<void(absl::StatusOr<std::string>) &&> cb) const { | |
| auto signature = cppbor::Bstr(cose_sign1.signature).toString(); | |
| auto hashed_message = MessageImprintForTimestamp( | |
| hasher_factory_, cose_sign1.protected_header, std::move(signature)); | |
| if (!hashed_message.ok()) { | |
| AsyncResolver<std::string>(options.async_context, std::move(cb)) | |
| .Return(hashed_message.status()); | |
| return; | |
| } | |
| TimestampWriteHandler::Options timestamp_handler_options; | |
| timestamp_handler_options.async_context = std::move(options.async_context); | |
| timestamp_handler_.CreateTimestamp(hasher_factory_.algorithm(), | |
| std::move(*hashed_message), | |
| timestamp_handler_options, std::move(cb)); | |
| } | |
| } // namespace credentio |