예제 #1
0
 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
예제 #2
0
 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
예제 #3
0
파일: test.py 프로젝트: pombredanne/signxml
    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)
예제 #4
0
    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)
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
    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)
예제 #8
0
파일: test.py 프로젝트: tjeb/signxml
 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())
예제 #9
0
 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)
예제 #10
0
    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
예제 #11
0
 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)
예제 #12
0
파일: test.py 프로젝트: xoe-labs/signxml
 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,
     )
예제 #13
0
 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()))
         ]
예제 #14
0
    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)
예제 #15
0
 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)
예제 #16
0
 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)
예제 #17
0
    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
예제 #18
0
파일: test.py 프로젝트: tjeb/signxml
    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)
예제 #19
0
파일: test.py 프로젝트: tjeb/signxml
    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
예제 #20
0
 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()]
예제 #21
0
    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
예제 #22
0
 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()