@@ -3,13 +3,19 @@ use catalyst_types::{catalyst_id::CatalystId, problem_report::ProblemReport};
33
44use crate :: {
55 signature:: { tbs_data, Signature } ,
6- CatalystSignedDocument , Content , InnerCatalystSignedDocument , Metadata , Signatures ,
7- PROBLEM_REPORT_CTX ,
6+ CatalystSignedDocument , Content , Metadata , Signatures ,
87} ;
98
109/// Catalyst Signed Document Builder.
1110#[ derive( Debug ) ]
12- pub struct Builder ( InnerCatalystSignedDocument ) ;
11+ pub struct Builder {
12+ /// metadata
13+ metadata : Metadata ,
14+ /// content
15+ content : Content ,
16+ /// signatures
17+ signatures : Signatures ,
18+ }
1319
1420impl Default for Builder {
1521 fn default ( ) -> Self {
@@ -21,14 +27,11 @@ impl Builder {
2127 /// Start building a signed document
2228 #[ must_use]
2329 pub fn new ( ) -> Self {
24- let report = ProblemReport :: new ( PROBLEM_REPORT_CTX ) ;
25- Self ( InnerCatalystSignedDocument {
26- report,
30+ Self {
2731 metadata : Metadata :: default ( ) ,
2832 content : Content :: default ( ) ,
2933 signatures : Signatures :: default ( ) ,
30- raw_bytes : None ,
31- } )
34+ }
3235 }
3336
3437 /// Set document metadata in JSON format
@@ -38,15 +41,21 @@ impl Builder {
3841 /// - Fails if it is invalid metadata fields JSON object.
3942 pub fn with_json_metadata ( mut self , json : serde_json:: Value ) -> anyhow:: Result < Self > {
4043 let metadata = serde_json:: from_value ( json) ?;
41- self . 0 . metadata = Metadata :: from_metadata_fields ( metadata, & self . 0 . report ) ;
44+ self . metadata = Metadata :: from_metadata_fields ( metadata, & ProblemReport :: new ( "" ) ) ;
4245 Ok ( self )
4346 }
4447
4548 /// Set decoded (original) document content bytes
46- #[ must_use]
47- pub fn with_decoded_content ( mut self , content : Vec < u8 > ) -> Self {
48- self . 0 . content = Content :: from_decoded ( content) ;
49- self
49+ ///
50+ /// # Errors
51+ /// - Compression failure
52+ pub fn with_decoded_content ( mut self , decoded : Vec < u8 > ) -> anyhow:: Result < Self > {
53+ if let Some ( encoding) = self . metadata . content_encoding ( ) {
54+ self . content = encoding. encode ( & decoded) ?. into ( ) ;
55+ } else {
56+ self . content = decoded. into ( ) ;
57+ }
58+ Ok ( self )
5059 }
5160
5261 /// Add a signature to the document
@@ -62,29 +71,49 @@ impl Builder {
6271 if kid. is_id ( ) {
6372 anyhow:: bail!( "Provided kid should be in a uri format, kid: {kid}" ) ;
6473 }
65- let data_to_sign = tbs_data ( & kid, & self . 0 . metadata , & self . 0 . content ) ?;
74+ let data_to_sign = tbs_data ( & kid, & self . metadata , & self . content ) ?;
6675 let sign_bytes = sign_fn ( data_to_sign) ;
67- self . 0 . signatures . push ( Signature :: new ( kid, sign_bytes) ) ;
76+ self . signatures . push ( Signature :: new ( kid, sign_bytes) ) ;
6877
6978 Ok ( self )
7079 }
7180
7281 /// Build a signed document with the collected error report.
7382 /// Could provide an invalid document.
83+ ///
84+ /// # Panics
85+ /// Should not panic
7486 #[ must_use]
87+ #[ allow(
88+ clippy:: unwrap_used,
89+ reason = "At this point all the data MUST be correctly encodable, and the final prepared bytes MUST be correctly decodable as a CatalystSignedDocument object."
90+ ) ]
7591 pub fn build ( self ) -> CatalystSignedDocument {
76- self . 0 . into ( )
92+ let mut e = minicbor:: Encoder :: new ( Vec :: new ( ) ) ;
93+ // COSE_Sign tag
94+ // <!https://datatracker.ietf.org/doc/html/rfc8152#page-9>
95+ e. tag ( minicbor:: data:: Tag :: new ( 98 ) ) . unwrap ( ) ;
96+ e. array ( 4 ) . unwrap ( ) ;
97+ // protected headers (metadata fields)
98+ e. bytes ( minicbor:: to_vec ( & self . metadata ) . unwrap ( ) . as_slice ( ) )
99+ . unwrap ( ) ;
100+ // empty unprotected headers
101+ e. map ( 0 ) . unwrap ( ) ;
102+ // content
103+ e. encode ( & self . content ) . unwrap ( ) ;
104+ // signatures
105+ e. encode ( self . signatures ) . unwrap ( ) ;
106+
107+ CatalystSignedDocument :: try_from ( e. into_writer ( ) . as_slice ( ) ) . unwrap ( )
77108 }
78109}
79110
80111impl From < & CatalystSignedDocument > for Builder {
81112 fn from ( value : & CatalystSignedDocument ) -> Self {
82- Self ( InnerCatalystSignedDocument {
113+ Self {
83114 metadata : value. inner . metadata . clone ( ) ,
84115 content : value. inner . content . clone ( ) ,
85116 signatures : value. inner . signatures . clone ( ) ,
86- report : value. inner . report . clone ( ) ,
87- raw_bytes : None ,
88- } )
117+ }
89118 }
90119}
0 commit comments