From 5479adbaca8e9d66cab07883917788e804dc9b90 Mon Sep 17 00:00:00 2001 From: "bit4bit@riseup.net" Date: Sun, 18 Oct 2020 03:10:32 +0000 Subject: [PATCH] ZE02 se tiro MACHETE, se retira el Signature/Reference a signedprops ya que no es validado ni por la dian ni por https://tools.chilkat.io/xmlDsigVerify.cshtml, pero si no se envia la dian recibe el documento. FossilOrigin-Name: efbd56aa2b5dc69918578eea610540e828e1e57296cb53d2ef7b7ca8e11a178d --- facho/cli.py | 8 ++++---- facho/fe/fe.py | 39 ++++++++++++++++++++++----------------- facho/fe/form.py | 4 ++++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/facho/cli.py b/facho/cli.py index 3c151b1..8d81df0 100644 --- a/facho/cli.py +++ b/facho/cli.py @@ -270,12 +270,12 @@ def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=Tr for extension in extensions: xml.add_extension(extension) + xmlstring = xml.tostringMACHETE(xml_declaration=True) if sign: signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) - xml.add_extension(signer) - - print(xml.tostring(xml_declaration=True)) - + print(signer.sign_xml_string(xmlstring.encode('utf-8'))) + else: + print(xmlstring) @click.group() def main(): diff --git a/facho/fe/fe.py b/facho/fe/fe.py index 4619122..30e8bc5 100644 --- a/facho/fe/fe.py +++ b/facho/fe/fe.py @@ -48,7 +48,7 @@ class FeXML(FachoXML): #self.find_or_create_element(self._cn) # MACHETE se elimina xml namespace fe - def tostring(self, **kw): + def tostringMACHETE(self, **kw): return super().tostring(**kw)\ .replace("fe:", "")\ .replace("xmlns:fe", "xmlns") @@ -181,6 +181,7 @@ class DianXMLExtensionSigner(FachoXMLExtension): POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf' POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.' + def __init__(self, pkcs12_path, passphrase=None, mockpolicy=False): self._pkcs12_path = pkcs12_path self._passphrase = None @@ -198,20 +199,20 @@ class DianXMLExtensionSigner(FachoXMLExtension): fachoxml = FachoXML(xml,nsmap=NAMESPACES) #DIAN 1.7.-2020: FAB01 - ublextension = fachoxml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) - extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent') + extcontent = fachoxml.builder.xpath(fachoxml.root, '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') fachoxml.append_element(extcontent, signature) - return fachoxml.tostring() + return fachoxml.tostring(xml_declaration=True) def sign_xml_element(self, xml): + id_uuid = str(uuid.uuid4()) signature = xmlsig.template.create( xmlsig.constants.TransformInclC14N, xmlsig.constants.TransformRsaSha256, - "Signature", + "xmlsig-%s" % (id_uuid), ) xml.append(signature) - id_uuid = str(uuid.uuid4()) + ref = xmlsig.template.add_reference( signature, xmlsig.constants.TransformSha256, uri="", name="xmldsig-%s-ref0" % (id_uuid) @@ -231,18 +232,22 @@ class DianXMLExtensionSigner(FachoXMLExtension): qualifying = xades.template.create_qualifying_properties(signature) xades.utils.ensure_id(qualifying) - # TODO assert with http://www.sic.gov.co/hora-legal-colombiana + id_props = "xmldsig-%s-signedprops" % (id_uuid) - props = xades.template.create_signed_properties(qualifying, datetime=datetime.now()) - props.set('Id', id_props) - xades.template.add_claimed_role(props, "supplier") - + # MACHETE si no lo envio la dian no lo valida y pasa + # si lo adiciono https://tools.chilkat.io/xmlDsigVerify.cshtml + # falla en validar este reference.. - props_ref = xmlsig.template.add_reference( - signature, xmlsig.constants.TransformSha256, uri="#%s" % (id_props), - uri_type="http://uri.etsi.org/01903#SignedProperties" - ) + #props_ref = xmlsig.template.add_reference( + # signature, xmlsig.constants.TransformSha256, uri="#%s" % (id_props), + # uri_type="http://uri.etsi.org/01903#SignedProperties" + #) + #xmlsig.template.add_transform(props_ref, xmlsig.constants.TransformInclC14N) + # TODO assert with http://www.sic.gov.co/hora-legal-colombiana + props = xades.template.create_signed_properties(qualifying, name=id_props, datetime=datetime.now()) + xades.template.add_claimed_role(props, "supplier") + policy = xades.policy.GenericPolicyId( self.POLICY_ID, self.POLICY_NAME, @@ -275,10 +280,10 @@ class DianXMLExtensionSigner(FachoXMLExtension): # return (xpath, xml.Element) def build(self, fachoxml): + raise RuntimeError("no funciona correctamente habria que modificar todo para funcionar sin el namespace fe:") signature = self.sign_xml_element(fachoxml.root) #DIAN 1.7.-2020: FAB01 - ublextension = fachoxml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) - extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent') + extcontent = fachoxml.builder.xpath(fachoxml.root, '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') fachoxml.append_element(extcontent, signature) diff --git a/facho/fe/form.py b/facho/fe/form.py index 77f2761..bcf7a29 100644 --- a/facho/fe/form.py +++ b/facho/fe/form.py @@ -342,6 +342,10 @@ class DIANInvoiceXML(fe.FeXML): def __init__(self, invoice): super().__init__('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') + + # ZE02 se requiere existencia para firmar + ublextension = self.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) + extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent') self.attach_invoice(invoice) def set_supplier(fexml, invoice):