Skip to main content

C2PA manifest embedding, hard binding, and verification for OpenType/TrueType (SFNT) fonts

Project description

c2pa-fonts

C2PA manifest embedding, hard binding, and verification for OpenType/TrueType (SFNT) fonts

crates.io docs.rs License

Overview

Implements the font embedding method from the C2PA Technical Specification and its c2pa.hash.data hard binding, for fonts that conform to the OpenType or OFF (ISO/IEC 14496-22) specification.

The manifest is stored in a dedicated SFNT table with the tag C2PA, which may carry an embedded Manifest Store, a remote manifest URI, or both:

Field Type Description
majorVersion / minorVersion uint16 Version of the C2PA font table
activeManifestUri Offset32 + uint16 URI of the active manifest (offset + length; 0 when absent)
manifestStore Offset32 + uint32 Embedded C2PA Manifest Store (offset + length; 0 when absent)

The C2PA font table is preliminary. The C2PA specification states the table format "is not yet defined in the OFF nor OpenType specification; the following definition is preliminary." There is no stable, ratified conformance requirement for fonts. This crate tracks the preliminary definition and emits table version 0.1.

What this crate does — and does not

Validating a font's provenance is a fixed pipeline. Only two steps are font-specific; this crate owns exactly those:

Step Owner
1. Locate + extract the Manifest Store c2pa-fonts
2. Parse the JUMBF/CBOR manifest c2pa-rs
3. Verify the COSE signature c2pa-rs
4. Evaluate the X.509 trust chain c2pa-rs
5. Hard binding: c2pa.hash.data exclusion geometry over the font c2pa-fonts
6. Validate assertions / ingredients c2pa-rs

This crate does not build manifests, sign, or implement COSE/trust — that is the official c2pa SDK's job. With the validation feature it delegates steps 2–4 and 6 to c2pa-rs, so an application using both can act as a C2PA generator and verifier for fonts. (This crate is a building block; C2PA conformance certification is a separate program for products, which this crate makes no claim to.)

Font collections (.ttc/ttcf) and WOFF/WOFF2 are rejected explicitly; decompress WOFF to SFNT first.

Quick Start

[dependencies]
c2pa-fonts = "0.2"
# Hard-binding hashers and the c2pa-rs validation bridge:
c2pa-fonts = { version = "0.2", features = ["validation"] }

Bindings for the zero-dependency core (embed, extract, hard-binding geometry) ship for JavaScript and Python:

npm install @writerslogic/c2pa-fonts   # wasm-bindgen, camelCase API
pip install c2pa-fonts                  # PyO3 abi3 wheel

Embed an already-signed manifest

use c2pa_fonts::{embed_manifest, ManifestSource};

let font: &[u8] = /* .ttf / .otf bytes */;
let signed = embed_manifest(font, ManifestSource::embedded(manifest_store)).unwrap();
// or ManifestSource::remote("https://example.com/m.c2pa") / ManifestSource::both(uri, store)

Generate with a hard binding (placeholder-then-fill)

The manifest signs over the font, so the font must be laid out before signing. Reserve the store, hash over the returned exclusions, sign a manifest that fits, then fill:

use c2pa_fonts::{reserve_manifest, fill_manifest, data_hash_ranges};

// 1. Reserve space; get the font-with-placeholder and its exclusions.
let reserved = reserve_manifest(font, 30_000, None).unwrap();

// 2. Hash reserved.font over reserved.exclusions and sign a data-hashed manifest
//    with the c2pa SDK (see tests/roundtrip.rs for the full flow).
//    data_hash_ranges(&reserved.font) yields the ranges as c2pa `HashRange`s.

// 3. Fill the reserved region with the signed manifest (<= reserved size).
let final_font = fill_manifest(&reserved.font, &signed_manifest).unwrap();

The exclusions cover the manifest store and the two checksum fields that depend on it (the C2PA table's directory checksum and head.checkSumAdjustment), so filling never invalidates the hash.

Read and verify

use c2pa_fonts::{read_manifest, read_manifest_uri, verify, validate};

let manifest = read_manifest(&final_font).unwrap();       // embedded store bytes
let uri = read_manifest_uri(&final_font).unwrap();        // Option<String>

let report = verify(&final_font).unwrap();                // structural, zero-dep
assert!(report.is_compliant());

// End-to-end (feature = "validation"): hard binding here, signature/trust via c2pa-rs.
let result = validate(&final_font).unwrap();
assert!(result.hard_binding_valid);
// result.state, result.success_codes, result.failure_codes, result.manifest_json

Design

  • The Manifest Store and/or active manifest URI live in a single C2PA SFNT table
  • Embedding normalizes the font: the table directory is re-sorted by tag, offsets re-aligned to 4-byte boundaries, and per-table checksums plus head.checkSumAdjustment recomputed
  • verify checks C2PA table well-formedness and SFNT checksum integrity; more than one C2PA table is rejected
  • validate (feature) extracts the store and delegates COSE/trust/assertion validation to c2pa-rs; trust uses c2pa-rs default settings — inspect the returned state and status codes
  • Single fonts only; collections and WOFF are rejected

Related Crates

Crate Description
c2pa-warc WARC web archive embedding (ISO 28500)
c2pa-structured-text Structured text embedding via ASCII armour delimiters
c2pa-text-binding Soft binding and content fingerprinting for text assets
c2pa-rs Official C2PA SDK

License

Licensed under either of Apache License, Version 2.0 or MIT License at your option.

Built by WritersLogic

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

c2pa_fonts-0.2.0.tar.gz (51.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

c2pa_fonts-0.2.0-cp39-abi3-win_amd64.whl (129.8 kB view details)

Uploaded CPython 3.9+Windows x86-64

c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (265.2 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (260.3 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

c2pa_fonts-0.2.0-cp39-abi3-macosx_11_0_arm64.whl (234.8 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file c2pa_fonts-0.2.0.tar.gz.

File metadata

  • Download URL: c2pa_fonts-0.2.0.tar.gz
  • Upload date:
  • Size: 51.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for c2pa_fonts-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8ec6aab70415d152726a21fee148edc70ff8ca3a13bc2365674c5eb55e404667
MD5 9bd2860664781e4f2e3fbf946e94daa4
BLAKE2b-256 51de5c82a312d7666ae542d5ef2b7cdc24b68f3420d74b33ef5a890b279b1598

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.2.0.tar.gz:

Publisher: release.yml on writerslogic/c2pa-fonts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file c2pa_fonts-0.2.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: c2pa_fonts-0.2.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 129.8 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for c2pa_fonts-0.2.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 8baca510225d876872c86fb7e93ffa757b437ef7d1ccb29b0650d3c680b0ee0c
MD5 ba50ca8b614419b386a1a9a1f1eeaca8
BLAKE2b-256 27f8cd98632f5cbf13bb91350ede8a5ffb96a7d9684a23a58b06a464708b1801

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.2.0-cp39-abi3-win_amd64.whl:

Publisher: release.yml on writerslogic/c2pa-fonts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 696fd4928616a5f8bfc65d43758971b83b049a0788c6661294c9491f7ecbf365
MD5 65952c3abeb4be794ca0d5a550076a53
BLAKE2b-256 d9bbaca9fc6933c3c90d5181f434661e326de534f29022dfc9c4bec9c39eec30

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on writerslogic/c2pa-fonts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 756cbae4166d072e87a9ed2eeb89e14cb262ce46a375643d1a6b27a549f4cad3
MD5 dec320a7eb5dcc700283941b2288d300
BLAKE2b-256 1560db4ba4defc1666c39ac7b19806b8d5453cf2b1b98a3c466cb0af2c0b991c

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on writerslogic/c2pa-fonts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file c2pa_fonts-0.2.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c2pa_fonts-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 044ed044b67ceb46e7ffb5e5a89a9846396a47c9e4935077f87bb7d697267ccc
MD5 4ca7a93d7d2862912f677c99b3517deb
BLAKE2b-256 62f7489375526e87df0d2f446281869046ff909f9499cd6c57b48e9030327e40

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.2.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on writerslogic/c2pa-fonts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page