From 437a672ca4b2eacb15630780188b7a6569c90c61 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 20 Nov 2025 09:34:20 -0500 Subject: [PATCH 1/2] fix: Allow untrusted failure code to be a Valid validation state --- sdk/src/validation_results.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/sdk/src/validation_results.rs b/sdk/src/validation_results.rs index f66a341fa..fb06b9ba8 100644 --- a/sdk/src/validation_results.rs +++ b/sdk/src/validation_results.rs @@ -216,17 +216,28 @@ impl ValidationResults { .map(|status| status.code()) .collect(); let failure_codes = active_manifest.failure(); - let ingredient_failure = self.ingredient_deltas.as_ref().is_some_and(|deltas| { - deltas - .iter() - .any(|idv| !idv.validation_deltas().failure().is_empty()) - }); + let ingredient_failure: Vec<&ValidationStatus> = self + .ingredient_deltas + .as_ref() + .map(|deltas| { + deltas + .iter() + .flat_map(|idv| idv.validation_deltas().failure().iter()) + .collect() + }) + .unwrap_or_default(); // https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_valid_manifest let is_valid = success_codes.contains(validation_status::CLAIM_SIGNATURE_VALIDATED) && success_codes.contains(validation_status::CLAIM_SIGNATURE_INSIDE_VALIDITY) - && failure_codes.is_empty() - && !ingredient_failure; + && (failure_codes.is_empty() + || failure_codes.iter().all(|status| { + status.code() == validation_status::SIGNING_CREDENTIAL_UNTRUSTED + })) + && (ingredient_failure.is_empty() + || ingredient_failure.iter().all(|status| { + status.code() == validation_status::SIGNING_CREDENTIAL_UNTRUSTED + })); // https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_trusted_manifest let is_trusted = success_codes.contains(validation_status::SIGNING_CREDENTIAL_TRUSTED) From 3f475f2995dc96b77a9204167a3da0b168b4cae0 Mon Sep 17 00:00:00 2001 From: ok-nick Date: Thu, 20 Nov 2025 10:11:52 -0500 Subject: [PATCH 2/2] fix: disallow ingredient failures for this PR --- sdk/src/validation_results.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/sdk/src/validation_results.rs b/sdk/src/validation_results.rs index fb06b9ba8..497f4d9d2 100644 --- a/sdk/src/validation_results.rs +++ b/sdk/src/validation_results.rs @@ -216,16 +216,11 @@ impl ValidationResults { .map(|status| status.code()) .collect(); let failure_codes = active_manifest.failure(); - let ingredient_failure: Vec<&ValidationStatus> = self - .ingredient_deltas - .as_ref() - .map(|deltas| { - deltas - .iter() - .flat_map(|idv| idv.validation_deltas().failure().iter()) - .collect() - }) - .unwrap_or_default(); + let ingredient_failure = self.ingredient_deltas.as_ref().is_some_and(|deltas| { + deltas + .iter() + .any(|idv| !idv.validation_deltas().failure().is_empty()) + }); // https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_valid_manifest let is_valid = success_codes.contains(validation_status::CLAIM_SIGNATURE_VALIDATED) @@ -234,10 +229,7 @@ impl ValidationResults { || failure_codes.iter().all(|status| { status.code() == validation_status::SIGNING_CREDENTIAL_UNTRUSTED })) - && (ingredient_failure.is_empty() - || ingredient_failure.iter().all(|status| { - status.code() == validation_status::SIGNING_CREDENTIAL_UNTRUSTED - })); + && !ingredient_failure; // https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_trusted_manifest let is_trusted = success_codes.contains(validation_status::SIGNING_CREDENTIAL_TRUSTED)