Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions c2pa_c_ffi/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ pub unsafe extern "C" fn c2pa_free_string_array(ptr: *const *const c_char, count

// Run CAWG post-validation - this is async and requires a runtime.
fn post_validate(result: Result<C2paReader, c2pa::Error>) -> Result<C2paReader, c2pa::Error> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostValidate could be useful for validating and formatting any 3rd party assertions we don't have in the SDK.
Ideally there would be some way to integrate this into the definition of an Assertion such that you would just need to add an assertion handler to the SDK, but that's a problem for tomorrow.

if false {
// CONSIDER BEFORE MERGING ...
todo!("Remove me?");
}

match result {
Ok(mut reader) => {
let runtime = match Runtime::new() {
Expand Down
4 changes: 4 additions & 0 deletions c2pa_c_ffi/src/json_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ use crate::{Error, Result, SignerInfo};
pub fn read_file(path: &str, data_dir: Option<String>) -> Result<String> {
let mut reader = Reader::from_file(path).map_err(Error::from_c2pa_error)?;
let runtime = Runtime::new().map_err(|e| Error::Other(e.to_string()))?;
if false {
// CONSIDER BEFORE MERGING ...
todo!("Remove post_validate_async here?");
}
runtime
.block_on(reader.post_validate_async(&CawgValidator {}))
.map_err(Error::from_c2pa_error)?;
Expand Down
4 changes: 4 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,10 @@ fn verify_fragmented(init_pattern: &Path, frag_pattern: &Path) -> Result<Vec<Rea

// run cawg validation if supported
fn validate_cawg(reader: &mut Reader) -> Result<()> {
if false {
// CONSIDER BEFORE MERGING ...
todo!("Remove me?");
}
#[cfg(not(target_os = "wasi"))]
{
Runtime::new()?
Expand Down
5 changes: 1 addition & 4 deletions sdk/examples/cawg_identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ mod cawg {
crypto::raw_signature,
identity::{
builder::{AsyncIdentityAssertionBuilder, AsyncIdentityAssertionSigner},
validator::CawgValidator,
x509::AsyncX509CredentialHolder,
},
AsyncSigner, Builder, Reader, SigningAlg,
Expand Down Expand Up @@ -125,9 +124,7 @@ mod cawg {

builder.sign_file_async(&signer, source, &dest).await?;

let mut reader = Reader::from_file(dest)?;

reader.post_validate_async(&CawgValidator {}).await?;
let reader = Reader::from_file_async(dest).await?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not keep the sync interface too? I am not sure we can make everything async


println!("{reader}");
Ok(())
Expand Down
18 changes: 10 additions & 8 deletions sdk/src/identity/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ mod tests {
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
use wasm_bindgen_test::wasm_bindgen_test;

use super::*;
use crate::{Reader, ValidationState};

const CONNECTED_IDENTITIES_VALID: &[u8] =
Expand All @@ -78,8 +77,9 @@ mod tests {
crate::settings::set_settings_value("verify.verify_trust", false).unwrap();

let mut stream = Cursor::new(CONNECTED_IDENTITIES_VALID);
let mut reader = Reader::from_stream("image/jpeg", &mut stream).unwrap();
reader.post_validate_async(&CawgValidator {}).await.unwrap();
let reader = Reader::from_stream_async("image/jpeg", &mut stream)
.await
.unwrap();
//println!("validation results: {}", reader);
assert_eq!(
reader
Expand All @@ -100,8 +100,9 @@ mod tests {
crate::settings::set_settings_value("verify.verify_trust", false).unwrap();

let mut stream = Cursor::new(MULTIPLE_IDENTITIES_VALID);
let mut reader = Reader::from_stream("image/jpeg", &mut stream).unwrap();
reader.post_validate_async(&CawgValidator {}).await.unwrap();
let reader = Reader::from_stream_async("image/jpeg", &mut stream)
.await
.unwrap();
println!("validation results: {reader}");
assert_eq!(
reader
Expand All @@ -116,10 +117,11 @@ mod tests {
}

#[c2pa_test_async]
async fn test_post_validate_with_hard_binding_missing() {
async fn test_cawg_validate_with_hard_binding_missing() {
let mut stream = Cursor::new(NO_HARD_BINDING);
let mut reader = Reader::from_stream("image/jpeg", &mut stream).unwrap();
reader.post_validate_async(&CawgValidator {}).await.unwrap();
let reader = Reader::from_stream_async("image/jpeg", &mut stream)
.await
.unwrap();
assert_eq!(
reader
.validation_results()
Expand Down
24 changes: 22 additions & 2 deletions sdk/src/identity/x509/x509_credential_holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ mod tests {
x509::{X509CredentialHolder, X509SignatureVerifier},
IdentityAssertion,
},
status_tracker::StatusTracker,
status_tracker::{LogKind, StatusTracker},
Builder, Reader, SigningAlg,
};

Expand Down Expand Up @@ -134,9 +134,29 @@ mod tests {
// Read back the Manifest that was generated.
dest.rewind().unwrap();

let manifest_store = Reader::from_stream(format, &mut dest).unwrap();
let manifest_store = Reader::from_stream_async(format, &mut dest).await.unwrap();
assert_eq!(manifest_store.validation_status(), None);

let validation_results = manifest_store.validation_results().unwrap();
let active_manifest_results = validation_results.active_manifest().unwrap();
let active_manifest_success_codes = active_manifest_results.success();

dbg!(&active_manifest_success_codes);

let mut ia_success_codes = active_manifest_success_codes.iter().filter(|s| {
s.url()
.map(|url| url.ends_with("cawg.identity"))
.unwrap_or(false)
&& !s.code().starts_with("assertion.")
});

let ia_success = ia_success_codes.next().unwrap();
dbg!(&ia_success);

assert_eq!(ia_success.code(), "signingCredential.trusted");
assert!(ia_success.url().unwrap().ends_with("cawg.identity"));
assert_eq!(ia_success.kind(), &LogKind::Success);

let manifest = manifest_store.active_manifest().unwrap();
let mut st = StatusTracker::default();
let mut ia_iter = IdentityAssertion::from_manifest(manifest, &mut st);
Expand Down
45 changes: 43 additions & 2 deletions sdk/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,22 @@ impl Reader {
Store::from_stream_async(format, &mut stream, verify, &mut validation_log).await
}?;

Self::from_store(store, &validation_log)
#[allow(unused_mut)] // TEMPORARY until I figure out the synchronous path.
let mut result = Self::from_store(store, &validation_log)?;
if _sync {
// TO DO: Figure out how to handle synchronous validation with
// identity assertions? Just report an error (needs async)?
if false {
todo!("Add identity assertion validation here");
}
} else {
use crate::identity::validator::CawgValidator;
result
.post_validate_internal_async(&CawgValidator {})
.await?;
}

Ok(result)
}

#[async_generic()]
Expand All @@ -151,7 +166,11 @@ impl Reader {
Store::from_stream_async(format, &mut stream, verify, &mut validation_log).await
}?;

Self::from_store(store, &validation_log)
let mut result = Self::from_store(store, &validation_log)?;
if false {
todo!("Add identity assertion validation here");
}
Ok(result)
}

#[cfg(feature = "file_io")]
Expand Down Expand Up @@ -735,6 +754,24 @@ impl Reader {
validator: &impl AsyncPostValidator
))]
pub fn post_validate(&mut self, validator: &impl PostValidator) -> Result<()> {
if false {
// CONSIDER BEFORE MERGING ...
todo!("Remove me?");
}

if _sync {
self.post_validate_internal(validator)
} else {
self.post_validate_internal_async(validator).await
}
}

#[async_generic(async_signature(
&mut self,
validator: &impl AsyncPostValidator
))]
fn post_validate_internal(&mut self, validator: &impl PostValidator) -> Result<()> {
// TEMPORARY: Make this available while I sort out new code path.
let mut validation_log = StatusTracker::default();
let mut validation_results = self.validation_results.take().unwrap_or_default();
let mut assertion_values = HashMap::new();
Expand Down Expand Up @@ -997,6 +1034,10 @@ pub mod tests {

#[test]
fn test_reader_post_validate() -> Result<()> {
if false {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed this was still here. Will remove shortly.

// CONSIDER BEFORE MERGING ...
todo!("Remove me?");
}
use crate::{log_item, status_tracker::StatusTracker};

let mut reader =
Expand Down
Loading