[package] name = "c2pa" version.workspace = true description = "Rust SDK for C2PA (Coalition for Content Provenance and Authenticity) implementors" authors = [ "Maurice Fisher ", "Gavin Peacock ", "Eric Scouten ", "Leonard Rosenthol ", "Dave Kozma ", "Dylan Ross ", ] license = "MIT OR Apache-2.0" documentation = "https://docs.rs/c2pa" homepage = "https://contentauthenticity.org" repository = "https://github.com/contentauth/c2pa-rs" readme = "../README.md" keywords = ["xmp", "metadata"] categories = ["api-bindings"] edition = "2021" rust-version = "1.96.0" exclude = ["tests/fixtures"] [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [features] default = ["openssl", "default_http"] add_thumbnails = ["dep:image"] # Experimental Builder action/ingredient filtering API (`Builder::filter_actions`, # `Builder::filter_ingredients`, `Ingredient::effective_id`). Experimental feature: exempt from # the crate's usual semantic-versioning stability guarantees and may change or be removed in any # release. See docs/experimental-features.md. unstable_builder_filter = [] # Native plain-text asset handler (C2PA A.8 Unicode-variation-selector wrapper), implemented # in-tree with no third-party C2PA-text crate; the only dependency is unicode-normalization for # NFC. Experimental feature: exempt from the crate's usual semantic-versioning stability # guarantees and may change or be removed in any release. See docs/experimental-features.md. unstable_plain_text = ["dep:unicode-normalization"] file_io = [] fetch_remote_manifests = ["dep:wasi"] json_schema = ["dep:schemars"] openssl = [ "dep:openssl", "c2pa_raw_crypto/openssl", ] pdf = ["dep:lopdf"] rust_native_crypto = ["c2pa_raw_crypto/rust_native_crypto"] # Native structured-text asset handler (C2PA A.9 ASCII-armour comment block). Experimental # feature: exempt from the crate's usual semantic-versioning stability guarantees and may change # or be removed in any release. See docs/experimental-features.md. unstable_structured_text = [] # TODO: make our async tests always use the async API so we don't need ureq + reqwest # see https://github.com/contentauth/c2pa-rs/issues/1364 default_http = ["http_reqwest", "http_ureq", "http_wasi", "http_wstd"] http_reqwest_blocking = ["dep:reqwest", "reqwest/blocking"] http_ureq = ["dep:ureq"] http_wasi = ["dep:wasi"] http_wstd = ["dep:wstd"] http_reqwest = ["dep:reqwest"] # The diagnostics feature is unsupported and might be removed. # It enables some low-overhead timing features used in our development cycle. diagnostics = [] [[example]] name = "cawg_identity" required-features = ["file_io"] [[example]] name = "client" required-features = ["file_io"] [[example]] name = "show" required-features = ["file_io"] [[example]] name = "v2show" [[example]] name = "api" [[example]] name = "fragmented_bmff" required-features = ["file_io"] [[example]] name = "progress" [[example]] name = "redaction" [lib] crate-type = ["lib"] [dependencies] asn1-rs = "0.7.2" async-generic = "1.1" async-trait = "0.1.89" atree = "0.5.4" base64 = "0.23.1" bcder = "0.7.6" bytes = "1.11.1" brotli = "7.0.0" byteorder = { version = "1.5.0", default-features = false } byteordered = "0.6.0" chrono = { version = "0.4.44", default-features = false, features = ["serde"] } c2pa_cbor = "0.78.0" c2pa_raw_crypto = { version = "0.1.2", default-features = false } const-hex = "1.19" coset = "0.4.2" der = { version = "0.8.1", features = ["alloc", "std", "oid"] } extfmt = "0.2.0" getrandom = { version = "0.3.4", default-features = false, features = ["std"] } glob = "0.3.3" ed25519-dalek = { version = "2.2.0", features = [ "alloc", "digest", "pem", "pkcs8", "rand_core", ] } hex = "0.4.3" http = "1.4.1" id3 = "1.17.2" img-parts = "0.4.0" iref = { version = "3.2.2", features = ["serde"] } jfifdump = "0.6.0" log = "0.4.30" lopdf = { version = "0.45.0", optional = true, default-features = false } lazy_static = "1.5.0" memchr = "2.8.1" nom = "7.1.3" non-empty-string = { version = "0.2.6", features = ["serde"] } nonempty-collections = { version = "1.3.0", features = ["serde"] } pem = "4.0.0" pkcs8 = "0.10.2" png_pong = "0.10.0" quick-xml = "0.41.0" rand = "0.10.2" rand_chacha = { version = "0.9.0", features = ["os_rng"] } range-set = "0.1.0" rasn = "0.28.13" rasn-cms = "0.28.13" rasn-ocsp = "0.28.13" rasn-pkix = "0.28.13" regex = "1.12.3" riff = "2.0.0" schemars = { version = "1.2.1", optional = true } serde = { version = "1.0.228", features = ["derive"] } serde_bytes = "0.11.19" serde_derive = "1.0.228" serde_json = { version = "1.0.150", features = ["preserve_order"] } serde_with = "3.20.0" serde-transcode = "1.1.1" sha1 = "0.11.0" sha2 = "0.11.0" static-iref = "3.0" tempfile = "3.27.0" thiserror = "2.0.18" toml = "1.1.2" url = "2.5.8" unicode-normalization = { version = "0.1", optional = true } uuid = { version = "1.23.2", features = ["serde", "v4"] } web-time = "1.1" x509-parser = "0.18.1" zeroize = { version = "1.8", features = ["zeroize_derive"] } zip = { version = "8.6.0", default-features = false } # lopdf's rayon needs real threads: native always has them, WASM only with atomics. [target.'cfg(any(not(target_arch = "wasm32"), target_feature = "atomics"))'.dependencies] lopdf = { version = "0.45.0", optional = true } [target.'cfg(not(target_os = "wasi"))'.dependencies] reqwest = { version = "0.12.28", default-features = false, features = [ # These are some of the defaults in `reqwest`. "http2", "system-proxy", "rustls-tls" ], optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] openssl = { version = "0.10.80", features = ["vendored"], optional = true } ureq = { version = "3.3.0", default-features = false, features = [ "rustls" ], optional = true } [target.'cfg(target_os = "wasi")'.dependencies] wasi = { version = "0.14.7", optional = true } wstd = { version = "0.5.6", optional = true } # `wstd` is required for testing, but optional as a normal dependency. [target.'cfg(target_os = "wasi")'.dev-dependencies] wstd = "0.5.6" [target.'cfg(any(target_os = "wasi", not(target_arch = "wasm32")))'.dependencies] image = { version = "0.25.10", default-features = false, features = [ # TODO: eventually define feature flags for the asset handlers and match them # up here. "png", "jpeg", "gif", "webp", "tiff", # "bmp", # "ico", # "avif", # TODO: AVIF requires the dav1d crate which causes some complications compiling # "avif-native" ], optional = true } [target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies.chrono] version = "0.4.44" default-features = false features = ["now"] [target.'cfg(all(target_arch = "wasm32", target_os = "emscripten"))'.dependencies.chrono] version = "0.4.44" default-features = false features = ["clock", "serde"] [target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies] getrandom = { version = "0.3.4", features = ["wasm_js"] } # Also enable getrandom 0.2 with js feature for other dependencies (rand, tempfile, config) # This is needed until all dependencies migrate to getrandom 0.3 getrandom_02 = { package = "getrandom", version = "0.2.8", features = ["js"] } # `rand` 0.10 depends on getrandom 0.4, which also needs the wasm_js feature # enabled for wasm32 support. getrandom_04 = { package = "getrandom", version = "0.4", features = [ "wasm_js", ] } uuid = { version = "1.23.2", features = ["serde", "v4", "js"] } [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] chrono = { version = "0.4.44", default-features = false, features = [ "clock", "serde", "wasmbind", ] } console_log = { version = "1.0.0", features = ["color"] } # Enable getrandom with wasm_js feature for WASM support js-sys = "0.3.99" serde-wasm-bindgen = "0.6.5" wasm-bindgen = "0.2.122" wasm-bindgen-futures = "0.4.72" web-sys = { version = "0.3.99", features = [ "console", "Crypto", "SubtleCrypto", "CryptoKey", "Window", "WorkerGlobalScope", ] } [dev-dependencies] anyhow = "1.0.103" env_logger = "0.11.10" flate2 = "1.1.10" glob = "0.3.3" hex-literal = "1.1.0" jumbf = "0.7.0" c2pa_macros = { path = "../macros" } mockall = "0.15.0" jsonschema = { version = "0.49.4", default-features = false } # `ed25519-dalek`'s `SigningKey::generate` requires an `rand_core` 0.6 RNG, # which is older than the `rand`/`rand_core` version used elsewhere in this # crate. The `getrandom` feature is required for `rand_core_06::OsRng`. rand_core_06 = { package = "rand_core", version = "0.6.4", features = [ "getrandom", ] } [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies] wasm-bindgen-test = "0.3.72" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] httpmock = "0.8.3" tokio = { version = "1.52.3", features = ["full"] } criterion = { package = "codspeed-criterion-compat", version = "4.7.0" } dhat = "0.3.3" # WASM/WASI doesn't support default criterion features. # https://github.com/bheisler/criterion.rs/blob/4c19e913b84e6a7e4a8470cb0f766796886ed891/book/src/user_guide/wasi.md [target.'cfg(target_arch = "wasm32")'.dev-dependencies] criterion = { package = "codspeed-criterion-compat", version = "4.7.0", default-features = false } [[bench]] name = "sign" harness = false [[bench]] name = "read" harness = false [[bench]] name = "complex_read" harness = false [[bench]] name = "settings" harness = false [[bench]] name = "settings_memory" harness = false