@@ -17,6 +17,7 @@ use std::{
1717} ;
1818
1919use c2pa:: { Manifest , Reader } ;
20+ use c2pa_status_tracker:: { log_item, StatusTracker } ;
2021use serde:: { Deserialize , Serialize } ;
2122use serde_bytes:: ByteBuf ;
2223
@@ -63,14 +64,31 @@ impl IdentityAssertion {
6364 /// Iterator returns a [`Result`] because each assertion may fail to parse.
6465 ///
6566 /// Aside from CBOR parsing, no further validation is performed.
66- pub fn from_manifest (
67- manifest : & Manifest ,
68- ) -> impl Iterator < Item = Result < Self , c2pa:: Error > > + use < ' _ > {
67+ pub fn from_manifest < ' a > (
68+ manifest : & ' a Manifest ,
69+ status_tracker : & ' a mut StatusTracker ,
70+ ) -> impl Iterator < Item = Result < Self , c2pa:: Error > > + use < ' a > {
6971 manifest
7072 . assertions ( )
7173 . iter ( )
7274 . filter ( |a| a. label ( ) . starts_with ( "cawg.identity" ) )
73- . map ( |a| a. to_assertion ( ) )
75+ . map ( |a| ( a. label ( ) . to_owned ( ) , a. to_assertion ( ) ) )
76+ . inspect ( |( label, r) | {
77+ if let Err ( err) = r {
78+ // TO DO: a.label() is probably wrong (not a full JUMBF URI)
79+ log_item ! (
80+ label. clone( ) ,
81+ "invalid CBOR" ,
82+ "IdentityAssertion::from_manifest"
83+ )
84+ . validation_status ( "cawg.identity.cbor.invalid" )
85+ . failure_no_throw (
86+ status_tracker,
87+ c2pa:: Error :: AssertionSpecificError ( err. to_string ( ) ) ,
88+ ) ;
89+ }
90+ } )
91+ . map ( move |( _label, r) | r)
7492 }
7593
7694 /// Create a summary report from this `IdentityAssertion`.
@@ -83,25 +101,28 @@ impl IdentityAssertion {
83101 pub async fn to_summary < SV : SignatureVerifier > (
84102 & self ,
85103 manifest : & Manifest ,
104+ status_tracker : & mut StatusTracker ,
86105 verifier : & SV ,
87106 ) -> impl Serialize
88107 where
89108 <SV as SignatureVerifier >:: Output : ' static ,
90109 {
91- self . to_summary_impl ( manifest, verifier) . await
110+ self . to_summary_impl ( manifest, status_tracker, verifier)
111+ . await
92112 }
93113
94114 pub ( crate ) async fn to_summary_impl < SV : SignatureVerifier > (
95115 & self ,
96116 manifest : & Manifest ,
117+ status_tracker : & mut StatusTracker ,
97118 verifier : & SV ,
98119 ) -> IdentityAssertionReport <
99120 <<SV as SignatureVerifier >:: Output as ToCredentialSummary >:: CredentialSummary ,
100121 >
101122 where
102123 <SV as SignatureVerifier >:: Output : ' static ,
103124 {
104- match self . validate ( manifest, verifier) . await {
125+ match self . validate ( manifest, status_tracker , verifier) . await {
105126 Ok ( named_actor) => {
106127 let summary = named_actor. to_summary ( ) ;
107128
@@ -120,13 +141,15 @@ impl IdentityAssertion {
120141 /// Summarize all of the identity assertions found for a [`Manifest`].
121142 pub async fn summarize_all < SV : SignatureVerifier > (
122143 manifest : & Manifest ,
144+ status_tracker : & mut StatusTracker ,
123145 verifier : & SV ,
124146 ) -> impl Serialize {
125- Self :: summarize_all_impl ( manifest, verifier) . await
147+ Self :: summarize_all_impl ( manifest, status_tracker , verifier) . await
126148 }
127149
128150 pub ( crate ) async fn summarize_all_impl < SV : SignatureVerifier > (
129151 manifest : & Manifest ,
152+ status_tracker : & mut StatusTracker ,
130153 verifier : & SV ,
131154 ) -> IdentityAssertionsForManifest <
132155 <<SV as SignatureVerifier >:: Output as ToCredentialSummary >:: CredentialSummary ,
@@ -139,9 +162,16 @@ impl IdentityAssertion {
139162 > ,
140163 > = vec ! [ ] ;
141164
142- for assertion in Self :: from_manifest ( manifest) {
165+ let assertion_results: Vec < Result < IdentityAssertion , c2pa:: Error > > =
166+ Self :: from_manifest ( manifest, status_tracker) . collect ( ) ;
167+
168+ for assertion in assertion_results {
143169 let report = match assertion {
144- Ok ( assertion) => assertion. to_summary_impl ( manifest, verifier) . await ,
170+ Ok ( assertion) => {
171+ assertion
172+ . to_summary_impl ( manifest, status_tracker, verifier)
173+ . await
174+ }
145175 Err ( _) => {
146176 todo ! ( "Handle assertion failed to parse case" ) ;
147177 }
@@ -163,6 +193,7 @@ impl IdentityAssertion {
163193 #[ cfg( feature = "v1_api" ) ]
164194 pub async fn summarize_manifest_store < SV : SignatureVerifier > (
165195 store : & c2pa:: ManifestStore ,
196+ status_tracker : & mut StatusTracker ,
166197 verifier : & SV ,
167198 ) -> impl Serialize {
168199 // NOTE: We can't write this using .map(...).collect() because there are async
@@ -175,7 +206,7 @@ impl IdentityAssertion {
175206 > = BTreeMap :: new ( ) ;
176207
177208 for ( id, manifest) in store. manifests ( ) {
178- let report = Self :: summarize_all_impl ( manifest, verifier) . await ;
209+ let report = Self :: summarize_all_impl ( manifest, status_tracker , verifier) . await ;
179210 reports. insert ( id. clone ( ) , report) ;
180211 }
181212
@@ -189,6 +220,7 @@ impl IdentityAssertion {
189220 /// Summarize all of the identity assertions found for a [`Reader`].
190221 pub async fn summarize_from_reader < SV : SignatureVerifier > (
191222 reader : & Reader ,
223+ status_tracker : & mut StatusTracker ,
192224 verifier : & SV ,
193225 ) -> impl Serialize {
194226 // NOTE: We can't write this using .map(...).collect() because there are async
@@ -201,7 +233,7 @@ impl IdentityAssertion {
201233 > = BTreeMap :: new ( ) ;
202234
203235 for ( id, manifest) in reader. manifests ( ) {
204- let report = Self :: summarize_all_impl ( manifest, verifier) . await ;
236+ let report = Self :: summarize_all_impl ( manifest, status_tracker , verifier) . await ;
205237 reports. insert ( id. clone ( ) , report) ;
206238 }
207239
@@ -222,25 +254,55 @@ impl IdentityAssertion {
222254 pub async fn validate < SV : SignatureVerifier > (
223255 & self ,
224256 manifest : & Manifest ,
257+ status_tracker : & mut StatusTracker ,
225258 verifier : & SV ,
226259 ) -> Result < SV :: Output , ValidationError < SV :: Error > > {
227- self . check_padding ( ) ?;
260+ // TO DO: Create new status tracker here and pass it through
261+ // the rest of this code. Then we can rewrite the log with
262+ // assertion label at the end of this process.
263+
264+ // UPDATED TO DO: Hold off until Gavin lands the post-validate branch.
265+ // Then we'll get the assertion label handed to us nicely.
266+ self . check_padding ( status_tracker) ?;
228267
229- self . signer_payload . check_against_manifest ( manifest) ?;
268+ self . signer_payload
269+ . check_against_manifest ( manifest, status_tracker) ?;
230270
231271 verifier
232- . check_signature ( & self . signer_payload , & self . signature )
272+ . check_signature ( & self . signer_payload , & self . signature , status_tracker )
233273 . await
234274 }
235275
236- fn check_padding < E > ( & self ) -> Result < ( ) , ValidationError < E > > {
276+ fn check_padding < E : Debug > (
277+ & self ,
278+ status_tracker : & mut StatusTracker ,
279+ ) -> Result < ( ) , ValidationError < E > > {
237280 if !self . pad1 . iter ( ) . all ( |b| * b == 0 ) {
238- return Err ( ValidationError :: InvalidPadding ) ;
281+ // TO DO: Where would we get assertion label?
282+ log_item ! (
283+ "NEED TO FIND LABEL" . to_owned( ) ,
284+ "invalid value in pad fields" ,
285+ "SignerPayload::check_padding"
286+ )
287+ . validation_status ( "cawg.identity.pad.invalid" )
288+ . failure ( status_tracker, ValidationError :: < E > :: InvalidPadding ) ?;
289+
290+ // We'll only get to this line if `pad1` is invalid and the status tracker is
291+ // configured to continue through recoverable errors. In that case, we want to
292+ // avoid logging a second "invalid padding" warning if `pad2` is also invalid.
293+ return Ok ( ( ) ) ;
239294 }
240295
241296 if let Some ( pad2) = self . pad2 . as_ref ( ) {
242297 if !pad2. iter ( ) . all ( |b| * b == 0 ) {
243- return Err ( ValidationError :: InvalidPadding ) ;
298+ // TO DO: Where would we get assertion label?
299+ log_item ! (
300+ "NEED TO FIND LABEL" . to_owned( ) ,
301+ "invalid value in pad fields" ,
302+ "SignerPayload::check_padding"
303+ )
304+ . validation_status ( "cawg.identity.pad.invalid" )
305+ . failure ( status_tracker, ValidationError :: < E > :: InvalidPadding ) ?;
244306 }
245307 }
246308
0 commit comments