blob: 77fc5b5d6547322f9fef50c61b9df711e16c12d4 [file] [edit]
// 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.
//
#ifndef THIRD_PARTY_CREDENTIO_CLAIM_MANIFEST_BOX_ENCODER_H_
#define THIRD_PARTY_CREDENTIO_CLAIM_MANIFEST_BOX_ENCODER_H_
#include <cstddef>
#include <string>
#include <vector>
#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "assertion/assertion_cbor_encoder.h"
#include "assertion/assertion_referencer.h"
#include "claim/claim_cbor_encoder.h"
#include "claim/manifest_box.h"
#include "claim/signer.h"
#include "constants/labels.h"
#include "crypto/algorithms.h"
#include "google/protobuf/repeated_ptr_field.h"
#include "jumbf/box_builder.h"
#include "proto/assertion.pb.h"
#include "proto/generator_info.pb.h"
#include "proto/hashed_uri.pb.h"
#include "proto/multi_asset_hash_assertion.pb.h"
#include "salt/salt_generator.h"
namespace credentio {
struct ManifestEncoderResult {
// Generated JUMBF manifest store superbox.
jumbf::BuiltSuperBox box;
};
class ManifestBoxEncoder {
public:
ManifestBoxEncoder(
const AssertionReferencer* absl_nonnull assertion_reference,
const GeneratorInfo* absl_nonnull generator_info,
const ClaimSigner* absl_nonnull claim_signer,
const AssertionCborEncoder* absl_nonnull assertion_cbor_encoder,
const ClaimCborEncoder* absl_nonnull claim_cbor_encoder,
ManifestBox* absl_nonnull manifest, HashAlgorithm hash_algorithm,
const SaltGenerator* absl_nonnull salt_generator)
: assertion_reference_(*ABSL_DIE_IF_NULL(assertion_reference)),
generator_info_(*ABSL_DIE_IF_NULL(generator_info)),
claim_signer_(*ABSL_DIE_IF_NULL(claim_signer)),
manifest_builder_(kStandardManifestUuid,
{.label = absl::Cord(manifest->label)}),
manifest_(*ABSL_DIE_IF_NULL(manifest)),
hash_algorithm_(hash_algorithm),
assertion_cbor_encoder_(*ABSL_DIE_IF_NULL(assertion_cbor_encoder)),
claim_cbor_encoder_(*ABSL_DIE_IF_NULL(claim_cbor_encoder)),
salt_generator_(*ABSL_DIE_IF_NULL(salt_generator)) {}
// Encodes the manifest to a JUMBF-type box.
// Consumes the provided ManifestBox.
// Encodings are done in the following order:
// 1. Build all assertions, resolving references between them.
// 2. Encode the claim and signature.
// 3. Encode the assertion store.
void Encode(
const ClaimSigner::Options& options,
absl::AnyInvocable<void(absl::StatusOr<ManifestEncoderResult>) &&> cb);
private:
// Encodes the given assertion and adds it to assertion_boxes_,
// assertion_hashed_uris_, and assertion_url_to_index_. The assertion box is
// salted with salt_generator_.
absl::Status AddAssertion(Assertion& assertion);
// Populates hashes for hashed URIs in the given actions assertion, then adds
// it via AddAssertion.
absl::Status AddActionsAssertion(Assertion assertion);
// Builds all assertions in the manifest and resolves references between
// them, populating assertion_boxes_, assertion_hashed_uris_, and
// assertion_url_to_index_.
absl::Status AddAssertions();
// Encodes and signs the claim, adding claim and claim signature boxes to
// manifest_builder_.
void EncodeClaimAndSignature(
const ClaimSigner::Options& options,
absl::AnyInvocable<void(absl::StatusOr<ManifestEncoderResult>) &&> cb);
// Adds the assertion store box to manifest_builder_.
absl::Status EncodeAssertionStore();
// Populates hashed URIs in the given multi-asset hash assertion.
// Assumes that the referenced part hash assertions have already been added.
absl::Status PopulateMultiAssetPartHashes(
MultiAssetHashAssertion* assertion) const;
// Encodes a gathered assertion as a JSON content superbox, generates its
// hashed URI, adds the box to assertion_boxes_, and adds the hashed URI to
// gathered_assertion_hashed_uris_.
absl::Status AddGatheredAssertion(
const GatheredAssertion& gathered_assertion);
const AssertionReferencer& assertion_reference_;
const GeneratorInfo& generator_info_;
const ClaimSigner& claim_signer_;
jumbf::SuperBoxBuilder manifest_builder_;
ManifestBox& manifest_;
// Redacted assertions to be added to the claim.
std::vector<std::string> redacted_assertions_;
std::vector<jumbf::BuiltSuperBox> assertion_boxes_;
google::protobuf::RepeatedPtrField<HashedUri> assertion_hashed_uris_;
google::protobuf::RepeatedPtrField<HashedUri> gathered_assertion_hashed_uris_;
// Map from relative assertion URL (e.g.
// "self#jumbf=c2pa.assertions/c2pa.actions.v2") to index in assertion_uris_.
// Needed for resolving references between assertions.
absl::flat_hash_map<std::string, size_t> assertion_url_to_index_;
HashAlgorithm hash_algorithm_;
const AssertionCborEncoder& assertion_cbor_encoder_;
const ClaimCborEncoder& claim_cbor_encoder_;
const SaltGenerator& salt_generator_;
};
} // namespace credentio
#endif // THIRD_PARTY_CREDENTIO_CLAIM_MANIFEST_BOX_ENCODER_H_