示例#1
0
    def check_document_signature(self, source, path):
        """ Digital signature validation.

            References:
                SMPTE ST 429-7:2006 6.13
                SMPTE ST 429-8:2007 5.10
                IETF RFC 3275
                IETF RFC 4051
        """
        # Check digest (XML document hash)
        signed_info = source['Signature']['SignedInfo']
        xml_digest = signed_info['Reference']['DigestValue']
        c14n_doc = canonicalize_xml(path,
                                    ns=DCP_SETTINGS['xmlns']['xmldsig'],
                                    strip='{*}Signature')

        c14n_digest = base64.b64encode(self.digest_func(c14n_doc).digest())
        c14n_digest = c14n_digest.decode("utf-8")
        if xml_digest != c14n_digest:
            self.error("XML Digest mismatch, signature can't be checked")

        # Check signature (XML document hash encrypted with certifier
        # private key)
        c14n_sign = canonicalize_xml(path,
                                     root='SignedInfo',
                                     ns=DCP_SETTINGS['xmlns']['xmldsig'])

        xml_sig = ''.join(source['Signature']['SignatureValue'].split('\n'))
        xml_sig = base64.b64decode(xml_sig)

        try:
            crypto.verify(self.cert_list[-1], xml_sig, c14n_sign,
                          self.sig_algorithm_map[self.dcp.schema])
        except crypto.Error as e:
            self.error("Signature validation failed")
示例#2
0
    def check_document_signature(self, source, path):
        """ Digital signature validation. """
        signed_info = source['Signature']['SignedInfo']
        xml_digest = signed_info['Reference']['DigestValue']
        c14n_doc = canonicalize_xml(
            path,
            ns=DCP_SETTINGS['xmlns']['xmldsig'])

        # We need to remove Signature node from the canonicalized XML
        # Note : If we do it with etree before canonicalization, we miss a \n
        # in the canonicalized form and the digest don't match !
        # Note 2 : why does the \n characters make a difference with C14n ?
        c14n_doc = c14n_doc.decode("utf-8")
        s = re.compile(
            r'<(ds|dsig):Signature xmlns:(ds|dsig)="{}">.*</(ds|dsig):Signature>'
            .format(DCP_SETTINGS['xmlns']['xmldsig']),
            re.DOTALL)
        c14n_doc = re.sub(s, '', c14n_doc)
        c14n_doc = c14n_doc.encode("utf-8")

        c14n_digest = base64.b64encode(self.digest_func(c14n_doc).digest())
        c14n_digest = c14n_digest.decode("utf-8")
        if xml_digest != c14n_digest:
            raise CheckException(
                "XML Digest mismatch, signature can't be checked")

        # Check SignatureValue
        c14n_sign = canonicalize_xml(
            path,
            root='SignedInfo',
            ns=DCP_SETTINGS['xmlns']['xmldsig'])

        xml_sig = ''.join(source['Signature']['SignatureValue'].split('\n'))
        xml_sig = base64.b64decode(xml_sig)

        try:
            crypto.verify(
                self.cert_list[-1],
                xml_sig,
                c14n_sign,
                self.sig_algorithm_map[self.dcp.schema])
        except crypto.Error as e:
            raise CheckException("Signature validation failed")