3535)
3636from signxml .xades import ( # noqa:E402
3737 XAdESDataObjectFormat ,
38+ XAdESSignatureConfiguration ,
3839 XAdESSignaturePolicy ,
3940 XAdESSigner ,
4041 XAdESVerifier ,
4142 XAdESVerifyResult ,
4243)
4344
4445
46+ class XMLSignerWithSHA1 (XMLSigner ):
47+ def check_deprecated_methods (self ):
48+ pass
49+
50+
51+ sha1_ok = SignatureConfiguration (signature_methods = list (SignatureMethod ), digest_algorithms = list (DigestAlgorithm ))
52+ xades_sha1_ok = XAdESSignatureConfiguration (
53+ signature_methods = list (SignatureMethod ), digest_algorithms = list (DigestAlgorithm )
54+ )
55+
56+
4557def reset_tree (t , method ):
4658 if not isinstance (t , str ):
4759 for s in t .findall (".//ds:Signature" , namespaces = namespaces ):
@@ -101,7 +113,7 @@ def test_basic_signxml_statements(self):
101113 self .assertEqual (SignatureMethod .RSA_SHA256 .value , "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" )
102114 self .assertEqual (SignatureConstructionMethod .enveloped , methods .enveloped )
103115 with self .assertRaisesRegex (InvalidInput , "Unknown signature construction method" ):
104- signer = XMLSigner (method = None )
116+ signer = XMLSignerWithSHA1 (method = None )
105117
106118 with self .assertRaisesRegex (InvalidInput , "must be an XML element" ):
107119 XMLSigner (signature_algorithm = "hmac-sha256" ).sign ("x" , key = b"abc" )
@@ -124,7 +136,7 @@ def test_basic_signxml_statements(self):
124136 continue
125137 print (digest_alg .name , sig_alg .name , c14n_alg , method , type (d ))
126138 reset_tree (d , method )
127- signer = XMLSigner (
139+ signer = XMLSignerWithSHA1 (
128140 method = method ,
129141 signature_algorithm = sig_alg ,
130142 digest_algorithm = digest_alg ,
@@ -136,7 +148,7 @@ def test_basic_signxml_statements(self):
136148 )
137149 # print(etree.tostring(signed))
138150 hmac_key = self .keys ["hmac" ] if sig_alg_type == "hmac" else None
139- verify_kwargs = dict (require_x509 = False , hmac_key = hmac_key , validate_schema = True )
151+ verify_kwargs = dict (require_x509 = False , hmac_key = hmac_key , validate_schema = True , expect_config = sha1_ok )
140152
141153 if method == methods .detached :
142154
@@ -169,7 +181,12 @@ def resolver(uri):
169181 XMLVerifier ().verify (signed_data , id_attribute = "X" , ** verify_kwargs )
170182
171183 with self .assertRaisesRegex (InvalidInput , "Expected a X.509 certificate based signature" ):
172- XMLVerifier ().verify (signed_data , hmac_key = hmac_key , uri_resolver = verify_kwargs .get ("uri_resolver" ))
184+ XMLVerifier ().verify (
185+ signed_data ,
186+ hmac_key = hmac_key ,
187+ uri_resolver = verify_kwargs .get ("uri_resolver" ),
188+ expect_config = sha1_ok ,
189+ )
173190
174191 if method != methods .detached :
175192 with self .assertRaisesRegex (InvalidSignature , "Digest mismatch" ):
@@ -205,36 +222,34 @@ def test_x509_certs(self):
205222 tree = etree .parse (self .example_xml_files [0 ])
206223 ca_pem_file = os .path .join (os .path .dirname (__file__ ), "example-ca.pem" ).encode ("utf-8" )
207224 crt , key = self .load_example_keys ()
208- for hash_alg in "sha1" , "sha256" :
209- for method in methods .enveloped , methods .enveloping :
210- print (hash_alg , method )
211- data = tree .getroot ()
212- reset_tree (data , method )
213- signer = XMLSigner (method = method , signature_algorithm = "rsa-" + hash_alg )
214- signed = signer .sign (data , key = key , cert = crt )
215- signed_data = etree .tostring (signed )
216- XMLVerifier ().verify (signed_data , ca_pem_file = ca_pem_file )
217- XMLVerifier ().verify (signed_data , x509_cert = crt )
218- XMLVerifier ().verify (signed_data , x509_cert = load_certificate (FILETYPE_PEM , crt ))
219- XMLVerifier ().verify (signed_data , x509_cert = crt , cert_subject_name = "*.example.com" )
220-
221- with self .assertRaises (OpenSSLCryptoError ):
222- XMLVerifier ().verify (signed_data , x509_cert = crt [::- 1 ])
223-
224- with self .assertRaises (InvalidSignature ):
225- XMLVerifier ().verify (signed_data , x509_cert = crt , cert_subject_name = "test" )
226-
227- with self .assertRaisesRegex (InvalidCertificate , "unable to get local issuer certificate" ):
228- XMLVerifier ().verify (signed_data )
229- # TODO: negative: verify with wrong cert, wrong CA
225+ for method in methods .enveloped , methods .enveloping :
226+ data = tree .getroot ()
227+ reset_tree (data , method )
228+ signer = XMLSigner (method = method , signature_algorithm = SignatureMethod .RSA_SHA256 )
229+ signed = signer .sign (data , key = key , cert = crt )
230+ signed_data = etree .tostring (signed )
231+ XMLVerifier ().verify (signed_data , ca_pem_file = ca_pem_file )
232+ XMLVerifier ().verify (signed_data , x509_cert = crt )
233+ XMLVerifier ().verify (signed_data , x509_cert = load_certificate (FILETYPE_PEM , crt ))
234+ XMLVerifier ().verify (signed_data , x509_cert = crt , cert_subject_name = "*.example.com" )
235+
236+ with self .assertRaises (OpenSSLCryptoError ):
237+ XMLVerifier ().verify (signed_data , x509_cert = crt [::- 1 ])
238+
239+ with self .assertRaises (InvalidSignature ):
240+ XMLVerifier ().verify (signed_data , x509_cert = crt , cert_subject_name = "test" )
241+
242+ with self .assertRaisesRegex (InvalidCertificate , "unable to get local issuer certificate" ):
243+ XMLVerifier ().verify (signed_data )
244+ # TODO: negative: verify with wrong cert, wrong CA
230245
231246 def test_xmldsig_interop_examples (self ):
232247 ca_pem_file = os .path .join (os .path .dirname (__file__ ), "interop" , "cacert.pem" ).encode ("utf-8" )
233248 for signature_file in glob (os .path .join (os .path .dirname (__file__ ), "interop" , "*.xml" )):
234249 print ("Verifying" , signature_file )
235250 with open (signature_file , "rb" ) as fh :
236251 with self .assertRaisesRegex (InvalidCertificate , "certificate has expired" ):
237- XMLVerifier ().verify (fh .read (), ca_pem_file = ca_pem_file )
252+ XMLVerifier ().verify (fh .read (), ca_pem_file = ca_pem_file , expect_config = sha1_ok )
238253
239254 def test_xmldsig_interop_TR2012 (self ):
240255 def get_x509_cert (** kwargs ):
@@ -256,6 +271,7 @@ def get_x509_cert(**kwargs):
256271 hmac_key = "testkey" ,
257272 validate_schema = True ,
258273 cert_resolver = get_x509_cert if "x509digest" in signature_file else None ,
274+ expect_config = sha1_ok ,
259275 )
260276 sig .decode ("utf-8" )
261277 except Exception as e :
@@ -325,6 +341,7 @@ def cert_resolver(x509_issuer_name, x509_serial_number, x509_digest):
325341 x509_cert = get_x509_cert (signature_file ),
326342 cert_resolver = cert_resolver if "issuer-serial" in signature_file else None ,
327343 ca_pem_file = get_ca_pem_file (signature_file ),
344+ expect_config = sha1_ok ,
328345 )
329346 decoded_sig = sig .decode ("utf-8" )
330347 if "HMACOutputLength" in decoded_sig or "bad" in signature_file or "expired" in signature_file :
@@ -543,13 +560,13 @@ def test_ws_security(self):
543560 with open (os .path .join (wsse_dir , "examples" , "server_public.pem" ), "rb" ) as fh :
544561 crt = fh .read ()
545562 data = etree .parse (os .path .join (wsse_dir , "test" , "unit" , "client" , "files" , "valid wss resp.xml" ))
546- XMLVerifier ().verify (data , x509_cert = crt , validate_schema = False , expect_references = 2 )
563+ XMLVerifier ().verify (data , x509_cert = crt , validate_schema = False , expect_references = 2 , expect_config = sha1_ok )
547564
548565 data = etree .parse (
549566 os .path .join (wsse_dir , "test" , "unit" , "client" , "files" , "invalid wss resp - changed content.xml" )
550567 )
551568 with self .assertRaisesRegex (InvalidDigest , "Digest mismatch for reference 0" ):
552- XMLVerifier ().verify (data , x509_cert = crt , validate_schema = False , expect_references = 2 )
569+ XMLVerifier ().verify (data , x509_cert = crt , validate_schema = False , expect_references = 2 , expect_config = sha1_ok )
553570
554571 def test_psha1 (self ):
555572 from signxml .util import p_sha1
@@ -620,6 +637,18 @@ def test_verify_config(self):
620637 with self .assertRaisesRegex (InvalidInput , "Digest algorithm SHA256 forbidden by configuration" ):
621638 verifier .verify (signed , x509_cert = cert , expect_config = config )
622639
640+ def test_sha1_policy (self ):
641+ data = etree .parse (self .example_xml_files [0 ]).getroot ()
642+ cert , key = self .load_example_keys ()
643+ with self .assertRaisesRegex (InvalidInput , "SHA1-based algorithms are not supported" ):
644+ XMLSigner (signature_algorithm = SignatureMethod .RSA_SHA1 )
645+ signer = XMLSignerWithSHA1 (signature_algorithm = SignatureMethod .RSA_SHA1 , digest_algorithm = DigestAlgorithm .SHA1 )
646+ signed = signer .sign (data , cert = cert , key = key )
647+ verifier = XMLVerifier ()
648+ with self .assertRaisesRegex (InvalidInput , "Signature method RSA_SHA1 forbidden by configuration" ):
649+ verifier .verify (signed , x509_cert = cert )
650+ verifier .verify (signed , x509_cert = cert , expect_config = sha1_ok )
651+
623652
624653class TestXAdES (unittest .TestCase , LoadExampleKeys ):
625654 expect_references = {
@@ -681,7 +710,11 @@ def test_xades_interop_examples(self):
681710 with open (sig_file , "rb" ) as fh :
682711 doc = etree .parse (fh )
683712 cert = doc .find ("//{http://www.w3.org/2000/09/xmldsig#}X509Certificate" ).text
684- kwargs = dict (x509_cert = cert , expect_references = self .expect_references .get (os .path .basename (sig_file ), 2 ))
713+ kwargs = dict (
714+ x509_cert = cert ,
715+ expect_references = self .expect_references .get (os .path .basename (sig_file ), 2 ),
716+ expect_config = xades_sha1_ok ,
717+ )
685718 if "nonconformant" in sig_file :
686719 kwargs .update (validate_schema = False )
687720 if "sigPolStore" in sig_file :
0 commit comments