From df82fcfba3b0f9793d4a03ca613354189d2e2b0c Mon Sep 17 00:00:00 2001 From: martini97 Date: Tue, 6 Sep 2016 19:16:36 -0300 Subject: [PATCH] =?UTF-8?q?Corre=C3=A7=C3=A3o=20na=20emiss=C3=A3o=20de=20n?= =?UTF-8?q?ota=20fiscal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytrustnfe/nfe/__init__.py | 11 +++++++--- pytrustnfe/nfe/assinatura.py | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index 0c2b0a7..824284b 100644 --- a/pytrustnfe/nfe/__init__.py +++ b/pytrustnfe/nfe/__init__.py @@ -10,6 +10,7 @@ from pytrustnfe.xml import render_xml from pytrustnfe.utils import CabecalhoSoap from pytrustnfe.utils import gerar_chave, ChaveNFe from pytrustnfe.Servidores import localizar_url +import re def _build_header(**kwargs): @@ -31,7 +32,9 @@ def _generate_nfe_id(**kwargs): 'codigo': item['infNFe']['ide']['cNF'], } chave = ChaveNFe(**vals) - item['infNFe']['Id'] = gerar_chave(chave, 'NFe') + chave_nfe = gerar_chave(chave, 'NFe') + item['infNFe']['Id'] = chave_nfe + item['infNFe']['ide']['cDV'] = chave_nfe[len(chave_nfe) - 1:] def _send(certificado, method, **kwargs): @@ -39,13 +42,15 @@ def _send(certificado, method, **kwargs): xml = render_xml(path, '%s.xml' % method, **kwargs) xml = ']>' + xml - + xml = xml.replace('\n', '') pfx_path = certificado.save_pfx() signer = Assinatura(pfx_path, certificado.password) - xml_signed = signer.assina_xml(xml, kwargs['NFes'][0]['infNFe']['Id']) + xml_signed = signer.assina_xml_nota(xml, kwargs['NFes'][0]['infNFe']['Id']) xml_signed = xml_signed.replace( '\n\n]>\n', '') + print xml_signed + xml_signed = xml_signed.replace('\n', '') url = localizar_url(0, 'RS') cabecalho = _build_header(**kwargs) diff --git a/pytrustnfe/nfe/assinatura.py b/pytrustnfe/nfe/assinatura.py index 81831fc..ad531b0 100644 --- a/pytrustnfe/nfe/assinatura.py +++ b/pytrustnfe/nfe/assinatura.py @@ -86,3 +86,54 @@ class Assinatura(object): finally: doc_xml.freeDoc() # self._finalizar_cripto() + + def assina_xml_nota(self, xml, reference): + self._checar_certificado() + self._inicializar_cripto() + try: + doc_xml = libxml2.parseMemory( + xml, len(xml)) + signNode = xmlsec.TmplSignature(doc_xml, + xmlsec.transformInclC14NId(), + xmlsec.transformRsaSha1Id(), None) + doc_xml.getRootElement().get_last().addChild(signNode) + refNode = signNode.addReference(xmlsec.transformSha1Id(), + None, '#' + str(reference), None) + + refNode.addTransform(xmlsec.transformEnvelopedId()) + refNode.addTransform(xmlsec.transformInclC14NId()) + keyInfoNode = signNode.ensureKeyInfo() + keyInfoNode.addX509Data() + + dsig_ctx = xmlsec.DSigCtx() + chave = xmlsec.cryptoAppKeyLoad(filename=str(self.arquivo), + format=xmlsec.KeyDataFormatPkcs12, + pwd=str(self.senha), + pwdCallback=None, + pwdCallbackCtx=None) + + dsig_ctx.signKey = chave + dsig_ctx.sign(signNode) + + status = dsig_ctx.status + dsig_ctx.destroy() + + if status != xmlsec.DSigStatusSucceeded: + raise RuntimeError( + 'Erro ao realizar a assinatura do arquivo; status: "' + + str(status) + + '"') + + xpath = doc_xml.xpathNewContext() + xpath.xpathRegisterNs('sig', NAMESPACE_SIG) + certificados = xpath.xpathEval( + '//sig:X509Data/sig:X509Certificate') + for i in range(len(certificados) - 1): + certificados[i].unlinkNode() + certificados[i].freeNode() + + xml = doc_xml.serialize() + return xml + finally: + doc_xml.freeDoc() + # self._finalizar_cripto()