| // 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 "claim/timestamp_updater.h" | |
| #include <cstddef> | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include "absl/base/nullability.h" | |
| #include "absl/functional/any_invocable.h" | |
| #include "absl/status/status.h" | |
| #include "absl/strings/string_view.h" | |
| #include "async/async_context.h" | |
| #include "claim/manifest_store_view.h" | |
| #include "cose/sig_structure.h" | |
| #include "cose/timestamp_updater.h" | |
| namespace credentio { | |
| void ClaimTimestampUpdater::InsertTimestamp( | |
| std::string* absl_nonnull manifest_store, AsyncContext async_context, | |
| absl::AnyInvocable<void(absl::Status) &&> cb) const { | |
| auto manifest_store_view = ManifestStoreView::Create(*manifest_store); | |
| if (!manifest_store_view.ok()) { | |
| AsyncResolver<void>(async_context, std::move(cb)) | |
| .Return(manifest_store_view.status()); | |
| return; | |
| } | |
| auto manifest_view = manifest_store_view->GetActiveManifest(); | |
| if (!manifest_view.ok()) { | |
| AsyncResolver<void>(async_context, std::move(cb)) | |
| .Return(manifest_view.status()); | |
| return; | |
| } | |
| auto claim_signature_view = manifest_view->GetClaimSignature(); | |
| if (!claim_signature_view.ok()) { | |
| AsyncResolver<void>(async_context, std::move(cb)) | |
| .Return(claim_signature_view.status()); | |
| return; | |
| } | |
| auto cose_sign1 = claim_signature_view->GetStruct(); | |
| if (!cose_sign1.ok()) { | |
| AsyncResolver<void>(async_context, std::move(cb)) | |
| .Return(cose_sign1.status()); | |
| return; | |
| } | |
| if (cose_sign1->unprotected_header.sig_tst2.has_value()) { | |
| AsyncResolver<void>(async_context, std::move(cb)).Return(absl::OkStatus()); | |
| return; | |
| } | |
| auto signature = claim_signature_view->GetPayload(); | |
| if (!signature.ok()) { | |
| AsyncResolver<void>(async_context, std::move(cb)) | |
| .Return(signature.status()); | |
| return; | |
| } | |
| auto updated_signature = std::make_shared<std::string>(*signature); | |
| absl::AnyInvocable<void(absl::Status) &&> done_cb = | |
| [manifest_store, signature = *signature, updated_signature, async_context, | |
| cb = std::move(cb)](absl::Status status) mutable { | |
| AsyncResolver<void> resolver(async_context, std::move(cb)); | |
| if (!status.ok()) { | |
| resolver.Return(status); | |
| return; | |
| } | |
| if (updated_signature->size() != signature.size()) { | |
| resolver.Return( | |
| absl::InternalError("updated signature size does not match the " | |
| "original size.")); | |
| return; | |
| } | |
| size_t signature_offset = | |
| signature.begin() - absl::string_view(*manifest_store).begin(); | |
| manifest_store->replace(signature_offset, signature.size(), | |
| *updated_signature); | |
| resolver.Return(absl::OkStatus()); | |
| }; | |
| TimestampUpdater updater(timestamp_creator_.get()); | |
| updater.UpdateTimestamp(updated_signature.get(), async_context, | |
| std::move(done_cb)); | |
| } | |
| } // namespace credentio |