Credentio

C++ libraries to support validation and generation of C2PA Content Credentials (https://c2pa.org/).

NOTE: We are actively developing this project and may introduce breaking changes without notice.

Supported Media Formats

The library supports C2PA provenance validation (extracting and verifying an embedded C2PA manifest store) and generation (embedding a newly generated and signed C2PA manifest store) for the following container formats:

FormatExtensionsValidationGeneration
JPEG.jpg, .jpegYesYes
PNG.pngYesYes
MP4.mp4YesYes
fMP4 (fragmented MP4)NoNo
RIFF (e.g., WebP, WAV, AVI).webp, .wav, .aviYesYes
TIFF (e.g., TIFF, DNG).tif, .tiff, .dngYesYes
AVIF.avifYesYes
M4A.m4aYesYes
HEIF, HEIC.heif, .heicYesYes
MOV.movYesYes
GIF.gifYesYes
MP3.mp3YesYes
FLAC.flacYesYes
PDF.pdfYesYes
SVGNoNo
OGG VorbisNoNo
TextNoNo
Live stream videoNoNo
ZIP-based containers.docx, .pptx, .xlsxYesYes
FontsNoNo

Prerequisites

  • Clang with libc++ (tested with Clang 19). .bazelrc builds with clang and clang++ against libc++, so both must be on PATH and the libc++ development packages must be installed.
  • Bazelisk, installed as bazel. It downloads the Bazel version pinned in .bazelversion.
  • Git

On Ubuntu, CI sets these up as follows:

# Clang 19, including libc++, from the LLVM apt repository.
sudo apt-get install -y lsb-release wget software-properties-common gnupg
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 19 all
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-19 100

# Bazelisk.
curl -sLO https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64
chmod +x bazelisk-linux-amd64
sudo mv bazelisk-linux-amd64 /usr/local/bin/bazel

Bazel caches the detected C++ toolchain, so after installing or changing the compiler or libc++, run bazel clean --expunge before building again.

Dependencies

Quickstart

Credentio includes fast standalone command-line tools for inspecting, verifying, and writing C2PA metadata embedded in media assets.

Building the CLIs

Build the tools once:

bazel build tools:c2pa_validate tools:asset_write

The binaries are written to bazel-bin/tools/c2pa_validate and bazel-bin/tools/asset_write.

Validating C2PA Metadata

Validating with Trust Anchors

You can validate assets against specific PEM-encoded trust anchors for claim signers and Time Stamping Authorities (TSA):

bazel-bin/tools/c2pa_validate \
  --asset=/path/to/asset.jpg \
  --claim_signer_trust=/path/to/claim_signer_trust_anchors.pem \
  --tsa_trust=/path/to/tsa_trust_anchors.pem

Note on Trust Lists: Credentio does not distribute or provide trust anchor lists. You can obtain the latest official C2PA trust lists from the C2PA organization on GitHub (https://github.com/c2pa-org/conformance-public/tree/main/trust-list).

Writing C2PA Metadata

The asset_write tool generates a C2PA manifest store, signs it with the provided claim signer key, and embeds it into a copy of the input asset. The media type is inferred from the input file extension.

Creating Test Keys and Certificates

asset_write needs an EC P-256 key and certificate for the claim signer, and optionally another pair for the Time Stamping Authority (TSA). For local testing, tools/create_test_pki.sh creates a private root CA and issues both certificates from it. It requires OpenSSL 1.1.1 or later:

tools/create_test_pki.sh test_pki

The script refuses to overwrite existing keys. It produces:

  • claim_signer_key.pem and claim_signer_cert.pem: pass to --claim_signer_key and --claim_signer_cert.
  • tsa_key.pem and tsa_cert.pem: pass to --tsa_key and --tsa_cert.
  • root_ca_cert.pem: pass to --claim_signer_trust and --tsa_trust when validating.

Writing a Manifest Store

bazel-bin/tools/asset_write \
  --input=/path/to/input.jpg \
  --output=/path/to/output.jpg \
  --claim_signer_key=/path/to/claim_signer_key.pem \
  --claim_signer_cert=/path/to/claim_signer_cert_chain.pem \
  --tsa_key=/path/to/tsa_key.pem \
  --tsa_cert=/path/to/tsa_cert.pem

Flags:

  • --claim_signer_key: PEM-encoded EC P-256 private key of the claim signer.
  • --claim_signer_cert: PEM-encoded claim signer certificate chain, leaf first.
  • --claim_signer_ocsp (optional): DER-encoded OCSP response for the claim signer certificate.
  • --tsa_key, --tsa_cert (optional): PEM-encoded EC P-256 private key and certificate used to timestamp the claim signature locally. If omitted, timestamping is disabled.
  • --disable_timestamping (optional): Disables timestamping.
  • --request_txtpb (optional): Text-format GenerateManifestStoreRequest describing the manifest to generate. Defaults to a single c2pa.created action.

End-to-End Example

Using the files from Creating Test Keys and Certificates, sign an asset and validate it against the test root CA. Run these commands from the repository root:

tools/create_test_pki.sh test_pki

bazel-bin/tools/asset_write \
  --input=/path/to/input.jpg \
  --output=signed.jpg \
  --claim_signer_key=test_pki/claim_signer_key.pem \
  --claim_signer_cert=test_pki/claim_signer_cert.pem \
  --tsa_key=test_pki/tsa_key.pem \
  --tsa_cert=test_pki/tsa_cert.pem

bazel-bin/tools/c2pa_validate \
  --asset=signed.jpg \
  --claim_signer_trust=test_pki/root_ca_cert.pem \
  --tsa_trust=test_pki/root_ca_cert.pem

The validation result should report claimSignature.validated, signingCredential.trusted and timeStamp.trusted with no failures.

Note: asset_write signs with locally supplied keys and is intended for development and testing. Manifest stores it produces are only trusted by validators that trust the supplied certificates.

Building & Testing

To build the entire project:

bazel build ...

To execute all unit tests:

bazel test ...

Support & Releases

Credentio recommends that users live-at-head (updating to the latest commit on the main branch as often as possible). We are actively developing this project and may introduce breaking changes without notice.

License & Disclaimer

Credentio is licensed under the terms of the Apache 2.0 License. See LICENSE for more information.

Disclaimer

This is not an officially supported Google product. This project is not eligible for the Google Open Source Software Vulnerability Rewards Program.

Contact

For questions, feedback, or inquiries, please contact: credentio-team@google.com.