c2pa-ts
is a pure TypeScript implementation of Coalition for Content Provenance and Authenticity (C2PA) according to specification version 2.0.
It does not use any native binaries or WebAssembly and is therefore truly platform independent. In modern browsers as well as Node.js it should run out of the box. In mobile apps or other environments lacking browser APIs, some external code may be necessary (see below for details).
Developed and curated by TrustNXT in Hamburg, Germany and licensed under the Apache 2.0 License. Contributions welcome!
This library is under active development and not fully functional yet. Proceed with caution!
Anything that's not listed below is not currently planned to be implemented.
- ✅ Reading manifests
- 🚧 Validating manifests (mostly implemented except chain of trust validation)
- ✅ Creating manifests
ℹ️ On C2PA versions: The library is targeted at C2PA specification 2.0, however data structures from older versions of the specification are also supported for backwards compatibility.
ℹ️ Although it is a separate project from C2PA, the library also includes support for several CAWG assertions.
- ✅ JPEG
- ✅ PNG
- ✅ HEIC/HEIF
- ❌ GIF
- ❌ TIFF
- ❌ WebP
- ✅ Data Hash
- ✅ BMFF-Based Hash (except Merkle tree hashing)
- ❌ General Boxes Hash
- ✅ Thumbnail
- ✅ Actions (except action templates and metadata)
- ✅ Ingredient
- ✅ Metadata (specialized, common, generic, and CAWG variants)
- ✅ Creative Work
- ✅ Training and Data Mining (C2PA and CAWG variants)
- ❌ CAWG Identity
- ✅ CBOR boxes
- ✅ JSON boxes
- ✅ Codestream boxes
- ✅ Embedded file boxes
- ✅ UUID boxes
- ✅ C2PA salt boxes
- ❌ Compressed boxes
Reading and validating a manifest
Example usage in a Node.js environment:
import * as fs from 'node:fs/promises';
import { MalformedContentError } from '@trustnxt/c2pa-ts';
import { Asset, BMFF, JPEG, PNG } from '@trustnxt/c2pa-ts/asset';
import { SuperBox } from '@trustnxt/c2pa-ts/jumbf';
import { ManifestStore, ValidationResult, ValidationStatusCode } from '@trustnxt/c2pa-ts/manifest';
if (process.argv.length < 3) {
console.error('Missing filename');
process.exit(1);
}
const buf = await fs.readFile(process.argv[2]);
// Read the asset file and dump some information about its structure
let asset: Asset;
if (JPEG.canRead(buf)) {
asset = new JPEG(buf);
} else if (PNG.canRead(buf)) {
asset = new PNG(buf);
} else if (BMFF.canRead(buf)) {
asset = new BMFF(buf);
} else {
console.error('Unknown file format');
process.exit(1);
}
console.log(asset.dumpInfo());
// Extract the C2PA manifest store in binary JUMBF format
const jumbf = asset.getManifestJUMBF();
if (jumbf) {
let validationResult: ValidationResult;
try {
// Deserialize the JUMBF box structure
const superBox = SuperBox.fromBuffer(jumbf);
console.log('JUMBF structure:');
console.log(superBox.toString());
// Read the manifest store from the JUMBF container
const manifests = ManifestStore.read(superBox);
// Validate the active manifest
validationResult = await manifests.validate(asset);
} catch (e) {
// Gracefully handle any exceptions to make sure we get a well-formed validation result
validationResult = ValidationResult.fromError(e as Error);
}
console.log('Validation result', validationResult);
}
Creating a manifest
This still needs proper example code (issue #58). For now, you can check jpeg-signing.test.ts
.
Usage with JavaScript engines that lack WebCrypto and other browser APIs (such as JavaScriptCore on iOS) is entirely possible but will require some additional code. In particular, a custom CryptoProvider
will need to be created and some polyfills might be required.
For more information or a reference iOS implementation, contact us.
Contributions are welcome!
When you're done with your changes, we use changesets to manage release notes. Run npm run changeset
to autogenerate notes to be appended to your pull request.
Distributed under the Apache 2.0 License. See LICENSE.md
for more information.
Created and curated by TrustNXT GmbH, a proud member of CAI and C2PA.
This project is not affiliated with or endorsed by CAI, C2PA, CAWG, or any other organization except TrustNXT.
The following resources were helpful during creation of this library:
- c2pa-rs
- public-testfiles
- CAI Discord server
- @peculiar/x509
- PKI.js
- ASN1.js
- MIPAMS JPEG Systems
- cbor-x
- mocha
- typed-binary
Thank you for providing them and keeping open source alive!