c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

commit a767433e9e59f1d5617070758a574ceda3d7ba8e
parent 16fe91e27e9b2653f1a13d11472ed659bfab62a3
Author: mklein13 <michaelsklein13@gmail.com>
Date:   Tue,  6 Feb 2024 12:11:56 -0500

Finish async signing implementation for cose_sign (#370)

Co-authored-by: klein <klein@adobe.com>
Diffstat:
Msdk/src/cose_sign.rs | 61++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msdk/src/utils/test.rs | 22++++++++++++++++++++++
2 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/sdk/src/cose_sign.rs b/sdk/src/cose_sign.rs @@ -50,27 +50,40 @@ use crate::{ /// will respond with an error.) /// 3. Verifies that the signature is valid COSE. Will respond with an error /// [`Error::CoseSignature`] if unable to validate. +#[async_generic(async_signature( + claim_bytes: &[u8], + signer: &dyn AsyncSigner, + box_size: usize +))] pub fn sign_claim(claim_bytes: &[u8], signer: &dyn Signer, box_size: usize) -> Result<Vec<u8>> { // Must be a valid claim. let label = "dummy_label"; let _claim = Claim::from_data(label, claim_bytes)?; - // Generate and verify a CoseSign1 representation of the data. - cose_sign(signer, claim_bytes, box_size).and_then(|sig| { - // Sanity check: Ensure that this signature is valid. - let mut cose_log = OneShotStatusTracker::new(); - - match verify_cose(&sig, claim_bytes, b"", false, &mut cose_log) { - Ok(r) => { - if !r.validated { - Err(Error::CoseSignature) - } else { - Ok(sig) + let signed_bytes = if _sync { + cose_sign(signer, claim_bytes, box_size) + } else { + cose_sign_async(signer, claim_bytes, box_size).await + }; + + match signed_bytes { + Ok(signed_bytes) => { + // Sanity check: Ensure that this signature is valid. + let mut cose_log = OneShotStatusTracker::new(); + + match verify_cose(&signed_bytes, claim_bytes, b"", false, &mut cose_log) { + Ok(r) => { + if !r.validated { + Err(Error::CoseSignature) + } else { + Ok(signed_bytes) + } } + Err(err) => Err(err), } - Err(err) => Err(err), } - }) + Err(err) => Err(err), + } } /// Returns signed Cose_Sign1 bytes for `data`. @@ -309,6 +322,28 @@ mod tests { assert_eq!(cose_sign1.len(), box_size); } + #[cfg(not(target_arch = "wasm32"))] + #[actix::test] + async fn test_sign_claim_async() { + use crate::{ + cose_sign::sign_claim_async, openssl::AsyncSignerAdapter, AsyncSigner, SigningAlg, + }; + + let mut claim = Claim::new("extern_sign_test", Some("contentauth")); + claim.build().unwrap(); + + let claim_bytes = claim.data().unwrap(); + + let signer = AsyncSignerAdapter::new(SigningAlg::Ps256); + let box_size = signer.reserve_size(); + + let cose_sign1 = sign_claim_async(&claim_bytes, &signer, box_size) + .await + .unwrap(); + + assert_eq!(cose_sign1.len(), box_size); + } + struct BogusSigner {} impl BogusSigner { diff --git a/sdk/src/utils/test.rs b/sdk/src/utils/test.rs @@ -286,6 +286,28 @@ impl crate::Signer for TestGoodSigner { } } +pub(crate) struct AsyncTestGoodSigner {} + +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] +impl crate::AsyncSigner for AsyncTestGoodSigner { + async fn sign(&self, _data: Vec<u8>) -> Result<Vec<u8>> { + Ok(b"not a valid signature".to_vec()) + } + + fn alg(&self) -> SigningAlg { + SigningAlg::Ps256 + } + + fn certs(&self) -> Result<Vec<Vec<u8>>> { + Ok(Vec::new()) + } + + fn reserve_size(&self) -> usize { + 1024 + } +} + /// Create a [`Signer`] instance that can be used for testing purposes using ps256 alg. /// /// # Returns