se cambian parametros a DianXMLExtensionSigner
facho/cli.py: generate permite firmar directamente FossilOrigin-Name: 23efe2dc5ae9df524963c927c5b461882f864008efbf25fd8677772ac8431cb1
This commit is contained in:
parent
86a9364c69
commit
a917258cee
@ -228,8 +228,9 @@ def sign_xml(private_key, passphrase, xmlfile, ssl=True):
|
|||||||
@click.option('--generate/--validate', default=False)
|
@click.option('--generate/--validate', default=False)
|
||||||
@click.option('--passphrase')
|
@click.option('--passphrase')
|
||||||
@click.option('--ssl/--no-ssl', default=False)
|
@click.option('--ssl/--no-ssl', default=False)
|
||||||
|
@click.option('--sign/--no-sign', default=False)
|
||||||
@click.argument('scriptname', type=click.Path(exists=True), required=True)
|
@click.argument('scriptname', type=click.Path(exists=True), required=True)
|
||||||
def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=True):
|
def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=True, sign=False):
|
||||||
"""
|
"""
|
||||||
imprime xml en pantalla.
|
imprime xml en pantalla.
|
||||||
SCRIPTNAME espera
|
SCRIPTNAME espera
|
||||||
@ -263,6 +264,10 @@ def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=Tr
|
|||||||
for extension in extensions:
|
for extension in extensions:
|
||||||
xml.add_extension(extension)
|
xml.add_extension(extension)
|
||||||
|
|
||||||
|
if sign:
|
||||||
|
signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase)
|
||||||
|
xml.add_extension(signer)
|
||||||
|
|
||||||
print(xml.tostring(xml_declaration=True))
|
print(xml.tostring(xml_declaration=True))
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# this repository contains the full copyright notices and license terms.
|
# this repository contains the full copyright notices and license terms.
|
||||||
|
|
||||||
from ..facho import FachoXML, FachoXMLExtension, LXMLBuilder
|
from ..facho import FachoXML, FachoXMLExtension, LXMLBuilder
|
||||||
|
import uuid
|
||||||
import xmlsig
|
import xmlsig
|
||||||
import xades
|
import xades
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -178,7 +179,7 @@ class DianXMLExtensionSoftwareSecurityCode(FachoXMLExtension):
|
|||||||
class DianXMLExtensionSigner(FachoXMLExtension):
|
class DianXMLExtensionSigner(FachoXMLExtension):
|
||||||
# RESOLUCION 0001: pagina 516
|
# RESOLUCION 0001: pagina 516
|
||||||
POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf'
|
POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf'
|
||||||
POLICY_NAME = 'Dian'
|
POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.'
|
||||||
|
|
||||||
def __init__(self, pkcs12_path, passphrase=None):
|
def __init__(self, pkcs12_path, passphrase=None):
|
||||||
self._pkcs12_path = pkcs12_path
|
self._pkcs12_path = pkcs12_path
|
||||||
@ -192,20 +193,34 @@ class DianXMLExtensionSigner(FachoXMLExtension):
|
|||||||
|
|
||||||
def sign_xml_string(self, document):
|
def sign_xml_string(self, document):
|
||||||
xml = LXMLBuilder.from_string(document)
|
xml = LXMLBuilder.from_string(document)
|
||||||
|
signature = self.sign_xml_element(xml)
|
||||||
|
|
||||||
|
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')
|
||||||
|
fachoxml.append_element(extcontent, signature)
|
||||||
|
|
||||||
|
return fachoxml.tostring()
|
||||||
|
|
||||||
|
def sign_xml_element(self, xml):
|
||||||
signature = xmlsig.template.create(
|
signature = xmlsig.template.create(
|
||||||
xmlsig.constants.TransformInclC14N,
|
xmlsig.constants.TransformInclC14N,
|
||||||
xmlsig.constants.TransformRsaSha256,
|
xmlsig.constants.TransformRsaSha256,
|
||||||
"Signature",
|
"Signature",
|
||||||
)
|
)
|
||||||
|
id_uuid = str(uuid.uuid4())
|
||||||
|
|
||||||
ref = xmlsig.template.add_reference(
|
ref = xmlsig.template.add_reference(
|
||||||
signature, xmlsig.constants.TransformSha256, uri="", name="R1"
|
signature, xmlsig.constants.TransformSha256, uri="", name="xmldsig-%s-ref0" % (id_uuid)
|
||||||
)
|
)
|
||||||
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
|
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
|
||||||
|
|
||||||
|
id_keyinfo = "%s-KeyInfo" % (id_uuid)
|
||||||
xmlsig.template.add_reference(
|
xmlsig.template.add_reference(
|
||||||
signature, xmlsig.constants.TransformSha256, uri="#KI", name="RKI"
|
signature, xmlsig.constants.TransformSha256, uri="#%s" % (id_keyinfo),
|
||||||
)
|
)
|
||||||
ki = xmlsig.template.ensure_key_info(signature, name="KI")
|
ki = xmlsig.template.ensure_key_info(signature, name=id_keyinfo)
|
||||||
data = xmlsig.template.add_x509_data(ki)
|
data = xmlsig.template.add_x509_data(ki)
|
||||||
xmlsig.template.x509_data_add_certificate(data)
|
xmlsig.template.x509_data_add_certificate(data)
|
||||||
serial = xmlsig.template.x509_data_add_issuer_serial(data)
|
serial = xmlsig.template.x509_data_add_issuer_serial(data)
|
||||||
@ -216,12 +231,20 @@ class DianXMLExtensionSigner(FachoXMLExtension):
|
|||||||
xmlsig.template.add_key_value(ki)
|
xmlsig.template.add_key_value(ki)
|
||||||
qualifying = xades.template.create_qualifying_properties(signature)
|
qualifying = xades.template.create_qualifying_properties(signature)
|
||||||
xades.utils.ensure_id(qualifying)
|
xades.utils.ensure_id(qualifying)
|
||||||
xades.utils.ensure_id(qualifying)
|
|
||||||
|
|
||||||
# TODO assert with http://www.sic.gov.co/hora-legal-colombiana
|
# 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 = xades.template.create_signed_properties(qualifying, datetime=datetime.now())
|
||||||
|
props.set('Id', id_props)
|
||||||
xades.template.add_claimed_role(props, "supplier")
|
xades.template.add_claimed_role(props, "supplier")
|
||||||
|
|
||||||
|
|
||||||
|
props_ref = xmlsig.template.add_reference(
|
||||||
|
props, xmlsig.constants.TransformSha256, uri="#%s" % (id_props),
|
||||||
|
)
|
||||||
|
props_ref.set('Type', "http://uri.etsi.org/01903#SignedProperties")
|
||||||
|
xmlsig.template.add_transform(props_ref, xmlsig.constants.TransformEnveloped)
|
||||||
|
|
||||||
xml.append(signature)
|
xml.append(signature)
|
||||||
|
|
||||||
policy = xades.policy.GenericPolicyId(
|
policy = xades.policy.GenericPolicyId(
|
||||||
@ -236,20 +259,15 @@ class DianXMLExtensionSigner(FachoXMLExtension):
|
|||||||
ctx.verify(signature)
|
ctx.verify(signature)
|
||||||
#xmlsig take parent root
|
#xmlsig take parent root
|
||||||
xml.remove(signature)
|
xml.remove(signature)
|
||||||
|
return signature
|
||||||
|
|
||||||
fachoxml = FachoXML(xml,nsmap=NAMESPACES)
|
# return (xpath, xml.Element)
|
||||||
|
def build(self, fachoxml):
|
||||||
|
signature = self.sign_xml_element(fachoxml.root)
|
||||||
#DIAN 1.7.-2020: FAB01
|
#DIAN 1.7.-2020: FAB01
|
||||||
ublextension = fachoxml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True)
|
ublextension = fachoxml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True)
|
||||||
extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent')
|
extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent')
|
||||||
fachoxml.append_element(extcontent, signature)
|
fachoxml.append_element(extcontent, signature)
|
||||||
return fachoxml.tostring()
|
|
||||||
|
|
||||||
# return (xpath, xml.Element)
|
|
||||||
def build(self, fachoxml):
|
|
||||||
xmlsigned = self.sign_xml_string(fachoxml.tostring())
|
|
||||||
xml = LXMLBuilder.from_string(xmlsigned)
|
|
||||||
fachoxml.root = xml
|
|
||||||
return fachoxml
|
|
||||||
|
|
||||||
|
|
||||||
class DianXMLExtensionAuthorizationProvider(FachoXMLExtension):
|
class DianXMLExtensionAuthorizationProvider(FachoXMLExtension):
|
||||||
|
Loading…
Reference in New Issue
Block a user