diff --git a/cli/tests/fixtures/trust/cawg_sign_settings.toml b/cli/tests/fixtures/trust/cawg_sign_settings.toml
index c76cf6a32..b567cb5ba 100644
--- a/cli/tests/fixtures/trust/cawg_sign_settings.toml
+++ b/cli/tests/fixtures/trust/cawg_sign_settings.toml
@@ -1,8 +1,7 @@
# c2pa-rs Configuration File
# Version information.
-version_major = 1
-version_minor = 0
+version = 1
# Trust settings for certificate validation.
# [trust]
@@ -220,13 +219,13 @@ xPd7wFhjRZHfuWb2cs63xjAGjQ==
"""
# String to trust configuration.
trust_config = """
-//id-kp-emailProtection
+//id-kp-emailProtection
1.3.6.1.5.5.7.3.4
-//id-kp-documentSigning
+//id-kp-documentSigning
1.3.6.1.5.5.7.3.36
-//id-kp-timeStamping
+//id-kp-timeStamping
1.3.6.1.5.5.7.3.8
-//id-kp-OCSPSigning
+//id-kp-OCSPSigning
1.3.6.1.5.5.7.3.9
// MS C2PA Signing
1.3.6.1.4.1.311.76.59.1.9
@@ -418,8 +417,8 @@ name = "c2pa-rs testing"
version = "1.0.0"
# The operating system the claim generator is running on.
#operating_system.name = "macOS"
-# Or if the name isn't specified, it can be inferred automatically.
-operating_system.infer = true
+# Or specify "auto" to infer the operating system automatically.
+operating_system = "auto"
# Arbitrary fields can also be defined.
#
# By default, the SDK adds a field "org.cai.c2pa_rs" with the value
diff --git a/cli/tests/fixtures/trust/cawg_test_settings.toml b/cli/tests/fixtures/trust/cawg_test_settings.toml
index 7eeccc45b..3d7000704 100644
--- a/cli/tests/fixtures/trust/cawg_test_settings.toml
+++ b/cli/tests/fixtures/trust/cawg_test_settings.toml
@@ -3,16 +3,18 @@ trusted = true
[trust]
trust_config = """
-//id-kp-emailProtection
+//id-kp-emailProtection
1.3.6.1.5.5.7.3.4
-//id-kp-documentSigning
+//id-kp-documentSigning
1.3.6.1.5.5.7.3.36
-//id-kp-timeStamping
+//id-kp-timeStamping
1.3.6.1.5.5.7.3.8
-//id-kp-OCSPSigning
+//id-kp-OCSPSigning
1.3.6.1.5.5.7.3.9
// MS C2PA Signing
1.3.6.1.4.1.311.76.59.1.9
+// c2pa-kp-claimSigning
+1.3.6.1.4.1.62558.2.1
"""
trust_anchors = """
-----BEGIN CERTIFICATE-----
@@ -227,9 +229,9 @@ xPd7wFhjRZHfuWb2cs63xjAGjQ==
[cawg_trust]
trust_config = """
-//id-kp-emailProtection
+//id-kp-emailProtection
1.3.6.1.5.5.7.3.4
-//id-kp-documentSigning
+//id-kp-documentSigning
1.3.6.1.5.5.7.3.36
"""
trust_anchors = """
diff --git a/sdk/examples/c2pa.toml b/sdk/examples/c2pa.toml
index 34a98b68d..8636388fa 100644
--- a/sdk/examples/c2pa.toml
+++ b/sdk/examples/c2pa.toml
@@ -1,8 +1,7 @@
# c2pa-rs Configuration File
# Version information.
-version_major = 1
-version_minor = 0
+version = 1
# # Trust settings for certificate validation.
# [trust]
@@ -66,9 +65,8 @@ name = "My Service"
# A human readable string of the product's version.
version = "1.0.0"
# The operating system the claim generator is running on.
-operating_system.name = "macOS"
-# Or if the name isn't specified, it can be inferred automatically.
-operating_system.infer = true
+# Or specify "auto" to infer the operating system automatically.
+operating_system = "macOS"
# Arbitrary fields can also be defined.
#
# By default, the SDK adds a field "org.cai.c2pa_rs" with the value
diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs
index 0c582d284..60c7d2da9 100644
--- a/sdk/src/settings/builder.rs
+++ b/sdk/src/settings/builder.rs
@@ -31,9 +31,10 @@ use crate::{
///
/// These formats are a combination of types supported in [image-rs](https://docs.rs/image/latest/image/enum.ImageFormat.html)
/// and types defined by the [IANA registry media type](https://www.iana.org/assignments/media-types/media-types.xhtml) (as defined in the spec).
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "lowercase")]
-pub(crate) enum ThumbnailFormat {
+pub enum ThumbnailFormat {
/// An image in PNG format.
Png,
/// An image in JPEG format.
@@ -46,9 +47,10 @@ pub(crate) enum ThumbnailFormat {
Tiff,
}
/// Quality of the thumbnail.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "lowercase")]
-pub(crate) enum ThumbnailQuality {
+pub enum ThumbnailQuality {
/// Low quality.
Low,
/// Medium quality.
@@ -58,23 +60,36 @@ pub(crate) enum ThumbnailQuality {
}
/// Settings for controlling automatic thumbnail generation.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub(crate) struct ThumbnailSettings {
+pub struct ThumbnailSettings {
/// Whether or not to automatically generate thumbnails.
+ ///
+ /// The default value is true.
+ ///
+ ///
+ /// This setting is only applicable if the crate is compiled with the `add_thumbnails` feature.
+ ///
pub enabled: bool,
/// Whether to ignore thumbnail generation errors.
///
/// This may occur, for instance, if the thumbnail media type or color layout isn't
/// supported.
+ ///
+ /// The default value is true.
pub ignore_errors: bool,
/// The size of the longest edge of the thumbnail.
///
/// This function will resize the input to preserve aspect ratio.
+ ///
+ /// The default value is 1024.
pub long_edge: u32,
/// Format of the thumbnail.
///
/// If this field isn't specified, the thumbnail format will correspond to the
/// input format.
+ ///
+ /// The default value is None.
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option,
/// Whether or not to prefer a smaller sized media format for the thumbnail.
@@ -85,11 +100,15 @@ pub(crate) struct ThumbnailSettings {
///
/// For instance, if the source input type is a PNG, but it doesn't have an alpha channel,
/// the image will be converted to a JPEG of smaller size.
+ ///
+ /// The default value is true.
pub prefer_smallest_format: bool,
/// The output quality of the thumbnail.
///
/// This setting contains sensible defaults for things like quality, compression, and
/// algorithms for various formats.
+ ///
+ /// The default value is [`ThumbnailQuality::Medium`].
pub quality: ThumbnailQuality,
}
@@ -118,9 +137,9 @@ impl SettingsValidate for ThumbnailSettings {
}
/// Settings for the auto actions (e.g. created, opened, placed).
-#[allow(unused)]
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub(crate) struct AutoActionSettings {
+pub struct AutoActionSettings {
/// Whether to enable this auto action or not.
pub enabled: bool,
/// The default source type for the auto action.
@@ -128,31 +147,33 @@ pub(crate) struct AutoActionSettings {
pub source_type: Option,
}
-/// Settings for how to specify the claim generator info's operating system.
-#[allow(unused)]
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub(crate) struct ClaimGeneratorInfoOSSettings {
- /// Whether or not to infer the operating system.
- pub infer: bool,
+#[serde(untagged, rename_all = "lowercase")]
+pub enum ClaimGeneratorInfoOperatingSystem {
+ /// Whether or not to automatically infer the operating system.
+ ///
+ /// This option will attempt to following the [LLVM "triples"] conventions. For more information,
+ /// see [`ClaimGeneratorInfoOperatingSystem::Other`].
+ ///
+ /// [LLVM "triples"]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple
+ Auto,
/// The name of the operating system.
///
- /// Note this field overrides [ClaimGeneratorInfoOSSettings::infer].
- pub name: Option,
-}
-
-impl Default for ClaimGeneratorInfoOSSettings {
- fn default() -> Self {
- Self {
- infer: true,
- name: None,
- }
- }
+ /// It is recommended to follow the [LLVM "triples"] conventions to define the operating system,
+ /// with the format `---`. For instance:
+ /// - `x86_64-unknown-linux-gnu`
+ /// - `x86_64-pc-windows-msvc`
+ /// - `arm64-apple-darwin`
+ ///
+ /// [LLVM "triples"]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple
+ Other(String),
}
/// Settings for the claim generator info.
-#[allow(unused)]
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub(crate) struct ClaimGeneratorInfoSettings {
+pub struct ClaimGeneratorInfoSettings {
/// A human readable string naming the claim_generator.
pub name: String,
/// A human readable string of the product's version.
@@ -160,13 +181,13 @@ pub(crate) struct ClaimGeneratorInfoSettings {
pub version: Option,
/// Reference to an icon.
#[serde(skip_serializing_if = "Option::is_none")]
- pub icon: Option,
+ pub(crate) icon: Option,
/// Settings for the claim generator info's operating system field.
#[serde(skip_serializing_if = "Option::is_none")]
- pub operating_system: Option,
+ pub operating_system: Option,
/// Any other values that are not part of the standard.
#[serde(flatten)]
- pub other: HashMap,
+ pub other: HashMap,
}
impl TryFrom for ClaimGeneratorInfo {
@@ -178,11 +199,12 @@ impl TryFrom for ClaimGeneratorInfo {
version: value.version,
icon: value.icon.map(UriOrResource::ResourceRef),
operating_system: {
- let os = value.operating_system.unwrap_or_default();
- match os.infer {
- true => Some(consts::OS.to_owned()),
- false => os.name,
- }
+ value.operating_system.map(|os| match os {
+ ClaimGeneratorInfoOperatingSystem::Auto => {
+ format!("{}-unknown-{}", consts::ARCH, consts::OS)
+ }
+ ClaimGeneratorInfoOperatingSystem::Other(name) => name,
+ })
},
other: value
.other
@@ -198,6 +220,7 @@ impl TryFrom for ClaimGeneratorInfo {
}
/// Settings for an action template.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub(crate) struct ActionTemplateSettings {
/// The label associated with this action. See ([c2pa_action][crate::assertions::actions::c2pa_action]).
@@ -221,7 +244,7 @@ pub(crate) struct ActionTemplateSettings {
pub description: Option,
/// Additional parameters for the template
#[serde(skip_serializing_if = "Option::is_none")]
- pub template_parameters: Option>,
+ pub template_parameters: Option>,
}
impl TryFrom for ActionTemplate {
@@ -256,7 +279,6 @@ impl TryFrom for ActionTemplate {
}
/// Settings for an action.
-#[allow(unused)]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub(crate) struct ActionSettings {
/// The label associated with this action. See ([`c2pa_action`]).
@@ -323,34 +345,33 @@ impl TryFrom for Action {
///
/// The reason this setting exists only for an [Actions][crate::assertions::Actions] assertion
/// is because of its mandations and reusable fields.
-#[allow(unused)]
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-pub(crate) struct ActionsSettings {
+pub struct ActionsSettings {
/// Whether or not to set the [Actions::all_actions_included][crate::assertions::Actions::all_actions_included]
/// field.
#[serde(skip_serializing_if = "Option::is_none")]
pub all_actions_included: Option,
/// Templates to be added to the [Actions::templates][crate::assertions::Actions::templates] field.
#[serde(skip_serializing_if = "Option::is_none")]
- pub templates: Option>,
- // TODO: should we define a new struct for "Action" too, like ActionTemplateSettings?
+ pub(crate) templates: Option>,
/// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field.
- #[serde(skip_serializing_if = "Option::is_none")]
- pub actions: Option>,
- /// Whether to automatically generate a c2pa.created [Action][crate::assertions::Action]
- /// assertion or error that it doesn't already exist.
+ // TODO: ActionSettings indirectly depends on ActionParameters which contains a serde_cbor::Value and
+ // schemars can't generate a schema for cbor values. It also doesn't feel right to change our API for
+ // the sake of json schemas.
+ #[cfg_attr(feature = "json_schema", schemars(skip))]
+ pub(crate) actions: Option>,
+ /// Whether to automatically generate a c2pa.created [Action] assertion or error that it doesn't already exist.
///
/// For more information about the mandatory conditions for a c2pa.created action assertion, see here:
///
pub auto_created_action: AutoActionSettings,
- /// Whether to automatically generate a c2pa.opened [Action][crate::assertions::Action]
- /// assertion or error that it doesn't already exist.
+ /// Whether to automatically generate a c2pa.opened [Action] assertion or error that it doesn't already exist.
///
/// For more information about the mandatory conditions for a c2pa.opened action assertion, see here:
///
pub auto_opened_action: AutoActionSettings,
- /// Whether to automatically generate a c2pa.placed [Action][crate::assertions::Action]
- /// assertion or error that it doesn't already exist.
+ /// Whether to automatically generate a c2pa.placed [Action] assertion or error that it doesn't already exist.
///
/// For more information about the mandatory conditions for a c2pa.placed action assertion, see:
///
@@ -390,9 +411,9 @@ impl SettingsValidate for ActionsSettings {
// TODO: do more validation on URL fields, cert fields, etc.
/// Settings for the [Builder][crate::Builder].
-#[allow(unused)]
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Default)]
-pub(crate) struct BuilderSettings {
+pub struct BuilderSettings {
/// Claim generator info that is automatically added to the builder.
///
/// Note that this information will prepend any claim generator info
@@ -405,18 +426,38 @@ pub(crate) struct BuilderSettings {
///
/// For more information on the reasoning behind this field see [ActionsSettings].
pub actions: ActionsSettings,
-
- // Certificate statuses will be fetched for either all the manifest labels, or just the active manifest.
- pub certificate_status_fetch: Option,
-
- // Whether or not existing OCSP responses should be overridden by new values.
- pub certificate_status_should_override: Option,
+ // TODO: this setting affects fetching and generation of the assertion; needs clarification
+ /// Whether to create [`CertificateStatus`] assertions for manifests to store certificate revocation
+ /// status. The assertion can be fetched for the active manifest or for all manifests (including
+ /// ingredients).
+ ///
+ /// The default is to not fetch them at all.
+ ///
+ /// See more information in the spec here:
+ ///
+ ///
+ /// [`CertificateStatus`]: crate::assertions::CertificateStatus
+ pub(crate) certificate_status_fetch: Option,
+ // TODO: this setting affects fetching and generation of the assertion; needs clarification
+ /// Whether to only use [`CertificateStatus`] assertions to check certificate revocation status. If there
+ /// is a stapled OCSP in the COSE claim of the manifest, it will be ignored. If [`Verify::ocsp_fetch`] is
+ /// enabled, it will also be ignored.
+ ///
+ /// The default value is false.
+ ///
+ /// [`CertificateStatus`]: crate::assertions::CertificateStatus
+ /// [`Verify::ocsp_fetch`]: crate::settings::Verify::ocsp_fetch
+ pub(crate) certificate_status_should_override: Option,
}
+/// The scope of which manifests to fetch for OCSP.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "lowercase")]
-pub(crate) enum OcspFetch {
+pub(crate) enum OcspFetchScope {
+ /// Fetch OCSP for all manifests.
All,
+ /// Fetch OCSP for the active manifest only.
Active,
}
diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs
index 5c605675c..7d664b60c 100644
--- a/sdk/src/settings/mod.rs
+++ b/sdk/src/settings/mod.rs
@@ -11,8 +11,10 @@
// specific language governing permissions and limitations under
// each license.
-pub(crate) mod builder;
-pub(crate) mod signer;
+/// Settings for configuring the [`Builder`][crate::Builder].
+pub mod builder;
+/// Settings for configuring the [`Settings::signer`].
+pub mod signer;
#[cfg(feature = "file_io")]
use std::path::Path;
@@ -27,6 +29,8 @@ use signer::SignerSettings;
use crate::{crypto::base64, settings::builder::BuilderSettings, Error, Result, Signer};
+const VERSION: u32 = 1;
+
thread_local!(
static SETTINGS: RefCell =
RefCell::new(Config::try_from(&Settings::default()).unwrap_or_default());
@@ -40,15 +44,24 @@ pub(crate) trait SettingsValidate {
}
}
-// Settings for trust list feature
+/// Settings to configure the trust list.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-#[allow(unused)]
-pub(crate) struct Trust {
- pub(crate) verify_trust_list: bool,
- pub(crate) user_anchors: Option,
- pub(crate) trust_anchors: Option,
- pub(crate) trust_config: Option,
- pub(crate) allowed_list: Option,
+pub struct Trust {
+ /// The default value is true.
+ pub verify_trust_list: bool,
+ /// List of additional user-provided trust anchor root certificates as a PEM bundle.
+ pub user_anchors: Option,
+ /// List of default trust anchor root certificates as a PEM bundle.
+ ///
+ /// Normally this option contains the official C2PA-recognized trust anchors found here:
+ ///
+ pub trust_anchors: Option,
+ /// List of allowed extended key usage (EKU) object identifiers (OID) that
+ /// certificates must have.
+ pub trust_config: Option,
+ /// List of explicitly allowed certificates as a PEM bundle.
+ pub allowed_list: Option,
}
impl Trust {
@@ -160,42 +173,49 @@ impl SettingsValidate for Trust {
}
}
-// TODO: all of these settings aren't implemented
-// Settings for core C2PA-RS functionality
+/// Settings to configure core features.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-#[allow(unused)]
-pub(crate) struct Core {
- debug: bool,
- hash_alg: String,
- #[serde(skip_serializing_if = "Option::is_none")]
- soft_hash_alg: Option,
- salt_jumbf_boxes: bool,
- prefer_box_hash: bool,
- pub(crate) merkle_tree_chunk_size_in_kb: Option,
- pub(crate) merkle_tree_max_proofs: usize,
- compress_manifests: bool,
- #[serde(skip_serializing_if = "Option::is_none")]
- max_memory_usage: Option,
- pub(crate) backing_store_memory_threshold_in_mb: usize,
- // TODO: pending https://github.com/contentauth/c2pa-rs/pull/1180
- // prefer_update_manifests: bool,
- pub(crate) decode_identity_assertions: bool,
+pub struct Core {
+ /// Size of the [`BmffHash`] merkle tree chunks in kilobytes.
+ ///
+ /// This option is associated with the [`MerkleMap::fixed_block_size`] field.
+ ///
+ /// See more information in the spec here:
+ ///
+ ///
+ /// [`MerkleMap::fixed_block_size`]: crate::assertions::MerkleMap::fixed_block_size
+ /// [`BmffHash`]: crate::assertions::BmffHash
+ pub merkle_tree_chunk_size_in_kb: Option,
+ /// Maximum number of proofs when validating or writing a [`BmffHash`] merkle tree.
+ ///
+ /// This option defaults to 5.
+ ///
+ /// See more information in the spec here:
+ ///
+ ///
+ /// [`BmffHash`]: crate::assertions::BmffHash
+ pub merkle_tree_max_proofs: usize,
+ /// Maximum amount of data in megabytes that will be loaded into memory before
+ /// being stored in temporary files on the disk.
+ ///
+ /// This option defaults to 512MB and can result in noticeable performance improvements.
+ pub backing_store_memory_threshold_in_mb: usize,
+ /// Whether to decode CAWG [`IdentityAssertion`]s during reading in the [`Reader`].
+ ///
+ /// This option defaults to true.
+ ///
+ /// [`IdentityAssertion`]: crate::identity::IdentityAssertion
+ /// [`Reader`]: crate::Reader
+ pub decode_identity_assertions: bool,
}
impl Default for Core {
fn default() -> Self {
Self {
- debug: false,
- hash_alg: "sha256".into(),
- soft_hash_alg: None,
- salt_jumbf_boxes: true,
- prefer_box_hash: false,
merkle_tree_chunk_size_in_kb: None,
merkle_tree_max_proofs: 5,
- compress_manifests: true,
- max_memory_usage: None,
backing_store_memory_threshold_in_mb: 512,
- // prefer_update_manifests: true,
decode_identity_assertions: true,
}
}
@@ -203,26 +223,95 @@ impl Default for Core {
impl SettingsValidate for Core {
fn validate(&self) -> Result<()> {
- match self.hash_alg.as_str() {
- "sha256" | "sha384" | "sha512" => Ok(()),
- _ => Err(Error::UnsupportedType),
- }
+ Ok(())
}
}
-// Settings for verification options
+/// Settings to configure the verification process.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-#[allow(unused)]
-pub(crate) struct Verify {
- pub(crate) verify_after_reading: bool,
- pub(crate) verify_after_sign: bool,
- pub(crate) verify_trust: bool,
- pub(crate) verify_timestamp_trust: bool,
- pub(crate) ocsp_fetch: bool,
- pub(crate) remote_manifest_fetch: bool,
+pub struct Verify {
+ /// Whether to verify the manifest after reading in the [`Reader`].
+ ///
+ /// The default value is true.
+ ///
+ ///
+ /// Disabling validation can improve reading performance, BUT it carries the risk of reading an invalid
+ /// manifest.
+ ///
+ ///
+ /// [`Reader`]: crate::Reader
+ pub verify_after_reading: bool,
+ /// Whether to verify the manifest after signing in the [`Builder`].
+ ///
+ /// The default value is true.
+ ///
+ ///
+ /// Disabling validation can improve signing performance, BUT it carries the risk of signing an invalid
+ /// manifest.
+ ///
+ ///
+ /// [`Builder`]: crate::Builder
+ pub verify_after_sign: bool,
+ /// Whether to verify certificates against the trust lists specified in [`Trust`]. To configure
+ /// timestamp certificate verification, see [`Verify::verify_timestamp_trust`].
+ ///
+ /// The default value is true.
+ ///
+ ///
+ /// Verifying trust is REQUIRED by the C2PA spec. This option should only be used for development or testing.
+ ///
+ pub verify_trust: bool,
+ /// Whether to verify the timestamp certificates against the trust lists specified in [`Trust`].
+ ///
+ /// The default value is true.
+ ///
+ ///
+ /// Verifying timestamp trust is REQUIRED by the C2PA spec. This option should only be used for development or testing.
+ ///
+ pub verify_timestamp_trust: bool,
+ /// Whether to fetch the certificates OCSP status during validation.
+ ///
+ /// Revocation status is checked in the following order:
+ /// 1. The OCSP staple stored in the COSE claim of the manifest
+ /// 2. Otherwise if `ocsp_fetch` is enabled, it fetches a new OCSP status
+ /// 3. Otherwise if `ocsp_fetch` is disabled, it checks [`CertificateStatus`] assertions
+ ///
+ /// The default value is false.
+ ///
+ /// [`CertificateStatus`]: crate::assertions::CertificateStatus
+ pub ocsp_fetch: bool,
+ /// Whether to fetch remote manifests in the following scenarios:
+ /// - Constructing a [`Reader`]
+ /// - Constructing an [`Ingredient`]
+ /// - Adding an [`Ingredient`] to the [`Builder`]
+ ///
+ /// The default value is true.
+ ///
+ ///
+ /// This setting is only applicable if the crate is compiled with the `fetch_remote_manifests` feature.
+ ///
+ ///
+ /// [`Reader`]: crate::Reader
+ /// [`Ingredient`]: crate::Ingredient
+ /// [`Builder`]: crate::Builder
+ pub remote_manifest_fetch: bool,
+ /// Whether to verify ingredient certificates against the trust lists specific in [`Trust`].
+ ///
+ /// The default value is true.
pub(crate) check_ingredient_trust: bool,
+ /// Whether to skip ingredient conflict resolution when multiple ingredients have the same
+ /// manifest identifier. This settings is only applicable for C2PA v2 validation.
+ ///
+ /// The default value is false.
+ ///
+ /// See more information in the spec here:
+ ///
pub(crate) skip_ingredient_conflict_resolution: bool,
- pub(crate) strict_v1_validation: bool,
+ /// Whether to do strictly C2PA v1 validation or otherwise the latest validation.
+ ///
+ /// The default value is false.
+ pub strict_v1_validation: bool,
}
impl Default for Verify {
@@ -243,29 +332,35 @@ impl Default for Verify {
impl SettingsValidate for Verify {}
-const MAJOR_VERSION: usize = 1;
-const MINOR_VERSION: usize = 0;
-
/// Settings for configuring all aspects of c2pa-rs.
///
/// [Settings::default] will be set thread-locally by default. Any settings set via
/// [Settings::from_toml] or [Settings::from_file] will also be thread-local.
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
-#[allow(unused)]
pub struct Settings {
- version_major: usize,
- version_minor: usize,
+ /// Version of the configuration.
+ pub version: u32,
// TODO (https://github.com/contentauth/c2pa-rs/issues/1314):
// Rename to c2pa_trust? Discuss possibly breaking change.
- pub(crate) trust: Trust,
- pub(crate) cawg_trust: Trust,
- pub(crate) core: Core,
- pub(crate) verify: Verify,
- pub(crate) builder: BuilderSettings,
+ /// Settings for configuring the C2PA trust lists.
+ pub trust: Trust,
+ /// Settings for configuring the CAWG trust lists.
+ pub cawg_trust: Trust,
+ /// Settings for configuring core features.
+ pub core: Core,
+ /// Settings for configuring verification.
+ pub verify: Verify,
+ /// Settings for configuring the [`Builder`].
+ ///
+ /// [`Builder`]: crate::Builder
+ pub builder: BuilderSettings,
+ /// Settings for configuring the base C2PA signer, accessible via [`Settings::signer`].
#[serde(skip_serializing_if = "Option::is_none")]
- signer: Option,
+ pub signer: Option,
+ /// Settings for configuring the CAWG x509 signer, accessible via [`Settings::signer`].
#[serde(skip_serializing_if = "Option::is_none")]
- cawg_x509_signer: Option,
+ pub cawg_x509_signer: Option,
}
impl Settings {
@@ -431,8 +526,7 @@ impl Settings {
impl Default for Settings {
fn default() -> Self {
Settings {
- version_major: MAJOR_VERSION,
- version_minor: MINOR_VERSION,
+ version: VERSION,
trust: Default::default(),
cawg_trust: Default::default(),
core: Default::default(),
@@ -446,7 +540,7 @@ impl Default for Settings {
impl SettingsValidate for Settings {
fn validate(&self) -> Result<()> {
- if self.version_major > MAJOR_VERSION {
+ if self.version > VERSION {
return Err(Error::VersionCompatibility(
"settings version too new".into(),
));
@@ -544,10 +638,6 @@ pub mod tests {
#[test]
fn test_get_val_by_direct_path() {
// you can do this for all values but if these sanity checks pass they all should if the path is correct
- assert_eq!(
- get_settings_value::("core.hash_alg").unwrap(),
- Core::default().hash_alg
- );
assert_eq!(
get_settings_value::("builder.thumbnail.enabled").unwrap(),
BuilderSettings::default().thumbnail.enabled
@@ -573,13 +663,11 @@ pub mod tests {
);
// test implicit deserialization
- let hash_alg: String = get_settings_value("core.hash_alg").unwrap();
let remote_manifest_fetch: bool =
get_settings_value("verify.remote_manifest_fetch").unwrap();
let auto_thumbnail: bool = get_settings_value("builder.thumbnail.enabled").unwrap();
let user_anchors: Option = get_settings_value("trust.user_anchors").unwrap();
- assert_eq!(hash_alg, Core::default().hash_alg);
assert_eq!(
remote_manifest_fetch,
Verify::default().remote_manifest_fetch
@@ -606,7 +694,7 @@ pub mod tests {
let ts = include_bytes!("../../tests/fixtures/certs/trust/test_cert_root_bundle.pem");
// test updating values
- Settings::set_value("core.hash_alg", "sha512").unwrap();
+ Settings::set_value("core.merkle_tree_chunk_size_in_kb", 10).unwrap();
Settings::set_value("verify.remote_manifest_fetch", false).unwrap();
Settings::set_value("builder.thumbnail.enabled", false).unwrap();
Settings::set_value(
@@ -616,8 +704,8 @@ pub mod tests {
.unwrap();
assert_eq!(
- get_settings_value::("core.hash_alg").unwrap(),
- "sha512"
+ get_settings_value::("core.merkle_tree_chunk_size_in_kb").unwrap(),
+ 10
);
assert!(!get_settings_value::("verify.remote_manifest_fetch").unwrap());
assert!(!get_settings_value::("builder.thumbnail.enabled").unwrap());
@@ -713,11 +801,6 @@ pub mod tests {
BuilderSettings::default().thumbnail.enabled
);
- assert_eq!(
- get_settings_value::("core.salt_jumbf_boxes").unwrap(),
- Core::default().salt_jumbf_boxes
- );
-
reset_default_settings().unwrap();
}
@@ -725,9 +808,9 @@ pub mod tests {
fn test_bad_setting() {
let modified_core = toml::toml! {
[core]
- debug = true
- hash_alg = "sha1000000"
- max_memory_usage = 123456
+ merkle_tree_chunk_size_in_kb = true
+ merkle_tree_max_proofs = "sha1000000"
+ backing_store_memory_threshold_in_mb = -123456
}
.to_string();
@@ -763,8 +846,7 @@ pub mod tests {
#[test]
fn test_all_setting() {
let all_settings = toml::toml! {
- version_major = 1
- version_minor = 0
+ version = 1
[trust]
diff --git a/sdk/src/settings/signer.rs b/sdk/src/settings/signer.rs
index 9857130e4..4a83059bf 100644
--- a/sdk/src/settings/signer.rs
+++ b/sdk/src/settings/signer.rs
@@ -27,11 +27,11 @@ use crate::{
/// A [`Signer`] can be obtained by calling the [`signer()`] function.
///
/// [`Signer`]: crate::Signer
-/// [`signer()`]: Builder::signer
-#[allow(unused)]
+/// [`signer()`]: crate::settings::Settings::signer
+#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "lowercase")]
-pub(crate) enum SignerSettings {
+pub enum SignerSettings {
/// A signer configured locally.
Local {
// Algorithm to use for signing.
@@ -60,9 +60,9 @@ pub(crate) enum SignerSettings {
impl SignerSettings {
// TODO: add async signer
- /// Returns the constructed signer from the [BuilderSettings::signer] field.
+ /// Returns the constructed signer from the [Settings::signer] field.
///
- /// If the signer settings aren't specified, this function will return [Error::MissingSignerSettings][crate::Error::MissingSignerSettings].
+ /// If the signer settings aren't specified, this function will return [Error::MissingSignerSettings].
pub fn signer() -> Result> {
let c2pa_signer = Self::c2pa_signer()?;
diff --git a/sdk/src/store.rs b/sdk/src/store.rs
index c4d8489ba..5ad0128ec 100644
--- a/sdk/src/store.rs
+++ b/sdk/src/store.rs
@@ -72,7 +72,7 @@ use crate::{
log_item,
manifest_store_report::ManifestStoreReport,
salt::DefaultSalt,
- settings::{builder::OcspFetch, Settings},
+ settings::{builder::OcspFetchScope, Settings},
status_tracker::{ErrorBehavior, StatusTracker},
utils::{
hash_utils::HashRange,
@@ -648,8 +648,8 @@ impl Store {
pub fn get_manifest_labels_for_ocsp(&self, settings: &Settings) -> Vec {
let labels = match settings.builder.certificate_status_fetch {
Some(ocsp_fetch) => match ocsp_fetch {
- OcspFetch::All => self.claims.clone(),
- OcspFetch::Active => {
+ OcspFetchScope::All => self.claims.clone(),
+ OcspFetchScope::Active => {
if let Some(active_label) = self.provenance_label() {
vec![active_label]
} else {
diff --git a/sdk/tests/fixtures/certs/trust/test_settings.toml b/sdk/tests/fixtures/certs/trust/test_settings.toml
index a666c4db7..8b1607092 100644
--- a/sdk/tests/fixtures/certs/trust/test_settings.toml
+++ b/sdk/tests/fixtures/certs/trust/test_settings.toml
@@ -3,16 +3,18 @@ trusted = true
[trust]
trust_config = """
-//id-kp-emailProtection
+//id-kp-emailProtection
1.3.6.1.5.5.7.3.4
-//id-kp-documentSigning
+//id-kp-documentSigning
1.3.6.1.5.5.7.3.36
-//id-kp-timeStamping
+//id-kp-timeStamping
1.3.6.1.5.5.7.3.8
-//id-kp-OCSPSigning
+//id-kp-OCSPSigning
1.3.6.1.5.5.7.3.9
// MS C2PA Signing
1.3.6.1.4.1.311.76.59.1.9
+// c2pa-kp-claimSigning
+1.3.6.1.4.1.62558.2.1
"""
trust_anchors = """
-----BEGIN CERTIFICATE-----
diff --git a/sdk/tests/fixtures/test_settings.toml b/sdk/tests/fixtures/test_settings.toml
index 9d987d66c..373abfad2 100644
--- a/sdk/tests/fixtures/test_settings.toml
+++ b/sdk/tests/fixtures/test_settings.toml
@@ -1,8 +1,7 @@
# c2pa-rs Configuration File
# Version information.
-version_major = 1
-version_minor = 0
+version = 1
# Trust settings for certificate validation.
# [trust]
@@ -222,16 +221,18 @@ xPd7wFhjRZHfuWb2cs63xjAGjQ==
"""
# String to trust configuration.
trust_config = """
-//id-kp-emailProtection
+//id-kp-emailProtection
1.3.6.1.5.5.7.3.4
-//id-kp-documentSigning
+//id-kp-documentSigning
1.3.6.1.5.5.7.3.36
-//id-kp-timeStamping
+//id-kp-timeStamping
1.3.6.1.5.5.7.3.8
-//id-kp-OCSPSigning
+//id-kp-OCSPSigning
1.3.6.1.5.5.7.3.9
// MS C2PA Signing
1.3.6.1.4.1.311.76.59.1.9
+// c2pa-kp-claimSigning
+1.3.6.1.4.1.62558.2.1
"""
# # Path to allowed certificate list (PEM format).
@@ -420,8 +421,8 @@ name = "c2pa-rs testing"
version = "1.0.0"
# The operating system the claim generator is running on.
#operating_system.name = "macOS"
-# Or if the name isn't specified, it can be inferred automatically.
-operating_system.infer = true
+# Or specify "auto" to infer the operating system automatically.
+operating_system = "auto"
# Arbitrary fields can also be defined.
#
# By default, the SDK adds a field "org.cai.c2pa_rs" with the value
diff --git a/sdk/tests/fixtures/test_settings_with_cawg_signing.toml b/sdk/tests/fixtures/test_settings_with_cawg_signing.toml
index c77950e02..02e1c0e2b 100644
--- a/sdk/tests/fixtures/test_settings_with_cawg_signing.toml
+++ b/sdk/tests/fixtures/test_settings_with_cawg_signing.toml
@@ -1,8 +1,7 @@
# c2pa-rs Configuration File
# Version information.
-version_major = 1
-version_minor = 0
+version = 1
# Trust settings for certificate validation.
# [trust]
@@ -220,16 +219,18 @@ xPd7wFhjRZHfuWb2cs63xjAGjQ==
"""
# String to trust configuration.
trust_config = """
-//id-kp-emailProtection
+//id-kp-emailProtection
1.3.6.1.5.5.7.3.4
-//id-kp-documentSigning
+//id-kp-documentSigning
1.3.6.1.5.5.7.3.36
-//id-kp-timeStamping
+//id-kp-timeStamping
1.3.6.1.5.5.7.3.8
-//id-kp-OCSPSigning
+//id-kp-OCSPSigning
1.3.6.1.5.5.7.3.9
// MS C2PA Signing
1.3.6.1.4.1.311.76.59.1.9
+// c2pa-kp-claimSigning
+1.3.6.1.4.1.62558.2.1
"""
# # Path to allowed certificate list (PEM format).
@@ -418,8 +419,8 @@ name = "c2pa-rs testing"
version = "1.0.0"
# The operating system the claim generator is running on.
#operating_system.name = "macOS"
-# Or if the name isn't specified, it can be inferred automatically.
-operating_system.infer = true
+# Or specify "auto" to infer the operating system automatically.
+operating_system = "auto"
# Arbitrary fields can also be defined.
#
# By default, the SDK adds a field "org.cai.c2pa_rs" with the value