1- use anyhow:: anyhow;
21use base64:: engine:: general_purpose;
32use base64:: Engine ;
43use der:: { DecodePem , EncodePem } ;
5- use libxml:: parser:: { Parser , XmlParseError } ;
6- use libxml:: tree:: { Document , Node } ;
74use openssl:: hash:: { hash, MessageDigest } ;
85use openssl:: pkey:: PKey ;
96use openssl:: rsa:: Rsa ;
107use openssl:: sign:: Signer ;
8+ use quick_xml:: events:: { BytesEnd , BytesStart , Event } ;
119use rsa:: pkcs1:: { DecodeRsaPrivateKey , EncodeRsaPrivateKey } ;
1210use rsa:: pkcs8:: LineEnding ;
1311use rsa:: RsaPrivateKey ;
12+ use std:: io:: Cursor ;
13+ use std:: { fs, io} ;
1414use x509_cert:: Certificate ;
1515use xml_c14n:: { canonicalize_xml, CanonicalizationMode , CanonicalizationOptions } ;
1616
@@ -88,36 +88,26 @@ impl From<Box<dyn std::error::Error + Send + Sync>> for SignErr {
8888}
8989
9090pub struct XSigner {
91- pub xml_document : Document ,
91+ pub xml_document : String ,
9292}
9393
9494impl XSigner {
95- pub fn from_file ( filename : & str ) -> Result < Self , XmlParseError > {
96- let xml_parser = libxml:: parser:: Parser :: default ( ) ;
97- let xml_document = xml_parser. parse_file ( filename) ?;
95+ pub fn from_file ( filename : & str ) -> Result < Self , io:: Error > {
96+ let xml_document = fs:: read_to_string ( filename) ?;
9897 Ok ( Self { xml_document } )
9998 }
10099
101- pub fn from_string ( xml : & str ) -> Result < Self , XmlParseError > {
102- let xml_parser = libxml:: parser:: Parser :: default ( ) ;
103- let xml_document = xml_parser. parse_string ( xml) ?;
104- Ok ( Self { xml_document } )
105- }
106-
107- pub fn sign ( & self , key_pair : & RsaKeyPair ) -> Result < ( ) , SignErr > {
108- let xml = & self . xml_document ;
109- let xml_string = xml. to_string ( ) ;
110-
100+ pub fn sign ( & self , key_pair : & RsaKeyPair ) -> Result < Vec < u8 > , SignErr > {
111101 let canonicalize_options = CanonicalizationOptions {
112102 mode : CanonicalizationMode :: Canonical1_1 ,
113- keep_comments : false ,
103+ keep_comments : true ,
114104 inclusive_ns_prefixes : vec ! [ ] ,
115105 } ;
116- let xml_canonicalize = canonicalize_xml ( & xml_string , canonicalize_options. clone ( ) )
106+ let xml_canonicalized = canonicalize_xml ( & self . xml_document , canonicalize_options. clone ( ) )
117107 . expect ( "Could not canonicalize xml" ) ;
118108
119109 // Generate digest
120- let digest = hash ( MessageDigest :: sha256 ( ) , xml_canonicalize . as_bytes ( ) )
110+ let digest = hash ( MessageDigest :: sha256 ( ) , xml_canonicalized . as_bytes ( ) )
121111 . expect ( "Digest generation error" ) ;
122112 let digest_base64 = general_purpose:: STANDARD . encode ( digest) ;
123113
@@ -159,31 +149,6 @@ impl XSigner {
159149 let signature = signer. sign_to_vec ( ) . expect ( "Error while signing" ) ;
160150 let signature_base64 = general_purpose:: STANDARD . encode ( & signature) ;
161151
162- // Search Signature element
163- fn find_extension_content_node ( node : Node ) -> Option < Node > {
164- if let Some ( ns) = node. get_namespace ( ) {
165- if ns. get_prefix ( ) == "ext" && node. get_name ( ) == "ExtensionContent" {
166- return Some ( node) ;
167- }
168- }
169-
170- for child in node. get_child_nodes ( ) . into_iter ( ) {
171- let result = find_extension_content_node ( child) ;
172- if result. is_some ( ) {
173- return result;
174- }
175- }
176-
177- None
178- }
179-
180- let xml_root_node = xml
181- . get_root_element ( )
182- . ok_or ( SignErr :: Any ( anyhow ! ( "Could not get the xml root element" ) ) ) ?;
183- let mut extension_content_node = find_extension_content_node ( xml_root_node) . ok_or (
184- SignErr :: Any ( anyhow ! ( "Could not find the ext:ExtensionContent tag" ) ) ,
185- ) ?;
186-
187152 // Signature
188153 let signature_string = format ! (
189154 "<ds:Signature xmlns:ds=\" http://www.w3.org/2000/09/xmldsig#\" Id=\" PROJECT-OPENUBL\" >
@@ -197,17 +162,65 @@ impl XSigner {
197162 </ds:Signature>"
198163 ) ;
199164
200- let parser = Parser :: default ( ) ;
201- let signature_string_node = parser
202- . parse_string ( & signature_string)
203- . expect ( "Could not parse Signature" ) ;
204- let mut signed_info_node_root = signature_string_node
205- . get_root_element ( )
206- . expect ( "Could not get root element of Signature" ) ;
207- signed_info_node_root. unlink ( ) ;
208-
209- extension_content_node. add_child ( & mut signed_info_node_root) ?;
210- Ok ( ( ) )
165+ let mut xml_reader = quick_xml:: Reader :: from_str ( & xml_canonicalized) ;
166+ let mut xml_writer = quick_xml:: Writer :: new ( Cursor :: new ( Vec :: new ( ) ) ) ;
167+
168+ let mut inside_target_element = false ;
169+ let mut requires_closing_extension_content_tag = false ;
170+
171+ loop {
172+ match xml_reader. read_event ( ) {
173+ Ok ( Event :: Empty ( e) ) => {
174+ if e. name ( ) . as_ref ( ) == b"ext:ExtensionContent" {
175+ inside_target_element = true ;
176+ requires_closing_extension_content_tag = true ;
177+
178+ xml_writer
179+ . write_event ( Event :: Start ( BytesStart :: new ( "ext:ExtensionContent" ) ) )
180+ . unwrap ( ) ;
181+ } else {
182+ assert ! ( xml_writer. write_event( Event :: Start ( e. clone( ) ) ) . is_ok( ) ) ;
183+ }
184+ }
185+ Ok ( Event :: Start ( e) ) => {
186+ assert ! ( xml_writer. write_event( Event :: Start ( e. clone( ) ) ) . is_ok( ) ) ;
187+ if e. name ( ) . as_ref ( ) == b"ext:ExtensionContent" {
188+ inside_target_element = true ;
189+ }
190+ }
191+ Ok ( Event :: End ( e) ) => {
192+ if inside_target_element {
193+ inside_target_element = false ;
194+
195+ let mut xml_content_reader = quick_xml:: Reader :: from_str ( & signature_string) ;
196+ loop {
197+ match xml_content_reader. read_event ( ) {
198+ Ok ( Event :: Eof ) => break ,
199+ Ok ( e) => assert ! ( xml_writer. write_event( e) . is_ok( ) ) ,
200+ Err ( e) => panic ! (
201+ "Error at position {}: {:?}" ,
202+ xml_reader. error_position( ) ,
203+ e
204+ ) ,
205+ }
206+ }
207+
208+ if requires_closing_extension_content_tag {
209+ xml_writer
210+ . write_event ( Event :: End ( BytesEnd :: new ( "ext:ExtensionContent" ) ) )
211+ . unwrap ( ) ;
212+ }
213+ }
214+ assert ! ( xml_writer. write_event( Event :: End ( e. clone( ) ) ) . is_ok( ) ) ;
215+ }
216+ Ok ( Event :: Eof ) => break ,
217+ Ok ( e) => assert ! ( xml_writer. write_event( e) . is_ok( ) ) ,
218+ Err ( e) => panic ! ( "Error at position {}: {:?}" , xml_reader. error_position( ) , e) ,
219+ }
220+ }
221+
222+ let result = xml_writer. into_inner ( ) . into_inner ( ) ;
223+ Ok ( result)
211224 }
212225}
213226
0 commit comments