Skip to main content

crates.io docs.rs CI OpenSSF Scorecard 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 specification marks this table format as preliminary: "The C2PA table format is not yet defined in the OFF nor OTF specification; the following definition is preliminary." The layout below tracks that definition and will follow it if it changes.

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

Part of a family of single-purpose crates, one per C2PA embedding method. Each is standalone and independently versioned.

Crate Description
c2pa-structured-text Structured text: ASCII-armoured manifest in a comment or front matter
c2pa-unstructured-text Unstructured text: invisible Unicode variation-selector run
c2pa-html HTML: script and link elements in the document head
c2pa-http HTTP: the c2pa-manifest Link header, with a Tower middleware
c2pa-text-binding Soft binding and content fingerprinting for text assets
c2pa-vtt WebVTT caption and subtitle embedding
c2pa-zip ZIP-based documents: EPUB, DOCX, ODT, OXPS
c2pa-warc WARC web archive embedding (ISO 28500)
c2pa-ml ML model containers: GGUF, SafeTensors, ONNX
c2pa Official C2PA SDK

Security

Found a vulnerability? Please report it privately — see SECURITY.md.

License

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

Built by WritersLogic

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.3.0.tar.gz (55.7 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.3.0-cp39-abi3-win_amd64.whl (130.9 kB view details)

Uploaded CPython 3.9+Windows x86-64

c2pa_fonts-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (265.6 kB view details)

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

c2pa_fonts-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (260.5 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

c2pa_fonts-0.3.0-cp39-abi3-macosx_11_0_arm64.whl (233.7 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: c2pa_fonts-0.3.0.tar.gz
  • Upload date:
  • Size: 55.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for c2pa_fonts-0.3.0.tar.gz
Algorithm Hash digest
SHA256 eaad42d9a48d54c02b92dc9b4b1ffa74eb56b2052f2249bb2712ccde923348ee
MD5 d89f7cc07e515242a75607e8c2b52614
BLAKE2b-256 b7bcc08eb155be46e89051207d7dfadf4b456b2d008f44a08071fac0174578c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.3.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.3.0-cp39-abi3-win_amd64.whl.

File metadata

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

File hashes

Hashes for c2pa_fonts-0.3.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c112eedb83da4b6f2d30d6948d04e2cb0cdf5daf462825c5360090474aab2c75
MD5 83de4ee42f8d750ce84f5bb41b5ff34b
BLAKE2b-256 4294bae1b97f66ddd4ada265c21de3dd4848d3d6835a89ba8e2c61b16f41e465

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.3.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.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c2pa_fonts-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ad6cea40a973330f7e225e8e96d9caaed3473cb364e90a0d15f5cb7a254cac3d
MD5 c35ef98ad9a33c92a55af0d7b83f3a38
BLAKE2b-256 ae9b5d145eb33794cc419e267fcc39188626bb721b842a351473135f8ff9a71f

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.3.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.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c2pa_fonts-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 75eab9e33e96c278683489e5ea0b1d1b1a26d1334f813276dac5ba2220e1a768
MD5 8ec93b609e4eb7181ae8777b660b22fa
BLAKE2b-256 93ffa58c78bc35ff22463a4cc24c88cb3e7dd865ec6dc63fff2b892555a9e2ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.3.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.3.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c2pa_fonts-0.3.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3c2ea10a36568810f5662db74a69dc366f2a84dd5ae83fd057a7b8185e5a68e2
MD5 930e4d22b6e897588f29f8cdd6aedc57
BLAKE2b-256 149768d2ff48daa97a18c806853c02d6667881b2cf06f8bce4551a56fe456d71

See more details on using hashes here.

Provenance

The following attestation bundles were made for c2pa_fonts-0.3.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.

Release history Release notifications | RSS feed

This release

0.3.0 This release

5 files

0.2.0

5 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page