# -*- coding: utf-8 -*- # © 2016 Danimar Ribeiro, Trustcode # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from lxml import etree import xmlsec import os.path consts = xmlsec.constants NAMESPACE_SIG = "http://www.w3.org/2000/09/xmldsig#" class Assinatura(object): def __init__(self, cert_pem, private_key, password): self.cert_pem = cert_pem self.private_key = private_key self.password = password def _checar_certificado(self): if not os.path.isfile(self.private_key): raise Exception("Caminho do certificado não existe.") def assina_xml(self, xml, reference): 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, ) 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 ctx.key.load_cert_from_file(self.cert_pem, consts.KeyDataFormatPem) ctx.sign(signature_node) return etree.tostring(template, encoding=str)