def get_x509_cert(signature_file): if "windows_store_signature" in signature_file: return open(os.path.join(interop_dir, "xml-crypto", "windows_store_certificate.pem")).read() elif "pyXMLSecurity" in signature_file: return open(os.path.join(interop_dir, "pyXMLSecurity", "test.pem")).read() else: return None
def get_x509_cert(signature_file): if "windows_store_signature" in signature_file: return open(os.path.join(interop_dir, "xml-crypto", "windows_store_certificate.pem")).read() elif "pyXMLSecurity" in signature_file: return open(os.path.join(interop_dir, "pyXMLSecurity", "test.pem")).read() else: return None
def test_x509_certs(self): from OpenSSL.crypto import load_certificate, FILETYPE_PEM, Error as OpenSSLCryptoError tree = etree.parse(self.example_xml_files[0]) ca_pem_file = os.path.join(os.path.dirname(__file__), "example-ca.pem").encode("utf-8") with open(os.path.join(os.path.dirname(__file__), "example.pem"), "rb") as fh: crt = fh.read() with open(os.path.join(os.path.dirname(__file__), "example.key"), "rb") as fh: key = fh.read() for hash_alg in "sha1", "sha256": for method in methods.enveloped, methods.enveloping: print(hash_alg, method) data = tree.getroot() reset_tree(data, method) signer = XMLSigner(method=method, signature_algorithm="rsa-" + hash_alg) signed = signer.sign(data, key=key, cert=crt) signed_data = etree.tostring(signed) XMLVerifier().verify(signed_data, ca_pem_file=ca_pem_file) XMLVerifier().verify(signed_data, x509_cert=crt) XMLVerifier().verify(signed_data, x509_cert=load_certificate( FILETYPE_PEM, crt)) with self.assertRaises(OpenSSLCryptoError): XMLVerifier().verify(signed_data, x509_cert=crt[::-1]) with self.assertRaisesRegexp( InvalidCertificate, "unable to get local issuer certificate"): XMLVerifier().verify(signed_data)
def test_x509_certs(self): from OpenSSL.crypto import load_certificate, FILETYPE_PEM, Error as OpenSSLCryptoError tree = etree.parse(self.example_xml_files[0]) ca_pem_file = os.path.join(os.path.dirname(__file__), "example-ca.pem").encode("utf-8") with open(os.path.join(os.path.dirname(__file__), "example.pem"), "rb") as fh: crt = fh.read() with open(os.path.join(os.path.dirname(__file__), "example.key"), "rb") as fh: key = fh.read() for hash_alg in "sha1", "sha256": for method in methods.enveloped, methods.enveloping: print(hash_alg, method) data = tree.getroot() reset_tree(data, method) signer = XMLSigner(method=method, signature_algorithm="rsa-" + hash_alg) signed = signer.sign(data, key=key, cert=crt) signed_data = etree.tostring(signed) XMLVerifier().verify(signed_data, ca_pem_file=ca_pem_file) XMLVerifier().verify(signed_data, x509_cert=crt) XMLVerifier().verify(signed_data, x509_cert=load_certificate(FILETYPE_PEM, crt)) with self.assertRaises(OpenSSLCryptoError): XMLVerifier().verify(signed_data, x509_cert=crt[::-1]) with self.assertRaisesRegexp(InvalidCertificate, "unable to get local issuer certificate"): XMLVerifier().verify(signed_data)
def resolver(uri): if uri == "document.xml": with open(os.path.join(interop_dir, "phaos-xmldsig-three", uri), "rb") as fh: return fh.read() elif uri == "http://www.ietf.org/rfc/rfc3161.txt": with open(os.path.join(os.path.dirname(__file__), "rfc3161.txt"), "rb") as fh: return fh.read() return None
def resolver(uri): if uri == "document.xml": with open(os.path.join(interop_dir, "phaos-xmldsig-three", uri), "rb") as fh: return fh.read() elif uri == "http://www.ietf.org/rfc/rfc3161.txt": with open(os.path.join(os.path.dirname(__file__), "rfc3161.txt"), "rb") as fh: return fh.read() return None
def test_reference_uris_and_custom_key_info(self): with open(os.path.join(os.path.dirname(__file__), "example.pem"), "rb") as fh: crt = fh.read() with open(os.path.join(os.path.dirname(__file__), "example.key"), "rb") as fh: key = fh.read() # Both ID and Id formats. XPath 1 doesn't have case insensitive attribute search for d in ['''<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="responseId"> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="assertionId"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="placeholder" /> </saml:Assertion> </samlp:Response>''', '''<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Id="responseId"> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" Id="assertionId"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="placeholder" /> </saml:Assertion> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" Id="assertion2"> </saml:Assertion> </samlp:Response>''']: data = etree.fromstring(d) reference_uri = ["assertionId", "assertion2"] if "assertion2" in d else "assertionId" signed_root = XMLSigner().sign(data, reference_uri=reference_uri, key=key, cert=crt) signed_data_root = XMLVerifier().verify(etree.tostring(signed_root), x509_cert=crt, expect_references=True)[1] ref = signed_root.xpath('/samlp:Response/saml:Assertion/ds:Signature/ds:SignedInfo/ds:Reference', namespaces={"ds": "http://www.w3.org/2000/09/xmldsig#", "saml": "urn:oasis:names:tc:SAML:2.0:assertion", "samlp": "urn:oasis:names:tc:SAML:2.0:protocol"}) self.assertEqual("assertionId", ref[0].attrib['URI'][1:]) self.assertEqual("{urn:oasis:names:tc:SAML:2.0:assertion}Assertion", signed_data_root.tag) # Also test with detached signing for c14_transform_option in include_c14_transformation: XMLSigner(method=methods.detached, include_c14n_transform=c14_transform_option ).sign(data, reference_uri=reference_uri, key=key, cert=crt) # Test setting custom key info custom_key_info = etree.fromstring(''' <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-639b8970-7644-4f9e-9bc4-9c2e367808fc-1"/> </wsse:SecurityTokenReference>''') XMLSigner().sign(data, reference_uri=reference_uri, key=key, cert=crt, key_info=custom_key_info)
def test_xml_attacks(self): for filename in glob( os.path.join(os.path.dirname(__file__), "defusedxml-test-data", "*.xml")): with open(filename, "rb") as fh: with self.assertRaises((InvalidInput, etree.XMLSyntaxError)): XMLVerifier().verify(fh.read())
def test_xmldsig_interop_examples(self): ca_pem_file = os.path.join(os.path.dirname(__file__), "interop", "cacert.pem").encode("utf-8") for signature_file in glob(os.path.join(os.path.dirname(__file__), "interop", "*.xml")): print("Verifying", signature_file) with open(signature_file, "rb") as fh: with self.assertRaisesRegexp(InvalidCertificate, "certificate has expired"): XMLVerifier().verify(fh.read(), ca_pem_file=ca_pem_file)
def test_xmldsig_interop_TR2012(self): def get_x509_cert(**kwargs): from cryptography.x509 import load_der_x509_certificate from OpenSSL.crypto import X509 with open(os.path.join(interop_dir, "TR2012", "rsa-cert.der"), "rb") as fh: return [ X509.from_cryptography( load_der_x509_certificate(fh.read(), backend=default_backend())) ] signature_files = glob( os.path.join(interop_dir, "TR2012", "signature*.xml")) for signature_file in signature_files: print("Verifying", signature_file) with open(signature_file, "rb") as fh: try: sig = fh.read() XMLVerifier().verify( sig, require_x509=False, hmac_key="testkey", validate_schema=True, cert_resolver=get_x509_cert if "x509digest" in signature_file else None) decoded_sig = sig.decode("utf-8") except Exception as e: if "keyinforeference" in signature_file: print("Unsupported test case:", type(e), e) elif "x509digest" in signature_file: assert isinstance(e, InvalidCertificate) else: raise
def test_xmldsig_interop_examples(self): ca_pem_file = os.path.join(os.path.dirname(__file__), "interop", "cacert.pem").encode("utf-8") for signature_file in glob(os.path.join(os.path.dirname(__file__), "interop", "*.xml")): print("Verifying", signature_file) with open(signature_file, "rb") as fh: with self.assertRaisesRegexp(InvalidCertificate, "certificate has expired"): XMLVerifier().verify(fh.read(), ca_pem_file=ca_pem_file)
def test_example_multi(self): with open(os.path.join(os.path.dirname(__file__), "example.pem")) as fh: cert = fh.read() example_file = os.path.join(os.path.dirname(__file__), "example-125.xml") verify_results = XMLVerifier().verify( data=etree.parse(example_file), x509_cert=cert, expect_references=2, )
def get_x509_cert(**kwargs): from cryptography.x509 import load_der_x509_certificate from OpenSSL.crypto import X509 with open(os.path.join(interop_dir, "TR2012", "rsa-cert.der"), "rb") as fh: return [ X509.from_cryptography( load_der_x509_certificate(fh.read(), backend=default_backend())) ]
def test_ws_security(self): wsse_dir = os.path.join(interop_dir, "ws-security", "ws.js") with open(os.path.join(wsse_dir, "examples", "server_public.pem"), "rb") as fh: crt = fh.read() data = etree.parse(os.path.join(wsse_dir, "test", "unit", "client", "files", "valid wss resp.xml")) XMLVerifier().verify(data, x509_cert=crt, validate_schema=False, expect_references=2) data = etree.parse(os.path.join(wsse_dir, "test", "unit", "client", "files", "invalid wss resp - changed content.xml")) with self.assertRaisesRegexp(InvalidDigest, "Digest mismatch for reference 0"): XMLVerifier().verify(data, x509_cert=crt, validate_schema=False, expect_references=2)
def test_soap_request_with_inclusive_namespaces(self): with open(os.path.join(interop_dir, "soap", "request.xml")) as req_fh: with self.assertRaises(etree.DocumentInvalid): XMLVerifier().verify(req_fh.read(), ca_pem_file=os.path.join(interop_dir, "soap", "ca.pem"), expect_references=False) req_fh.seek(0) XMLVerifier().verify(req_fh.read(), ca_pem_file=os.path.join(interop_dir, "soap", "ca.pem"), expect_references=False, validate_schema=False)
def test_signature_properties_with_detached_method(self): doc = etree.Element('Test', attrib={'Id': 'mytest'}) sigprop = etree.Element('{http://somenamespace}MyCustomProperty') sigprop.text = 'Some Text' with open(os.path.join(os.path.dirname(__file__), "example.key"), "rb") as file: key = file.read() with open(os.path.join(os.path.dirname(__file__), "example.pem"), "rb") as file: cert = file.read() signature = XMLSigner(method=methods.detached).sign( doc, cert=cert, key=key, reference_uri="#mytest", signature_properties=sigprop) fulldoc = b'<root>' + etree.tostring(signature) + etree.tostring( doc) + b'</root>' XMLVerifier().verify(etree.fromstring(fulldoc), x509_cert=cert, expect_references=2)
def test_xmldsig_interop_TR2012(self): def get_x509_cert(signature_file): with open( os.path.join(os.path.dirname(__file__), "keys", "p256-cert.der"), "rb") as fh: return fh.read() signature_files = glob( os.path.join(interop_dir, "TR2012", "signature*.xml")) for signature_file in signature_files: print("Verifying", signature_file) with open(signature_file, "rb") as fh: try: sig = fh.read() XMLVerifier().verify(sig, require_x509=False, hmac_key="testkey", validate_schema=True) decoded_sig = sig.decode("utf-8") except Exception as e: if "keyinforeference" in signature_file or "x509digest" in signature_file: print("Unsupported test case:", type(e), e) else: raise
def test_reference_uris_and_custom_key_info(self): with open(os.path.join(os.path.dirname(__file__), "example.pem"), "rb") as fh: crt = fh.read() with open(os.path.join(os.path.dirname(__file__), "example.key"), "rb") as fh: key = fh.read() # Both ID and Id formats. XPath 1 doesn't have case insensitive attribute search for d in [ '''<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="responseId"> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="assertionId"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="placeholder" /> </saml:Assertion> </samlp:Response>''', '''<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Id="responseId"> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" Id="assertionId"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="placeholder" /> </saml:Assertion> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" Id="assertion2"> </saml:Assertion> </samlp:Response>''' ]: data = etree.fromstring(d) reference_uri = ["assertionId", "assertion2" ] if "assertion2" in d else "assertionId" signed_root = XMLSigner().sign(data, reference_uri=reference_uri, key=key, cert=crt) signed_data_root = XMLVerifier().verify( etree.tostring(signed_root), x509_cert=crt, expect_references=True)[1] ref = signed_root.xpath( '/samlp:Response/saml:Assertion/ds:Signature/ds:SignedInfo/ds:Reference', namespaces={ "ds": "http://www.w3.org/2000/09/xmldsig#", "saml": "urn:oasis:names:tc:SAML:2.0:assertion", "samlp": "urn:oasis:names:tc:SAML:2.0:protocol" }) self.assertEqual("assertionId", ref[0].attrib['URI'][1:]) self.assertEqual( "{urn:oasis:names:tc:SAML:2.0:assertion}Assertion", signed_data_root.tag) # Also test with detached signing ref_xpath = "/ds:Signature/ds:SignedInfo/ds:Reference" signer = XMLSigner(method=methods.detached) s = signer.sign(data, reference_uri=reference_uri, key=key, cert=crt) self.assertTrue( s.xpath(ref_xpath + "/ds:Transforms", namespaces=namespaces)) self.assertTrue( s.xpath(ref_xpath + "/ds:DigestMethod", namespaces=namespaces)) self.assertTrue( s.xpath(ref_xpath + "/ds:DigestValue", namespaces=namespaces)) self.assertTrue( s.xpath("/ds:Signature/ds:KeyInfo/ds:X509Data", namespaces=namespaces)) self.assertFalse( s.xpath("/ds:Signature/ds:KeyInfo/ds:KeyValue", namespaces=namespaces)) s2 = signer.sign(data, reference_uri=reference_uri, key=key, cert=crt, always_add_key_value=True) self.assertTrue( s2.xpath("/ds:Signature/ds:KeyInfo/ds:X509Data", namespaces=namespaces)) self.assertTrue( s2.xpath("/ds:Signature/ds:KeyInfo/ds:KeyValue", namespaces=namespaces)) # Test setting custom key info wsse_ns = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" with open( os.path.join(os.path.dirname(__file__), "wsse_keyinfo.xml")) as fh: custom_key_info = etree.fromstring(fh.read()) s3 = signer.sign(data, reference_uri=reference_uri, key=key, cert=crt, key_info=custom_key_info) self.assertTrue( s3.xpath( "/ds:Signature/ds:KeyInfo/wsse:SecurityTokenReference", namespaces=dict(namespaces, wsse=wsse_ns))) # Test setting both X509Data and KeyInfo s4 = XMLSigner().sign(data, reference_uri=reference_uri, key=key, cert=crt, always_add_key_value=True) with self.assertRaisesRegexp(InvalidInput, "Both X509Data and KeyValue found"): XMLVerifier().verify(s4, x509_cert=crt) expect_refs = etree.tostring(s4).decode().count("<ds:Reference") XMLVerifier().verify(s4, x509_cert=crt, ignore_ambiguous_key_info=True, expect_references=expect_refs)
def test_xmldsig_interop(self): def resolver(uri): if uri == "document.xml": with open( os.path.join(interop_dir, "phaos-xmldsig-three", uri), "rb") as fh: return fh.read() elif uri == "http://www.ietf.org/rfc/rfc3161.txt": with open( os.path.join(os.path.dirname(__file__), "rfc3161.txt"), "rb") as fh: return fh.read() return None def get_x509_cert(signature_file): if "windows_store_signature" in signature_file: return open( os.path.join(interop_dir, "xml-crypto", "windows_store_certificate.pem")).read() elif "pyXMLSecurity" in signature_file: return open( os.path.join(interop_dir, "pyXMLSecurity", "test.pem")).read() else: return None def get_ca_pem_file(signature_file): if "signature-dsa" in signature_file: ca_pem_file = os.path.join(interop_dir, "phaos-xmldsig-three", "certs", "dsa-ca-cert.pem") elif "signature-rsa" in signature_file: ca_pem_file = os.path.join(interop_dir, "phaos-xmldsig-three", "certs", "rsa-ca-cert.pem") elif "aleksey-xmldsig-01-enveloped" in signature_file: ca_pem_file = os.path.join(interop_dir, "aleksey-xmldsig-01-enveloped", "cacert.pem") elif "aleksey" in signature_file: ca_pem_file = os.path.join(interop_dir, "aleksey-xmldsig-01", "cacert.pem") elif "wsfederation_metadata" in signature_file: ca_pem_file = os.path.join(interop_dir, "xml-crypto", "wsfederation_metadata.pem") elif "signature_with_inclusivenamespaces" in signature_file: ca_pem_file = os.path.join( interop_dir, "xml-crypto", "signature_with_inclusivenamespaces.pem") else: return None return ca_pem_file.encode("utf-8") signature_files = glob(os.path.join(interop_dir, "*", "signature*.xml")) signature_files += glob(os.path.join(interop_dir, "aleksey*", "*.xml")) signature_files += glob( os.path.join(interop_dir, "xml-crypto", "*.xml")) signature_files += glob( os.path.join(interop_dir, "pyXMLSecurity", "*.xml")) for signature_file in signature_files: print("Verifying", signature_file) with open(signature_file, "rb") as fh: try: sig = fh.read() XMLVerifier().verify( sig, require_x509=False, hmac_key="test" if "phaos" in signature_file else "secret", validate_schema=True, uri_resolver=resolver, x509_cert=get_x509_cert(signature_file), ca_pem_file=get_ca_pem_file(signature_file)) decoded_sig = sig.decode("utf-8") if "HMACOutputLength" in decoded_sig or "bad" in signature_file or "expired" in signature_file: raise BaseException("Expected an exception to occur") except Exception as e: unsupported_cases = ("xpath-transform", "xslt-transform", "xpointer", "x509-data-issuer-serial", "x509-data-ski", "x509-data-subject-name", "x509data", "signature-x509-ski", "signature-x509-is") bad_interop_cases = ("signature-big", "enveloping-dsa-x509chain", "enveloping-sha512-hmac-sha512", "enveloping-sha512-rsa-sha512", "enveloping-rsa-x509chain", "enveloping-sha1-rsa-sha1", "enveloping-sha224-rsa-sha224", "enveloping-sha256-rsa-sha256", "enveloping-sha384-rsa-sha384") if signature_file.endswith( "expired-cert.xml") or signature_file.endswith( "wsfederation_metadata.xml"): # noqa with self.assertRaisesRegexp( InvalidCertificate, "certificate has expired"): raise elif signature_file.endswith( "invalid_enveloped_transform.xml"): self.assertIsInstance(e, InvalidSignature) # with self.assertRaisesRegexp(ValueError, "Can't remove the root signature node"): # raise elif "md5" in signature_file or "ripemd160" in signature_file: self.assertIsInstance(e, InvalidInput) # with self.assertRaisesRegexp(InvalidInput, "Algorithm .+ is not recognized"): # raise elif "HMACOutputLength" in sig.decode("utf-8"): self.assertIsInstance( e, (InvalidSignature, InvalidDigest)) elif signature_file.endswith( "signature-rsa-enveloped-bad-digest-val.xml"): # self.assertIsInstance(e, InvalidDigest) self.assertIsInstance(e, InvalidCertificate) elif signature_file.endswith( "signature-rsa-detached-xslt-transform-bad-retrieval-method.xml" ): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith( "signature-rsa-enveloped-bad-sig.xml"): self.assertIsInstance(e, etree.DocumentInvalid) elif signature_file.endswith("signature-x509-crt.xml"): self.assertIsInstance(e, InvalidCertificate) elif signature_file.endswith("signature-keyname.xml"): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith("signature-x509-sn.xml"): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith("signature-x509-crt-crl.xml"): self.assertIsInstance(e, InvalidCertificate) elif signature_file.endswith( "signature-retrievalmethod-rawx509crt.xml"): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith( "merlin-xmldsig-twenty-three/signature.xml"): self.assertIsInstance(e, InvalidInput) elif any(x in signature_file for x in unsupported_cases): print("Unsupported test case:", type(e), e) elif any(x in signature_file for x in bad_interop_cases ) or "Unable to resolve reference" in str(e): print("Bad interop test case:", type(e), e) elif "certificate has expired" in str(e) and ( "signature-dsa" in signature_file or "signature-rsa" in signature_file): # noqa print("IGNORED:", type(e), e) else: raise
def cert_resolver(x509_issuer_name, x509_serial_number, x509_digest): with open( os.path.join(interop_dir, "phaos-xmldsig-three", "certs", "rsa-cert.pem")) as fh: return [fh.read()]
def test_xmldsig_interop(self): interop_dir = os.path.join(os.path.dirname(__file__), "interop") def resolver(uri): if uri == "document.xml": with open(os.path.join(interop_dir, "phaos-xmldsig-three", uri), "rb") as fh: return fh.read() elif uri == "http://www.ietf.org/rfc/rfc3161.txt": with open(os.path.join(os.path.dirname(__file__), "rfc3161.txt"), "rb") as fh: return fh.read() return None #from ssl import DER_cert_to_PEM_cert #with open(os.path.join(os.path.dirname(__file__), "interop", "phaos-xmldsig-three", "certs", "dsa-ca-cert.der"), "rb") as fh: # ca_pem_file = DER_cert_to_PEM_cert(fh.read()) # with open(os.path.join(os.path.dirname(__file__), "interop", "phaos-xmldsig-three", "certs", "dsa-ca-cert.pem"), "wb") as fh2: # fh2.write(ca_pem_file) def get_x509_cert(signature_file): if "windows_store_signature" in signature_file: return open(os.path.join(interop_dir, "xml-crypto", "windows_store_certificate.pem")).read() elif "pyXMLSecurity" in signature_file: return open(os.path.join(interop_dir, "pyXMLSecurity", "test.pem")).read() else: return None def get_ca_pem_file(signature_file): if "signature-dsa" in signature_file: ca_pem_file = os.path.join(interop_dir, "phaos-xmldsig-three", "certs", "dsa-ca-cert.pem") elif "signature-rsa" in signature_file: ca_pem_file = os.path.join(interop_dir, "phaos-xmldsig-three", "certs", "rsa-ca-cert.pem") elif "aleksey-xmldsig-01-enveloped" in signature_file: ca_pem_file = os.path.join(interop_dir, "aleksey-xmldsig-01-enveloped", "cacert.pem") elif "aleksey" in signature_file: ca_pem_file = os.path.join(interop_dir, "aleksey-xmldsig-01", "cacert.pem") elif "wsfederation_metadata" in signature_file: ca_pem_file = os.path.join(interop_dir, "xml-crypto", "wsfederation_metadata.pem") elif "signature_with_inclusivenamespaces" in signature_file: ca_pem_file = os.path.join(interop_dir, "xml-crypto", "signature_with_inclusivenamespaces.pem") else: return None return ca_pem_file.encode("utf-8") signature_files = glob(os.path.join(interop_dir, "*", "signature*.xml")) signature_files += glob(os.path.join(interop_dir, "aleksey*", "*.xml")) signature_files += glob(os.path.join(interop_dir, "xml-crypto", "*.xml")) signature_files += glob(os.path.join(interop_dir, "pyXMLSecurity", "*.xml")) for signature_file in signature_files: print("Verifying", signature_file) with open(signature_file, "rb") as fh: try: sig = fh.read() XMLVerifier().verify(sig, require_x509=False, hmac_key="test" if "phaos" in signature_file else "secret", validate_schema=True, uri_resolver=resolver, x509_cert=get_x509_cert(signature_file), ca_pem_file=get_ca_pem_file(signature_file)) if "HMACOutputLength" in sig.decode("utf-8") or "bad" in signature_file or "expired" in signature_file: raise BaseException("Expected an exception to occur") except Exception as e: unsupported_cases = ("xpath-transform", "xslt-transform", "xpointer", "x509-data-issuer-serial", "x509-data-ski", "x509-data-subject-name", "x509data", "signature-x509-ski", "signature-x509-is") todo_cases = ("signature-big", "enveloping-dsa-x509chain", "enveloping-sha512-hmac-sha512", "enveloping-sha512-rsa-sha512") if signature_file.endswith("expired-cert.xml"): with self.assertRaisesRegexp(InvalidCertificate, "certificate has expired"): raise elif signature_file.endswith("invalid_enveloped_transform.xml"): self.assertIsInstance(e, InvalidSignature) #with self.assertRaisesRegexp(ValueError, "Can't remove the root signature node"): # raise elif "md5" in signature_file or "ripemd160" in signature_file: self.assertIsInstance(e, InvalidInput) #with self.assertRaisesRegexp(InvalidInput, "Algorithm .+ is not recognized"): # raise elif "HMACOutputLength" in sig.decode("utf-8"): self.assertIsInstance(e, (InvalidSignature, InvalidDigest)) elif signature_file.endswith("signature-rsa-enveloped-bad-digest-val.xml"): #self.assertIsInstance(e, InvalidDigest) self.assertIsInstance(e, InvalidCertificate) elif signature_file.endswith("signature-rsa-detached-xslt-transform-bad-retrieval-method.xml"): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith("signature-rsa-enveloped-bad-sig.xml"): self.assertIsInstance(e, etree.DocumentInvalid) elif signature_file.endswith("signature-x509-crt.xml"): self.assertIsInstance(e, InvalidCertificate) elif signature_file.endswith("signature-keyname.xml"): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith("signature-x509-sn.xml"): self.assertIsInstance(e, InvalidInput) elif signature_file.endswith("signature-x509-crt-crl.xml"): self.assertIsInstance(e, InvalidCertificate) elif signature_file.endswith("signature-retrievalmethod-rawx509crt.xml"): self.assertIsInstance(e, InvalidInput) elif any(x in signature_file for x in unsupported_cases) or "EntitiesForbidden" in str(e): print("Unsupported test case:", type(e), e) elif any(x in signature_file for x in todo_cases) or "Unable to resolve reference" in str(e): print("IGNORED test case:", type(e), e) elif "certificate has expired" in str(e) and ("signature-dsa" in signature_file or "signature-rsa" in signature_file): print("IGNORED:", type(e), e) else: raise
def get_x509_cert(signature_file): with open( os.path.join(os.path.dirname(__file__), "keys", "p256-cert.der"), "rb") as fh: return fh.read()