1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Copyright 2022 Adobe. All rights reserved.
// This file is licensed to you under the Apache License,
// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
// or the MIT license (http://opensource.org/licenses/MIT),
// at your option.

// Unless required by applicable law or agreed to in writing,
// this software is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
// implied. See the LICENSE-MIT and LICENSE-APACHE files for the
// specific language governing permissions and limitations under
// each license.

#![deny(warnings)]
#![deny(clippy::expect_used)]
#![deny(clippy::panic)]
#![deny(clippy::unwrap_used)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))]

//! This library supports reading, creating and embedding C2PA data
//! with a variety of asset types.
//!
//! We have a new experimental Builder/Reader API that will eventually replace
//! the existing methods of reading and writing C2PA data.
//! The new API focuses on stream support and can do more with fewer methods.
//! It will be supported in all language bindings and build environments.
//! To try these out, you need to enable the `unstable_api` feature.
//!
//! To read with file based methods, you must add the `file_io` dependency to your Cargo.toml.
//! For example:
//!
//! ```text
//! c2pa = {version="0.32.0", features=["file_io"]}
//! ```
//!
//! # Example: Reading a ManifestStore
//!
//! ```
//! # use c2pa::Result;
//! use c2pa::{assertions::Actions, Reader};
//!
//! # fn main() -> Result<()> {
//! let stream = std::fs::File::open("tests/fixtures/C.jpg")?;
//! let reader = Reader::from_stream("image/jpeg", stream)?;
//! println!("{}", reader.json());
//!
//! if let Some(manifest) = reader.active_manifest() {
//!     let actions: Actions = manifest.find_assertion(Actions::LABEL)?;
//!     for action in actions.actions {
//!         println!("{}\n", action.action());
//!     }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Example: Adding a Manifest to a file
//!
//! ```
//! # use c2pa::Result;
//! use std::path::PathBuf;
//!
//! use c2pa::{create_signer, Builder, SigningAlg};
//! use serde::Serialize;
//! use tempfile::tempdir;
//!
//! #[derive(Serialize)]
//! struct Test {
//!     my_tag: usize,
//! }
//!
//! # fn main() -> Result<()> {
//! let mut builder = Builder::from_json(r#"{"title": "Test"}"#)?;
//! builder.add_assertion("org.contentauth.test", &Test { my_tag: 42 })?;
//!
//! // Create a ps256 signer using certs and key files
//! let signer = create_signer::from_files(
//!     "tests/fixtures/certs/ps256.pub",
//!     "tests/fixtures/certs/ps256.pem",
//!     SigningAlg::Ps256,
//!     None,
//! )?;
//!
//! // embed a manifest using the signer
//! std::fs::remove_file("../target/tmp/lib_sign.jpg"); // ensure the file does not exist
//! builder.sign_file(
//!     &*signer,
//!     "tests/fixtures/C.jpg",
//!     "../target/tmp/lib_sign.jpg",
//! )?;
//! # Ok(())
//! # }
//! ```

/// The internal name of the C2PA SDK
pub const NAME: &str = "c2pa-rs";

/// The version of this C2PA SDK
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

// Public modules
pub mod assertions;
pub mod cose_sign;
#[cfg(feature = "openssl_sign")]
pub mod create_signer;
pub mod jumbf_io;
pub mod settings;
pub mod validation_status;
#[cfg(target_arch = "wasm32")]
pub mod wasm;

// Public exports
#[cfg(feature = "v1_api")]
pub use asset_io::{CAIRead, CAIReadWrite};
#[cfg(feature = "unstable_api")]
pub use builder::{Builder, ManifestDefinition};
pub use callback_signer::{CallbackFunc, CallbackSigner};
pub use claim_generator_info::ClaimGeneratorInfo;
pub use error::{Error, Result};
pub use hash_utils::{hash_stream_by_alg, HashRange};
pub use ingredient::Ingredient;
#[cfg(feature = "file_io")]
pub use ingredient::{DefaultOptions, IngredientOptions};
pub use manifest::Manifest;
pub use manifest_assertion::{ManifestAssertion, ManifestAssertionKind};
#[cfg(feature = "v1_api")]
pub use manifest_store::ManifestStore;
#[cfg(feature = "v1_api")]
pub use manifest_store_report::ManifestStoreReport;
#[cfg(feature = "unstable_api")]
pub use reader::Reader;
pub use resource_store::ResourceRef;
pub use signer::{AsyncSigner, RemoteSigner, Signer};
pub use signing_alg::SigningAlg;
pub use utils::mime::format_from_path;

// Internal modules
#[allow(dead_code, clippy::enum_variant_names)]
pub(crate) mod asn1;
pub(crate) mod assertion;
pub(crate) mod asset_handlers;
pub(crate) mod asset_io;
#[cfg(feature = "unstable_api")]
pub(crate) mod builder;
pub(crate) mod callback_signer;
pub(crate) mod claim;
pub(crate) mod claim_generator_info;
pub(crate) mod cose_validator;
pub(crate) mod error;
pub(crate) mod hashed_uri;
pub(crate) mod ingredient;
#[allow(dead_code)]
pub(crate) mod jumbf;
pub(crate) mod manifest;
pub(crate) mod manifest_assertion;
pub(crate) mod manifest_store;
pub(crate) mod manifest_store_report;
pub(crate) mod ocsp_utils;
#[cfg(feature = "openssl")]
pub(crate) mod openssl;
#[allow(dead_code)]
// TODO: Remove this when the feature is released (used in tests only for some builds now)
pub(crate) mod reader;
pub(crate) mod resource_store;
pub(crate) mod salt;
pub(crate) mod signer;
pub(crate) mod signing_alg;
pub(crate) mod status_tracker;
pub(crate) mod store;
pub(crate) mod time_stamp;
pub(crate) mod trust_handler;
pub(crate) mod utils;
pub(crate) use utils::{cbor_types, hash_utils};
pub(crate) mod validator;