@@ -8,7 +8,9 @@ use std::{
88 path:: PathBuf ,
99} ;
1010
11- use catalyst_signed_doc:: { CatalystSignedDocument , Decode , Decoder , KidUri , Metadata } ;
11+ use catalyst_signed_doc:: {
12+ Builder , CatalystSignedDocument , Content , Decode , Decoder , KidUri , Metadata , Signatures ,
13+ } ;
1214use clap:: Parser ;
1315use coset:: { CborSerializable , Header } ;
1416use ed25519_dalek:: { ed25519:: signature:: Signer , pkcs8:: DecodePrivateKey } ;
@@ -60,19 +62,39 @@ impl Cli {
6062 match self {
6163 Self :: Build {
6264 doc,
63- schema,
65+ schema : _ ,
6466 output,
6567 meta,
6668 } => {
67- let doc_schema = load_schema_from_file ( & schema) ?;
68- let json_doc = load_json_from_file ( & doc) ?;
69- let json_meta = & load_json_from_file ( & meta)
69+ // Load Metadata from JSON file
70+ let metadata: Metadata = load_json_from_file ( & meta)
7071 . map_err ( |e| anyhow:: anyhow!( "Failed to load metadata from file: {e}" ) ) ?;
71- println ! ( "{json_meta}" ) ;
72- validate_json ( & json_doc, & doc_schema) ?;
73- let compressed_doc = brotli_compress_json ( & json_doc) ?;
74- let empty_cose_sign = build_empty_cose_doc ( compressed_doc, json_meta) ?;
75- store_cose_file ( empty_cose_sign, & output) ?;
72+ println ! ( "{metadata}" ) ;
73+ // Load Document from JSON file
74+ let json_doc: serde_json:: Value = load_json_from_file ( & doc) ?;
75+ // Possibly encode if Metadata has an encoding set.
76+ let payload_bytes = serde_json:: to_vec ( & json_doc) ?;
77+ let payload = match metadata. content_encoding ( ) {
78+ Some ( encoding) => encoding. encode ( & payload_bytes) ?,
79+ None => payload_bytes,
80+ } ;
81+ let content = Content :: new (
82+ payload,
83+ metadata. content_type ( ) ,
84+ metadata. content_encoding ( ) ,
85+ ) ?;
86+ // Start with no signatures.
87+ let signatures = Signatures :: try_from ( & Vec :: new ( ) ) ?;
88+ let signed_doc = Builder :: new ( )
89+ . content ( content)
90+ . metadata ( metadata)
91+ . signatures ( signatures)
92+ . build ( ) ?;
93+ let mut bytes: Vec < u8 > = Vec :: new ( ) ;
94+ minicbor:: encode ( signed_doc, & mut bytes)
95+ . map_err ( |e| anyhow:: anyhow!( "Failed to encode document: {e}" ) ) ?;
96+
97+ write_bytes_to_file ( & bytes, & output) ?;
7698 } ,
7799 Self :: Sign { sk, doc, kid } => {
78100 let sk = load_secret_key_from_file ( & sk)
@@ -106,14 +128,14 @@ fn decode_signed_doc(cose_bytes: &[u8]) {
106128 ) ;
107129 match CatalystSignedDocument :: decode ( & mut Decoder :: new ( cose_bytes) , & mut ( ) ) {
108130 Ok ( cat_signed_doc) => {
109- println ! ( "This is a valid Catalyst Signed Document." ) ;
131+ println ! ( "This is a valid Catalyst Document." ) ;
110132 println ! ( "{cat_signed_doc}" ) ;
111133 } ,
112- Err ( e) => eprintln ! ( "Invalid Catalyst Signed Document, err: {e}" ) ,
134+ Err ( e) => eprintln ! ( "Invalid Catalyst Document, err: {e}" ) ,
113135 }
114136}
115137
116- fn load_schema_from_file ( schema_path : & PathBuf ) -> anyhow:: Result < jsonschema:: JSONSchema > {
138+ fn _load_schema_from_file ( schema_path : & PathBuf ) -> anyhow:: Result < jsonschema:: JSONSchema > {
117139 let schema_file = File :: open ( schema_path) ?;
118140 let schema_json = serde_json:: from_reader ( schema_file) ?;
119141 let schema = jsonschema:: JSONSchema :: options ( )
@@ -130,7 +152,7 @@ where T: for<'de> serde::Deserialize<'de> {
130152 Ok ( json)
131153}
132154
133- fn validate_json ( doc : & serde_json:: Value , schema : & jsonschema:: JSONSchema ) -> anyhow:: Result < ( ) > {
155+ fn _validate_json ( doc : & serde_json:: Value , schema : & jsonschema:: JSONSchema ) -> anyhow:: Result < ( ) > {
134156 schema. validate ( doc) . map_err ( |err| {
135157 let mut validation_error = String :: new ( ) ;
136158 for e in err {
@@ -141,15 +163,15 @@ fn validate_json(doc: &serde_json::Value, schema: &jsonschema::JSONSchema) -> an
141163 Ok ( ( ) )
142164}
143165
144- fn brotli_compress_json ( doc : & serde_json:: Value ) -> anyhow:: Result < Vec < u8 > > {
166+ fn _brotli_compress_json ( doc : & serde_json:: Value ) -> anyhow:: Result < Vec < u8 > > {
145167 let brotli_params = brotli:: enc:: BrotliEncoderParams :: default ( ) ;
146- let doc_bytes = serde_json:: to_vec ( & doc) ?;
168+ let doc_bytes = serde_json:: to_vec ( doc) ?;
147169 let mut buf = Vec :: new ( ) ;
148170 brotli:: BrotliCompress ( & mut doc_bytes. as_slice ( ) , & mut buf, & brotli_params) ?;
149171 Ok ( buf)
150172}
151173
152- fn build_empty_cose_doc ( doc_bytes : Vec < u8 > , meta : & Metadata ) -> anyhow:: Result < coset:: CoseSign > {
174+ fn _build_empty_cose_doc ( doc_bytes : Vec < u8 > , meta : & Metadata ) -> anyhow:: Result < coset:: CoseSign > {
153175 let protected_header = Header :: try_from ( meta) ?;
154176 Ok ( coset:: CoseSignBuilder :: new ( )
155177 . protected ( protected_header)
@@ -158,20 +180,28 @@ fn build_empty_cose_doc(doc_bytes: Vec<u8>, meta: &Metadata) -> anyhow::Result<c
158180}
159181
160182fn load_cose_from_file ( cose_path : & PathBuf ) -> anyhow:: Result < coset:: CoseSign > {
161- let mut cose_file = File :: open ( cose_path) ?;
162- let mut cose_file_bytes = Vec :: new ( ) ;
163- cose_file. read_to_end ( & mut cose_file_bytes) ?;
183+ let cose_file_bytes = read_bytes_from_file ( cose_path) ?;
164184 let cose = coset:: CoseSign :: from_slice ( & cose_file_bytes) . map_err ( |e| anyhow:: anyhow!( "{e}" ) ) ?;
165185 Ok ( cose)
166186}
167187
188+ fn read_bytes_from_file ( path : & PathBuf ) -> anyhow:: Result < Vec < u8 > > {
189+ let mut file_bytes = Vec :: new ( ) ;
190+ File :: open ( path) ?. read_to_end ( & mut file_bytes) ?;
191+ Ok ( file_bytes)
192+ }
193+
194+ fn write_bytes_to_file ( bytes : & [ u8 ] , output : & PathBuf ) -> anyhow:: Result < ( ) > {
195+ File :: create ( output) ?
196+ . write_all ( bytes)
197+ . map_err ( |e| anyhow:: anyhow!( "Failed to write to file {output:?}: {e}" ) )
198+ }
199+
168200fn store_cose_file ( cose : coset:: CoseSign , output : & PathBuf ) -> anyhow:: Result < ( ) > {
169- let mut cose_file = File :: create ( output) ?;
170201 let cose_bytes = cose
171202 . to_vec ( )
172203 . map_err ( |e| anyhow:: anyhow!( "Failed to Store COSE SIGN: {e}" ) ) ?;
173- cose_file. write_all ( & cose_bytes) ?;
174- Ok ( ( ) )
204+ write_bytes_to_file ( & cose_bytes, output)
175205}
176206
177207fn load_secret_key_from_file ( sk_path : & PathBuf ) -> anyhow:: Result < ed25519_dalek:: SigningKey > {
0 commit comments