Skip to content

Commit

Permalink
WIP on error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
scouten-adobe committed Feb 26, 2025
1 parent 6a4a7cc commit 4b4806c
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 deletions.
22 changes: 19 additions & 3 deletions cawg_identity/src/identity_assertion/assertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::{
};

use c2pa::{Manifest, Reader};
use c2pa_status_tracker::StatusTracker;
use c2pa_status_tracker::{log_item, StatusTracker};
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;

Expand Down Expand Up @@ -66,13 +66,29 @@ impl IdentityAssertion {
/// Aside from CBOR parsing, no further validation is performed.
pub fn from_manifest<'a>(
manifest: &'a Manifest,
_status_tracker: &'a mut StatusTracker,
status_tracker: &'a mut StatusTracker,
) -> impl Iterator<Item = Result<Self, c2pa::Error>> + use<'a> {
manifest
.assertions()
.iter()
.filter(|a| a.label().starts_with("cawg.identity"))
.map(|a| a.to_assertion())
.map(|a| (a.label().to_owned(), a.to_assertion()))
.inspect(|(label, r)| {
if let Err(err) = r {
// TO DO: a.label() is probably wrong (not a full JUMBF URI)
log_item!(
label.clone(),
"invalid CBOR",
"IdentityAssertion::from_manifest"
)
.validation_status("cawg.identity.cbor.invalid")
.failure_no_throw(
status_tracker,
c2pa::Error::AssertionSpecificError(err.to_string()),
);
}
})
.map(move |(_label, r)| r)
}

/// Create a summary report from this `IdentityAssertion`.
Expand Down
99 changes: 99 additions & 0 deletions cawg_identity/src/tests/identity_assertion/assertion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2025 Adobe. All rights reserved.
// This file is licensed to you under the Apache License,
// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
// or the MIT license (http://opensource.org/licenses/MIT),
// at your option.

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

use std::io::{Cursor, Seek};

use c2pa::{Builder, Reader, SigningAlg};
use c2pa_crypto::raw_signature;
use c2pa_status_tracker::StatusTracker;
use serde_json::json;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test;

use crate::{
builder::{AsyncIdentityAssertionBuilder, AsyncIdentityAssertionSigner},
tests::fixtures::cert_chain_and_private_key_for_alg,
x509::{X509CredentialHolder, X509SignatureVerifier},
IdentityAssertion,
};

const TEST_IMAGE: &[u8] = include_bytes!("../../../sdk/tests/fixtures/CA.jpg");
const TEST_THUMBNAIL: &[u8] = include_bytes!("../../../sdk/tests/fixtures/thumbnail.jpg");

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn not_cbor() {
let format = "image/jpeg";
let mut source = Cursor::new(TEST_IMAGE);
let mut dest = Cursor::new(Vec::new());

let mut builder = Builder::from_json(&manifest_json()).unwrap();
builder
.add_ingredient_from_stream(parent_json(), format, &mut source)
.unwrap();

builder
.add_resource("thumbnail.jpg", Cursor::new(TEST_THUMBNAIL))
.unwrap();

let mut c2pa_signer = AsyncIdentityAssertionSigner::from_test_credentials(SigningAlg::Ps256);

let (cawg_cert_chain, cawg_private_key) =
cert_chain_and_private_key_for_alg(SigningAlg::Ed25519);

let cawg_raw_signer = raw_signature::async_signer_from_cert_chain_and_private_key(
&cawg_cert_chain,
&cawg_private_key,
SigningAlg::Ed25519,
None,
)
.unwrap();

let x509_holder = X509CredentialHolder::from_async_raw_signer(cawg_raw_signer);
let iab = AsyncIdentityAssertionBuilder::for_credential_holder(x509_holder);
c2pa_signer.add_identity_assertion(iab);

builder
.sign_async(&c2pa_signer, format, &mut source, &mut dest)
.await
.unwrap();

// Read back the Manifest that was generated.
dest.rewind().unwrap();

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

let manifest = manifest_store.active_manifest().unwrap();
let mut st = StatusTracker::default();
let mut ia_iter = IdentityAssertion::from_manifest(manifest, &mut st);

// Should find exactly one identity assertion.
let ia = ia_iter.next().unwrap().unwrap();
assert!(ia_iter.next().is_none());
drop(ia_iter);

// And that identity assertion should be valid for this manifest.
let x509_verifier = X509SignatureVerifier {};
let sig_info = ia
.validate(manifest, &mut st, &x509_verifier)
.await
.unwrap();

let cert_info = &sig_info.cert_info;
assert_eq!(cert_info.alg.unwrap(), SigningAlg::Ed25519);
assert_eq!(
cert_info.issuer_org.as_ref().unwrap(),
"C2PA Test Signing Cert"
);
}
1 change: 1 addition & 0 deletions cawg_identity/src/tests/identity_assertion/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
// specific language governing permissions and limitations under
// each license.

mod assertion;
mod signer_payload;
3 changes: 3 additions & 0 deletions sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ pub enum Error {
#[error("could not find the assertion to redact")]
AssertionRedactionNotFound,

#[error("assertion-specific error: {0}")]
AssertionSpecificError(String),

#[error("bad parameter: {0}")]
BadParam(String),

Expand Down

0 comments on commit 4b4806c

Please sign in to comment.