From c254ab71eaaaa89dc1fafbbdffa11b11a2892f03 Mon Sep 17 00:00:00 2001 From: Mackilem Date: Fri, 17 Jul 2020 17:22:20 -0300 Subject: [PATCH] =?UTF-8?q?altera=C3=A7=C3=A3o=20do=20m=C3=A9todo=20assina?= =?UTF-8?q?=5Fxml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytrustnfe/nfse/assinatura.py | 71 ++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/pytrustnfe/nfse/assinatura.py b/pytrustnfe/nfse/assinatura.py index 44b3e7a..cdfe64e 100644 --- a/pytrustnfe/nfse/assinatura.py +++ b/pytrustnfe/nfse/assinatura.py @@ -2,13 +2,10 @@ # © 2016 Danimar Ribeiro, Trustcode # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import signxml +import os from lxml import etree -import xmlsec -import os.path - -consts = xmlsec.constants - -NAMESPACE_SIG = "http://www.w3.org/2000/09/xmldsig#" +from signxml import XMLSigner class Assinatura(object): @@ -21,36 +18,40 @@ class Assinatura(object): if not os.path.isfile(self.private_key): raise Exception("Caminho do certificado não existe.") - def assina_xml(self, xml, reference): + def assina_xml(self, xml_element, reference, getchildren=False): self._checar_certificado() - template = etree.fromstring(xml) - - key = xmlsec.Key.from_file( - self.private_key, - format=xmlsec.constants.KeyDataFormatPem, - password=self.password, - ) - - signature_node = xmlsec.template.create( - template, - c14n_method=consts.TransformInclC14N, - sign_method=consts.TransformRsaSha1, + cert = self.cert_pem + key = self.password + + for element in xml_element.iter("*"): + if element.text is not None and not element.text.strip(): + element.text = None + + signer = XMLSigner( + method=signxml.methods.enveloped, + signature_algorithm="rsa-sha1", + digest_algorithm="sha1", + c14n_algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315", ) - template.append(signature_node) - ref = xmlsec.template.add_reference( - signature_node, consts.TransformSha1, uri="" - ) - - xmlsec.template.add_transform(ref, consts.TransformEnveloped) - xmlsec.template.add_transform(ref, consts.TransformInclC14N) - - ki = xmlsec.template.ensure_key_info(signature_node) - xmlsec.template.add_x509_data(ki) - ctx = xmlsec.SignatureContext() - ctx.key = key + ns = {} + ns[None] = signer.namespaces["ds"] + signer.namespaces = ns - ctx.key.load_cert_from_file(self.cert_pem, consts.KeyDataFormatPem) - - ctx.sign(signature_node) - return etree.tostring(template, encoding=str) + ref_uri = ("#%s" % reference) if reference else None + signed_root = signer.sign( + xml_element, key=key.encode(), cert=cert.encode(), reference_uri=ref_uri + ) + if reference: + element_signed = signed_root.find(".//*[@Id='%s']" % reference) + signature = signed_root.find( + ".//{http://www.w3.org/2000/09/xmldsig#}Signature" + ) + + if getchildren and element_signed is not None and signature is not None: + child = element_signed.getchildren() + child.append(signature) + elif element_signed is not None and signature is not None: + parent = element_signed.getparent() + parent.append(signature) + return etree.tostring(signed_root, encoding=str)