From 550319baf7fba648ef2f5ad5cabd881926f14b0f Mon Sep 17 00:00:00 2001 From: ok-nick Date: Wed, 24 Sep 2025 15:43:24 -0400 Subject: [PATCH 01/22] feat: add settings structs to public API --- sdk/src/settings/builder.rs | 37 ++++++------- sdk/src/settings/mod.rs | 107 +++++++++++++----------------------- sdk/src/settings/signer.rs | 3 +- 3 files changed, 54 insertions(+), 93 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 022ac55d7..90451c5a3 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -33,7 +33,7 @@ use crate::{ /// and types defined by the [IANA registry media type](https://www.iana.org/assignments/media-types/media-types.xhtml) (as defined in the spec). #[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. @@ -48,7 +48,7 @@ pub(crate) enum ThumbnailFormat { /// Quality of the thumbnail. #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] -pub(crate) enum ThumbnailQuality { +pub enum ThumbnailQuality { /// Low quality. Low, /// Medium quality. @@ -59,7 +59,7 @@ pub(crate) enum ThumbnailQuality { /// Settings for controlling automatic thumbnail generation. #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -pub(crate) struct ThumbnailSettings { +pub struct ThumbnailSettings { /// Whether or not to automatically generate thumbnails. pub enabled: bool, /// Whether to ignore thumbnail generation errors. @@ -118,9 +118,8 @@ impl SettingsValidate for ThumbnailSettings { } /// Settings for the auto actions (e.g. created, opened, placed). -#[allow(unused)] #[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. @@ -129,9 +128,8 @@ pub(crate) struct AutoActionSettings { } /// Settings for how to specify the claim generator info's operating system. -#[allow(unused)] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -pub(crate) struct ClaimGeneratorInfoOSSettings { +pub struct ClaimGeneratorInfoOSSettings { /// Whether or not to infer the operating system. pub infer: bool, /// The name of the operating system. @@ -150,9 +148,8 @@ impl Default for ClaimGeneratorInfoOSSettings { } /// Settings for the claim generator info. -#[allow(unused)] #[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. @@ -256,7 +253,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,19 +319,20 @@ 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)] #[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. pub all_actions_included: bool, /// Templates to be added to the [Actions::templates][crate::assertions::Actions::templates] field. + #[doc(hidden)] #[serde(skip_serializing_if = "Option::is_none")] - pub templates: Option>, + pub(crate) templates: Option>, // TODO: should we define a new struct for "Action" too, like ActionTemplateSettings? /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. + #[doc(hidden)] #[serde(skip_serializing_if = "Option::is_none")] - pub actions: Option>, + pub(crate) actions: Option>, /// Whether to automatically generate a c2pa.created [Action][crate::assertions::Action] /// assertion or error that it doesn't already exist. /// @@ -389,9 +386,8 @@ impl SettingsValidate for ActionsSettings { // TODO: do more validation on URL fields, cert fields, etc. /// Settings for the [Builder][crate::Builder]. -#[allow(unused)] #[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 @@ -404,17 +400,16 @@ 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. + // REVIEW NOTE: should this be in builder settings or core? + /// 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. + /// Whether or not existing OCSP responses should be overridden by new values. pub certificate_status_should_override: Option, } #[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] -pub(crate) enum OcspFetch { +pub enum OcspFetch { All, Active, } diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index c718cab16..76c9a6eea 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -11,8 +11,8 @@ // specific language governing permissions and limitations under // each license. -pub(crate) mod builder; -pub(crate) mod signer; +pub mod builder; +pub mod signer; #[cfg(feature = "file_io")] use std::path::Path; @@ -42,13 +42,13 @@ pub(crate) trait SettingsValidate { // Settings for trust list feature #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -#[allow(unused)] -pub(crate) struct Trust { - verify_trust_list: bool, - user_anchors: Option, - trust_anchors: Option, - trust_config: Option, - allowed_list: Option, +pub struct Trust { + // REVIEW NOTE: move this down to the `Verify` struct? + pub verify_trust_list: bool, + pub user_anchors: Option, + pub trust_anchors: Option, + pub trust_config: Option, + pub allowed_list: Option, } impl Trust { @@ -160,67 +160,45 @@ impl SettingsValidate for Trust { } } -// TODO: all of these settings aren't implemented // Settings for core C2PA-RS functionality #[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, - merkle_tree_chunk_size_in_kb: Option, - merkle_tree_max_proofs: usize, - compress_manifests: bool, - #[serde(skip_serializing_if = "Option::is_none")] - max_memory_usage: Option, - backing_store_memory_threshold_in_mb: usize, - // TODO: pending https://github.com/contentauth/c2pa-rs/pull/1180 - // prefer_update_manifests: bool, +pub struct Core { + pub merkle_tree_chunk_size_in_kb: Option, + pub merkle_tree_max_proofs: usize, + pub backing_store_memory_threshold_in_mb: usize, } 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, } } } 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 #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -#[allow(unused)] -pub(crate) struct Verify { - verify_after_reading: bool, - verify_after_sign: bool, - verify_trust: bool, - verify_timestamp_trust: bool, - ocsp_fetch: bool, - remote_manifest_fetch: bool, - check_ingredient_trust: bool, - skip_ingredient_conflict_resolution: bool, - strict_v1_validation: bool, +pub struct Verify { + pub verify_after_reading: bool, + pub verify_after_sign: bool, + pub verify_trust: bool, + pub verify_timestamp_trust: bool, + // REVIEW NOTE: what's the difference between this and builder.certificate_status_fetch? + pub ocsp_fetch: bool, + pub remote_manifest_fetch: bool, + #[doc(hidden)] + pub(crate) check_ingredient_trust: bool, + #[doc(hidden)] + pub(crate) skip_ingredient_conflict_resolution: bool, + pub strict_v1_validation: bool, } impl Default for Verify { @@ -249,21 +227,21 @@ const MINOR_VERSION: usize = 0; /// [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. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -#[allow(unused)] pub struct Settings { - version_major: usize, - version_minor: usize, + // REVIEW NOTE: do we need both a major and minor version? + pub version_major: usize, + pub version_minor: usize, // TODO (https://github.com/contentauth/c2pa-rs/issues/1314): // Rename to c2pa_trust? Discuss possibly breaking change. - trust: Trust, - cawg_trust: Trust, - core: Core, - verify: Verify, - builder: BuilderSettings, + pub trust: Trust, + pub cawg_trust: Trust, + pub core: Core, + pub verify: Verify, + pub builder: BuilderSettings, #[serde(skip_serializing_if = "Option::is_none")] - signer: Option, + pub signer: Option, #[serde(skip_serializing_if = "Option::is_none")] - cawg_x509_signer: Option, + pub cawg_x509_signer: Option, } impl Settings { @@ -544,10 +522,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 +547,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 @@ -713,11 +685,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(); } diff --git a/sdk/src/settings/signer.rs b/sdk/src/settings/signer.rs index 9857130e4..d3c5e8d03 100644 --- a/sdk/src/settings/signer.rs +++ b/sdk/src/settings/signer.rs @@ -28,10 +28,9 @@ use crate::{ /// /// [`Signer`]: crate::Signer /// [`signer()`]: Builder::signer -#[allow(unused)] #[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. From 2d710cb296bd2b29defc978e245b92328317fc29 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Wed, 24 Sep 2025 16:30:29 -0400 Subject: [PATCH 02/22] feat: add json schemas for settings structs --- sdk/src/settings/builder.rs | 29 +++++++++++++++++++++-------- sdk/src/settings/mod.rs | 4 ++++ sdk/src/settings/signer.rs | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 90451c5a3..f0199d422 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -31,6 +31,7 @@ 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 enum ThumbnailFormat { @@ -46,6 +47,7 @@ pub enum ThumbnailFormat { Tiff, } /// Quality of the thumbnail. +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] pub enum ThumbnailQuality { @@ -58,6 +60,7 @@ pub enum ThumbnailQuality { } /// Settings for controlling automatic thumbnail generation. +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct ThumbnailSettings { /// Whether or not to automatically generate thumbnails. @@ -118,6 +121,7 @@ impl SettingsValidate for ThumbnailSettings { } /// Settings for the auto actions (e.g. created, opened, placed). +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct AutoActionSettings { /// Whether to enable this auto action or not. @@ -128,6 +132,7 @@ pub struct AutoActionSettings { } /// Settings for how to specify the claim generator info's operating system. +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct ClaimGeneratorInfoOSSettings { /// Whether or not to infer the operating system. @@ -148,6 +153,7 @@ impl Default for ClaimGeneratorInfoOSSettings { } /// Settings for the claim generator info. +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct ClaimGeneratorInfoSettings { /// A human readable string naming the claim_generator. @@ -163,7 +169,7 @@ pub struct ClaimGeneratorInfoSettings { 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 { @@ -195,6 +201,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]). @@ -218,7 +225,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 { @@ -319,6 +326,7 @@ 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. +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct ActionsSettings { /// Whether or not to set the [Actions::all_actions_included][crate::assertions::Actions::all_actions_included] @@ -328,11 +336,15 @@ pub struct ActionsSettings { #[doc(hidden)] #[serde(skip_serializing_if = "Option::is_none")] pub(crate) templates: Option>, - // TODO: should we define a new struct for "Action" too, like ActionTemplateSettings? - /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. - #[doc(hidden)] - #[serde(skip_serializing_if = "Option::is_none")] - pub(crate) actions: Option>, + // + // REVIEW NOTE: 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. + // /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. + // #[doc(hidden)] + // #[serde(skip_serializing_if = "Option::is_none")] + // pub(crate) actions: Option>, + // /// Whether to automatically generate a c2pa.created [Action][crate::assertions::Action] /// assertion or error that it doesn't already exist. /// @@ -358,7 +370,6 @@ impl Default for ActionsSettings { ActionsSettings { all_actions_included: true, templates: None, - actions: None, auto_created_action: AutoActionSettings { enabled: true, source_type: Some(DigitalSourceType::Empty), @@ -386,6 +397,7 @@ impl SettingsValidate for ActionsSettings { // TODO: do more validation on URL fields, cert fields, etc. /// Settings for the [Builder][crate::Builder]. +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Default)] pub struct BuilderSettings { /// Claim generator info that is automatically added to the builder. @@ -407,6 +419,7 @@ pub struct BuilderSettings { pub certificate_status_should_override: Option, } +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] pub enum OcspFetch { diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 76c9a6eea..5b3b41125 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -41,6 +41,7 @@ pub(crate) trait SettingsValidate { } // Settings for trust list feature +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Trust { // REVIEW NOTE: move this down to the `Verify` struct? @@ -161,6 +162,7 @@ impl SettingsValidate for Trust { } // Settings for core C2PA-RS functionality +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Core { pub merkle_tree_chunk_size_in_kb: Option, @@ -185,6 +187,7 @@ impl SettingsValidate for Core { } // Settings for verification options +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Verify { pub verify_after_reading: bool, @@ -226,6 +229,7 @@ const MINOR_VERSION: usize = 0; /// /// [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)] pub struct Settings { // REVIEW NOTE: do we need both a major and minor version? diff --git a/sdk/src/settings/signer.rs b/sdk/src/settings/signer.rs index d3c5e8d03..2fc057cd2 100644 --- a/sdk/src/settings/signer.rs +++ b/sdk/src/settings/signer.rs @@ -28,6 +28,7 @@ use crate::{ /// /// [`Signer`]: crate::Signer /// [`signer()`]: Builder::signer +#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] pub enum SignerSettings { From 10aed0e3435650b1b25af61a49e5a4da08199d2d Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 25 Sep 2025 11:25:06 -0400 Subject: [PATCH 03/22] docs: document all settings structs and fields --- sdk/src/settings/mod.rs | 76 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 5b3b41125..9a0373c60 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -40,15 +40,21 @@ 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)] pub struct Trust { - // REVIEW NOTE: move this down to the `Verify` struct? - 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, } @@ -108,7 +114,6 @@ impl Default for Trust { #[cfg(test)] { let mut trust = Self { - verify_trust_list: true, user_anchors: None, trust_anchors: None, trust_config: None, @@ -133,7 +138,6 @@ impl Default for Trust { #[cfg(not(test))] { Self { - verify_trust_list: true, user_anchors: None, trust_anchors: None, trust_config: None, @@ -161,12 +165,33 @@ impl SettingsValidate for Trust { } } -// 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)] 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 + /// it's 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, } @@ -186,21 +211,56 @@ impl SettingsValidate for Core { } } -// Settings for verification options +/// Settings to configure the verification process. #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Verify { + /// Whether to verify the manifest after reading in the [`Reader`]. + /// + /// The default value is true. + /// + /// [`Reader`]: crate::Reader pub verify_after_reading: bool, + /// Whether to verify the manifest after signing in the [`Builder`]. + /// + /// The default value is true. + /// + /// [`Builer`]: crate::Builer pub verify_after_sign: bool, + /// Whether to verify certificates against the trust lists specified in [`Trust`]. + /// + /// The default value is true. pub verify_trust: bool, + /// Whether to verify the timestamp certificates against the trust lists specified in [`Trust`]. + /// + /// The default value is true. pub verify_timestamp_trust: bool, - // REVIEW NOTE: what's the difference between this and builder.certificate_status_fetch? + // REVIEW NOTE: what's the difference between this and builder.certificate_status_fetch? does it have to do with checking staples? + /// Whether to fetch the certificates OCSP status during validation. + /// + /// The default value is false. pub ocsp_fetch: bool, + /// Whether to fetch remote manifests during reading in the [`Reader`]. + /// + /// The default value is true. pub remote_manifest_fetch: bool, + /// Whether to verify ingredient certificates against the trust lists specific in [`Trust`]. + /// + /// The default value is true. #[doc(hidden)] 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: + /// #[doc(hidden)] pub(crate) skip_ingredient_conflict_resolution: bool, + /// Whether to do strictly C2PA v1 validation or otherwise the latest validation. + /// + /// The default value is false. pub strict_v1_validation: bool, } From 992ec270eee5501478fe7969363725adfe880908 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 25 Sep 2025 11:26:16 -0400 Subject: [PATCH 04/22] docs: document settings modules --- sdk/src/settings/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 9a0373c60..b86fb5032 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -11,7 +11,9 @@ // specific language governing permissions and limitations under // each license. +/// Settings for configuring the [`Builder`]. pub mod builder; +/// Settings for configuring the [`Settings::signer`]. pub mod signer; #[cfg(feature = "file_io")] From 17927f59a2223bb69ab27cafa0472ba2809341df Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 25 Sep 2025 11:42:27 -0400 Subject: [PATCH 05/22] docs: finishing documenting settings structs and fix doc lints --- sdk/src/settings/builder.rs | 16 ++++++++-------- sdk/src/settings/mod.rs | 6 ++++-- sdk/src/settings/signer.rs | 6 +++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index f0199d422..e1c214231 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -345,20 +345,17 @@ pub struct ActionsSettings { // #[serde(skip_serializing_if = "Option::is_none")] // pub(crate) actions: Option>, // - /// Whether to automatically generate a c2pa.created [Action][crate::assertions::Action] - /// assertion or error that it doesn't already exist. + /// 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: /// @@ -414,16 +411,19 @@ pub struct BuilderSettings { pub actions: ActionsSettings, // REVIEW NOTE: should this be in builder settings or core? /// Certificate statuses will be fetched for either all the manifest labels, or just the active manifest. - pub certificate_status_fetch: Option, + pub certificate_status_fetch: Option, /// Whether or not existing OCSP responses should be overridden by new values. pub 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 enum OcspFetch { +pub 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 b86fb5032..baf2fb391 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -11,7 +11,7 @@ // specific language governing permissions and limitations under // each license. -/// Settings for configuring the [`Builder`]. +/// Settings for configuring the [`Builder`][crate::Builder]. pub mod builder; /// Settings for configuring the [`Settings::signer`]. pub mod signer; @@ -227,7 +227,7 @@ pub struct Verify { /// /// The default value is true. /// - /// [`Builer`]: crate::Builer + /// [`Builder`]: crate::Builder pub verify_after_sign: bool, /// Whether to verify certificates against the trust lists specified in [`Trust`]. /// @@ -245,6 +245,8 @@ pub struct Verify { /// Whether to fetch remote manifests during reading in the [`Reader`]. /// /// The default value is true. + /// + /// [`Reader`]: crate::Reader pub remote_manifest_fetch: bool, /// Whether to verify ingredient certificates against the trust lists specific in [`Trust`]. /// diff --git a/sdk/src/settings/signer.rs b/sdk/src/settings/signer.rs index 2fc057cd2..4a83059bf 100644 --- a/sdk/src/settings/signer.rs +++ b/sdk/src/settings/signer.rs @@ -27,7 +27,7 @@ use crate::{ /// A [`Signer`] can be obtained by calling the [`signer()`] function. /// /// [`Signer`]: crate::Signer -/// [`signer()`]: Builder::signer +/// [`signer()`]: crate::settings::Settings::signer #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] @@ -60,9 +60,9 @@ pub 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()?; From be43767c826e84626ed7e5f3b6b98fd940cdb6a1 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 25 Sep 2025 13:10:58 -0400 Subject: [PATCH 06/22] docs: document main settings struct fields --- sdk/src/settings/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index baf2fb391..f9c5bbcfb 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -297,17 +297,28 @@ const MINOR_VERSION: usize = 0; #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Settings { // REVIEW NOTE: do we need both a major and minor version? + /// Major version of the configuration. pub version_major: usize, + /// Minor version of the configuration. pub version_minor: usize, // TODO (https://github.com/contentauth/c2pa-rs/issues/1314): // Rename to c2pa_trust? Discuss possibly breaking change. + /// 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")] pub signer: Option, + /// Settings for configuring the CAWG x509 signer, accessible via [`Settings::signer`]. #[serde(skip_serializing_if = "Option::is_none")] pub cawg_x509_signer: Option, } From f752fb52a1f040affd6eaae3ef2cccb5e8b654d4 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 25 Sep 2025 14:23:54 -0400 Subject: [PATCH 07/22] fix: naming and old field tests --- sdk/src/settings/mod.rs | 12 ++++++------ sdk/src/store.rs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index f9c5bbcfb..6000ac3d5 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -657,7 +657,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( @@ -667,8 +667,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()); @@ -771,9 +771,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(); diff --git a/sdk/src/store.rs b/sdk/src/store.rs index 541cd5ed7..4a1cc7825 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, get_settings_value}, + settings::{builder::OcspFetchScope, get_settings_value}, status_tracker::{ErrorBehavior, StatusTracker}, utils::{ hash_utils::HashRange, @@ -603,12 +603,12 @@ impl Store { /// Retrieves all manifest labels that need to fetch ocsp responses. pub fn get_manifest_labels_for_ocsp(&self) -> Vec { - let labels = match crate::settings::get_settings_value::( + let labels = match crate::settings::get_settings_value::( "builder.certificate_status_fetch", ) { Ok(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 { From 40591e7bcb65f2c35cf530d790dd1dfd33858e6f Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 25 Sep 2025 16:28:02 -0400 Subject: [PATCH 08/22] fix: add back trust.verify_trust_list --- sdk/src/settings/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 6000ac3d5..03c4fecab 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -46,6 +46,11 @@ pub(crate) trait SettingsValidate { #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Trust { + // REVIEW NOTE: should we remove this field in favor of `verify.verify_trust`, only CAWG is using it. + /// Whether to verify certificates against the trust lists specified in [`Trust`], only applicable to CAWG. + /// + /// 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. @@ -116,6 +121,7 @@ impl Default for Trust { #[cfg(test)] { let mut trust = Self { + verify_trust_list: true, user_anchors: None, trust_anchors: None, trust_config: None, @@ -140,6 +146,7 @@ impl Default for Trust { #[cfg(not(test))] { Self { + verify_trust_list: true, user_anchors: None, trust_anchors: None, trust_config: None, From a89476f316f77e293e9e26ab1f9c944e33b9805b Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 29 Sep 2025 14:29:36 -0400 Subject: [PATCH 09/22] fix: doc verify setting warnings, private icon resource, single integer for version --- sdk/src/settings/builder.rs | 2 +- sdk/src/settings/mod.rs | 30 ++++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index e1c214231..8fb90f897 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -163,7 +163,7 @@ pub 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, diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 03c4fecab..ceeb1e96b 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -29,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()); @@ -228,21 +230,39 @@ pub struct Verify { /// /// 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`]. /// /// 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, // REVIEW NOTE: what's the difference between this and builder.certificate_status_fetch? does it have to do with checking staples? /// Whether to fetch the certificates OCSP status during validation. @@ -293,9 +313,6 @@ 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 @@ -303,11 +320,8 @@ const MINOR_VERSION: usize = 0; #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Settings { - // REVIEW NOTE: do we need both a major and minor version? - /// Major version of the configuration. - pub version_major: usize, - /// Minor version of the configuration. - pub 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. /// Settings for configuring the C2PA trust lists. From b3e6cb4c3485a33245dd50c5bf559dcf89549c70 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 29 Sep 2025 14:45:24 -0400 Subject: [PATCH 10/22] fix: specify claim generator info operating system as enum --- sdk/src/settings/builder.rs | 32 ++++++++++---------------------- sdk/src/settings/mod.rs | 5 ++--- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 8fb90f897..bc8b25ce5 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -131,25 +131,14 @@ pub struct AutoActionSettings { pub source_type: Option, } -/// Settings for how to specify the claim generator info's operating system. #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -pub struct ClaimGeneratorInfoOSSettings { - /// Whether or not to infer the operating system. - pub infer: bool, +#[serde(rename_all = "lowercase")] +pub enum ClaimGeneratorInfoOperatingSystem { + /// Whether or not to automatically infer the operating system. + 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, - } - } + Other(String), } /// Settings for the claim generator info. @@ -166,7 +155,7 @@ pub struct ClaimGeneratorInfoSettings { 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, @@ -181,11 +170,10 @@ 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 => consts::OS.to_owned(), + ClaimGeneratorInfoOperatingSystem::Other(name) => name, + }) }, other: value .other diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index ceeb1e96b..cbd9aa231 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -507,8 +507,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(), @@ -522,7 +521,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(), )); From aee4a005f7ebabead90b13bb5f9afe92a177f40f Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 29 Sep 2025 14:52:54 -0400 Subject: [PATCH 11/22] fix: example settings files --- cli/tests/fixtures/trust/cawg_sign_settings.toml | 15 +++++++-------- sdk/examples/c2pa.toml | 8 +++----- sdk/src/settings/builder.rs | 2 +- sdk/src/settings/mod.rs | 3 +-- sdk/tests/fixtures/test_settings.toml | 15 +++++++-------- .../fixtures/test_settings_with_cawg_signing.toml | 15 +++++++-------- 6 files changed, 26 insertions(+), 32 deletions(-) diff --git a/cli/tests/fixtures/trust/cawg_sign_settings.toml b/cli/tests/fixtures/trust/cawg_sign_settings.toml index 708728f4c..88be46901 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/sdk/examples/c2pa.toml b/sdk/examples/c2pa.toml index 7bea707b6..249a8cf97 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 bc8b25ce5..32e5fedf6 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -133,7 +133,7 @@ pub struct AutoActionSettings { #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -#[serde(rename_all = "lowercase")] +#[serde(untagged, rename_all = "lowercase")] pub enum ClaimGeneratorInfoOperatingSystem { /// Whether or not to automatically infer the operating system. Auto, diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index cbd9aa231..885482da5 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -829,8 +829,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/tests/fixtures/test_settings.toml b/sdk/tests/fixtures/test_settings.toml index 3c67383a8..581aac8e8 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] @@ -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/sdk/tests/fixtures/test_settings_with_cawg_signing.toml b/sdk/tests/fixtures/test_settings_with_cawg_signing.toml index 708728f4c..88be46901 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,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 From 2ae744fb71c655d4cf2a383d4b340e1de2efbce7 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 29 Sep 2025 15:06:14 -0400 Subject: [PATCH 12/22] docs: clarify `verify_trust` doesn't include `verify_timestamp_trust` --- sdk/src/settings/builder.rs | 3 --- sdk/src/settings/mod.rs | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 32e5fedf6..4bff13307 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -325,9 +325,6 @@ pub struct ActionsSettings { #[serde(skip_serializing_if = "Option::is_none")] pub(crate) templates: Option>, // - // REVIEW NOTE: 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. // /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. // #[doc(hidden)] // #[serde(skip_serializing_if = "Option::is_none")] diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 885482da5..cddc58d0d 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -248,7 +248,8 @@ pub struct Verify { /// /// [`Builder`]: crate::Builder pub verify_after_sign: bool, - /// Whether to verify certificates against the trust lists specified in [`Trust`]. + /// 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. /// From 3cfa1077ae31a2dd03b4dd39f8282787f2377ba5 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 29 Sep 2025 15:47:24 -0400 Subject: [PATCH 13/22] docs: improve certificate status fetch/override docs --- sdk/src/settings/builder.rs | 16 +++++++++++++--- sdk/src/settings/mod.rs | 6 ++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 4bff13307..d58f9a8c2 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -394,10 +394,20 @@ pub struct BuilderSettings { /// /// For more information on the reasoning behind this field see [ActionsSettings]. pub actions: ActionsSettings, - // REVIEW NOTE: should this be in builder settings or core? - /// Certificate statuses will be fetched for either all the manifest labels, or just the active manifest. + /// Whether to create [`CertificateStatus`] assertions for manifests, also known as OCSP stapling. 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 certificate_status_fetch: Option, - /// Whether or not existing OCSP responses should be overridden by new values. + /// Whether existing [`CertificateStatus`] assertions should be refreshed, also known as OCSP stapling. Use + /// [`BuilderSettings::certificate_status_fetch`] to configure which certificates are affected. + /// + /// The default value is false. pub certificate_status_should_override: Option, } diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index cddc58d0d..eeacfb4bb 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -265,10 +265,12 @@ pub struct Verify { /// Verifying timestamp trust is REQUIRED by the C2PA spec. This option should only be used for development or testing. /// pub verify_timestamp_trust: bool, - // REVIEW NOTE: what's the difference between this and builder.certificate_status_fetch? does it have to do with checking staples? - /// Whether to fetch the certificates OCSP status during validation. + /// Whether to fetch the certificates OCSP status during validation. This setting will fetch OCSP for all certificates + /// even if they are stapled with a [`CertificateStatus`] assertion. /// /// The default value is false. + /// + /// [`CertificateStatus`]: crate::assertions::CertificateStatus pub ocsp_fetch: bool, /// Whether to fetch remote manifests during reading in the [`Reader`]. /// From 3b2cb72aa544172d2350259ea1a88837d273644b Mon Sep 17 00:00:00 2001 From: ok-nick Date: Tue, 7 Oct 2025 16:39:16 -0400 Subject: [PATCH 14/22] docs: clarify ocsp_fetch and certificate status settings --- sdk/src/settings/builder.rs | 33 +++++++++++++++++++++------------ sdk/src/settings/mod.rs | 8 ++++++-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index d58f9a8c2..7440f741e 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -324,12 +324,13 @@ pub struct ActionsSettings { #[doc(hidden)] #[serde(skip_serializing_if = "Option::is_none")] pub(crate) templates: Option>, - // - // /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. - // #[doc(hidden)] - // #[serde(skip_serializing_if = "Option::is_none")] - // pub(crate) actions: Option>, - // + /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. + #[doc(hidden)] + // 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. + #[serde(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: @@ -352,6 +353,7 @@ impl Default for ActionsSettings { ActionsSettings { all_actions_included: true, templates: None, + actions: None, auto_created_action: AutoActionSettings { enabled: true, source_type: Some(DigitalSourceType::Empty), @@ -394,8 +396,10 @@ pub struct BuilderSettings { /// /// For more information on the reasoning behind this field see [ActionsSettings]. pub actions: ActionsSettings, - /// Whether to create [`CertificateStatus`] assertions for manifests, also known as OCSP stapling. The - /// assertion can be fetched for the active manifest or for all manifests (including ingredients). + // 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. /// @@ -403,12 +407,17 @@ pub struct BuilderSettings { /// /// /// [`CertificateStatus`]: crate::assertions::CertificateStatus - pub certificate_status_fetch: Option, - /// Whether existing [`CertificateStatus`] assertions should be refreshed, also known as OCSP stapling. Use - /// [`BuilderSettings::certificate_status_fetch`] to configure which certificates are affected. + 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. - pub certificate_status_should_override: Option, + /// + /// [`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. diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index eeacfb4bb..7d7ed3ced 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -265,8 +265,12 @@ pub struct Verify { /// 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. This setting will fetch OCSP for all certificates - /// even if they are stapled with a [`CertificateStatus`] assertion. + /// 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. /// From 9fb4585236a89b865f01f4f3bb607bee5a58fe4d Mon Sep 17 00:00:00 2001 From: ok-nick Date: Wed, 8 Oct 2025 11:23:22 -0400 Subject: [PATCH 15/22] fix: private `OcspFetchScope` --- sdk/src/settings/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 7440f741e..a1f1740e7 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -424,7 +424,7 @@ pub struct BuilderSettings { #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] -pub enum OcspFetchScope { +pub(crate) enum OcspFetchScope { /// Fetch OCSP for all manifests. All, /// Fetch OCSP for the active manifest only. From 4efca84cc5328809924a849f642fe585ee00d4c9 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Wed, 8 Oct 2025 11:23:33 -0400 Subject: [PATCH 16/22] docs: clarify `remote_manifest_fetch` docs --- sdk/src/settings/mod.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 7d7ed3ced..a53fad00b 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -276,11 +276,20 @@ pub struct Verify { /// /// [`CertificateStatus`]: crate::assertions::CertificateStatus pub ocsp_fetch: bool, - /// Whether to fetch remote manifests during reading in the [`Reader`]. + /// 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 field 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`]. /// From 62f34dd4b75a920c9e8c0544707b9cd966e05ae6 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Wed, 8 Oct 2025 11:28:51 -0400 Subject: [PATCH 17/22] docs: clarify thumbnail settings --- sdk/src/settings/builder.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index a1f1740e7..ecf0cb5ee 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -64,20 +64,32 @@ pub enum ThumbnailQuality { #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] 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. @@ -88,11 +100,15 @@ pub 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, } From 7d934440299107fa3573e1f94e8195eb517c681f Mon Sep 17 00:00:00 2001 From: ok-nick Date: Wed, 8 Oct 2025 11:36:32 -0400 Subject: [PATCH 18/22] fix: use LLVM triples as claim generator OS convention --- sdk/src/settings/builder.rs | 17 ++++++++++++++++- sdk/src/settings/mod.rs | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index ecf0cb5ee..73f2000d5 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -152,8 +152,21 @@ pub struct AutoActionSettings { #[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. + /// + /// 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), } @@ -187,7 +200,9 @@ impl TryFrom for ClaimGeneratorInfo { icon: value.icon.map(UriOrResource::ResourceRef), operating_system: { value.operating_system.map(|os| match os { - ClaimGeneratorInfoOperatingSystem::Auto => consts::OS.to_owned(), + ClaimGeneratorInfoOperatingSystem::Auto => { + format!("{}-unknown-{}", consts::ARCH, consts::OS) + } ClaimGeneratorInfoOperatingSystem::Other(name) => name, }) }, diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index a53fad00b..061aa8000 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -284,7 +284,7 @@ pub struct Verify { /// The default value is true. /// ///
- /// This field is only applicable if the crate is compiled with the `fetch_remote_manifests` feature. + /// This setting is only applicable if the crate is compiled with the `fetch_remote_manifests` feature. ///
/// /// [`Reader`]: crate::Reader From 585c9bc2b3f39d32653e64f903f7b5693acffda1 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 13 Oct 2025 09:47:05 -0400 Subject: [PATCH 19/22] docs: remove hidden attribute for pub(crate) fields and clean up --- sdk/src/settings/builder.rs | 2 -- sdk/src/settings/mod.rs | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 9af372616..acade3dae 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -353,11 +353,9 @@ pub struct ActionsSettings { #[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. - #[doc(hidden)] #[serde(skip_serializing_if = "Option::is_none")] pub(crate) templates: Option>, /// Actions to be added to the [Actions::actions][crate::assertions::Actions::actions] field. - #[doc(hidden)] // 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. diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 5191d95a5..027c09b1d 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -48,9 +48,6 @@ pub(crate) trait SettingsValidate { #[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Trust { - // REVIEW NOTE: should we remove this field in favor of `verify.verify_trust`, only CAWG is using it. - /// Whether to verify certificates against the trust lists specified in [`Trust`], only applicable to CAWG. - /// /// The default value is true. pub verify_trust_list: bool, /// List of additional user-provided trust anchor root certificates as a PEM bundle. @@ -200,7 +197,7 @@ pub struct Core { /// [`BmffHash`]: crate::assertions::BmffHash pub merkle_tree_max_proofs: usize, /// Maximum amount of data in megabytes that will be loaded into memory before - /// it's stored in temporary files on the disk. + /// 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, @@ -294,7 +291,6 @@ pub struct Verify { /// Whether to verify ingredient certificates against the trust lists specific in [`Trust`]. /// /// The default value is true. - #[doc(hidden)] 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. @@ -303,7 +299,6 @@ pub struct Verify { /// /// See more information in the spec here: /// - #[doc(hidden)] pub(crate) skip_ingredient_conflict_resolution: bool, /// Whether to do strictly C2PA v1 validation or otherwise the latest validation. /// From f3d9ff407686d9a5cd2c2a099862a11356eef409 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Mon, 13 Oct 2025 12:16:45 -0400 Subject: [PATCH 20/22] fix: add c2pa-kp-claimSigning OID to trusted EKUs --- cli/tests/fixtures/trust/cawg_test_settings.toml | 14 ++++++++------ sdk/tests/fixtures/certs/trust/test_settings.toml | 10 ++++++---- sdk/tests/fixtures/test_settings.toml | 2 ++ .../fixtures/test_settings_with_cawg_signing.toml | 2 ++ 4 files changed, 18 insertions(+), 10 deletions(-) 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/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 a5b57f74f..373abfad2 100644 --- a/sdk/tests/fixtures/test_settings.toml +++ b/sdk/tests/fixtures/test_settings.toml @@ -231,6 +231,8 @@ trust_config = """ 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). diff --git a/sdk/tests/fixtures/test_settings_with_cawg_signing.toml b/sdk/tests/fixtures/test_settings_with_cawg_signing.toml index ac89f9961..02e1c0e2b 100644 --- a/sdk/tests/fixtures/test_settings_with_cawg_signing.toml +++ b/sdk/tests/fixtures/test_settings_with_cawg_signing.toml @@ -229,6 +229,8 @@ trust_config = """ 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). From 2e221f40b924a8052404939219b2147117f458ab Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 16 Oct 2025 10:19:07 -0400 Subject: [PATCH 21/22] fix: don't serde skip builder.actions, only schemars skip --- sdk/src/settings/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index 14245153b..a74c7bce0 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -359,7 +359,7 @@ pub struct ActionsSettings { // 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. - #[serde(skip)] + #[schemars(skip)] pub(crate) actions: Option>, /// Whether to automatically generate a c2pa.created [Action] assertion or error that it doesn't already exist. /// From 9d8017259e632ec4639d338d7b65bea53a57c86d Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 16 Oct 2025 10:51:10 -0400 Subject: [PATCH 22/22] fix: feature flag schemars(skip) --- sdk/src/settings/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/settings/builder.rs b/sdk/src/settings/builder.rs index a74c7bce0..60c7d2da9 100644 --- a/sdk/src/settings/builder.rs +++ b/sdk/src/settings/builder.rs @@ -359,7 +359,7 @@ pub struct ActionsSettings { // 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. - #[schemars(skip)] + #[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. ///