Fix problem with electronic mail sign.

Task: #065156
This commit is contained in:
Bernat Brunet 2022-09-20 12:29:17 +02:00
parent b478a7d826
commit 99072e3f7b
3 changed files with 52 additions and 21 deletions

View File

@ -452,19 +452,17 @@ class Invoice(metaclass=PoolMeta):
cert_file.close() cert_file.close()
def _sign_file(cert, password, request): def _sign_file(cert, password, request):
# get key and certificates from PCK12 file
( (
private_key, private_key,
certificate, certificate,
additional_certificates, additional_certificates,
) = pkcs12.load_key_and_certificates(cert, password) ) = pkcs12.load_key_and_certificates(cert, password)
# key = private_key.private_bytes(
# encoding=serialization.Encoding.PEM,
# format=serialization.PrivateFormat.PKCS8,
# encryption_algorithm=serialization.NoEncryption(),
# )
# DER is an ASN.1 encoding type # DER is an ASN.1 encoding type
crt = certificate.public_bytes(serialization.Encoding.DER) crt = certificate.public_bytes(serialization.Encoding.DER)
# Set variables values
rand_min = 1 rand_min = 1
rand_max = 99999 rand_max = 99999
signature_id = "Signature%05d" % random.randint(rand_min, rand_max) signature_id = "Signature%05d" % random.randint(rand_min, rand_max)
@ -483,18 +481,32 @@ class Invoice(metaclass=PoolMeta):
".pdf" ".pdf"
) )
sig_policy_hash_value = "Ohixl6upD6av8N7pEvDABhEL6hM=" sig_policy_hash_value = "Ohixl6upD6av8N7pEvDABhEL6hM="
# Get XML file to edit
root = etree.fromstring(request) root = etree.fromstring(request)
# Create a signature template for RSA-SHA1 enveloped signature.
sign = xmlsig.template.create( sign = xmlsig.template.create(
c14n_method=xmlsig.constants.TransformInclC14N, c14n_method=xmlsig.constants.TransformInclC14N,
sign_method=xmlsig.constants.TransformRsaSha1, sign_method=xmlsig.constants.TransformRsaSha1,
name=signature_id, name=signature_id,
ns="ds", ns="ds",
) )
key_info = xmlsig.template.ensure_key_info(sign, name=key_info_id) assert sign is not None
x509_data = xmlsig.template.add_x509_data(key_info)
xmlsig.template.x509_data_add_certificate(x509_data)
xmlsig.template.add_key_value(key_info)
# Add the <ds:Signature/> node to the document.
root.append(sign)
# Add the <ds:Reference/> node to the signature template.
ref = xmlsig.template.add_reference(
sign, xmlsig.constants.TransformSha1, name=reference_id, uri=""
)
# Add the enveloped transform descriptor.
xmlsig.template.add_transform(ref,
xmlsig.constants.TransformEnveloped)
# Add 2 new <ds:Reference/> node to the signature template.
xmlsig.template.add_reference( xmlsig.template.add_reference(
sign, sign,
xmlsig.constants.TransformSha1, xmlsig.constants.TransformSha1,
@ -504,11 +516,20 @@ class Invoice(metaclass=PoolMeta):
xmlsig.template.add_reference( xmlsig.template.add_reference(
sign, xmlsig.constants.TransformSha1, uri="#" + key_info_id sign, xmlsig.constants.TransformSha1, uri="#" + key_info_id
) )
ref = xmlsig.template.add_reference(
sign, xmlsig.constants.TransformSha1, name=reference_id, uri="" # Add the <ds:KeyInfo/> and <ds:KeyName/> nodes.
) key_info = xmlsig.template.ensure_key_info(sign, name=key_info_id)
xmlsig.template.add_transform(ref, x509_data = xmlsig.template.add_x509_data(key_info)
xmlsig.constants.TransformEnveloped) xmlsig.template.x509_data_add_certificate(x509_data)
# Set the certificate values
ctx = xmlsig.SignatureContext()
ctx.private_key = private_key
ctx.x509 = certificate
ctx.ca_certificates = additional_certificates
ctx.public_key = certificate.public_key()
# Set the footer validation
object_node = etree.SubElement( object_node = etree.SubElement(
sign, sign,
etree.QName(xmlsig.constants.DSigNs, "Object"), etree.QName(xmlsig.constants.DSigNs, "Object"),
@ -618,15 +639,25 @@ class Invoice(metaclass=PoolMeta):
etree.SubElement( etree.SubElement(
data_object_format, etree.QName(etsi, "Description") data_object_format, etree.QName(etsi, "Description")
).text = "Factura" ).text = "Factura"
data_object_format_identifier = etree.SubElement(
data_object_format, etree.QName(etsi, "ObjectIdentifier")
)
etree.SubElement(
data_object_format_identifier,
etree.QName(etsi, "Identifier"),
attrib={"Qualifier": "OIDAsURN"}
).text = "urn:oid:1.2.840.10003.5.109.10"
etree.SubElement(
data_object_format_identifier, etree.QName(etsi, "Description")
)
etree.SubElement( etree.SubElement(
data_object_format, etree.QName(etsi, "MimeType") data_object_format, etree.QName(etsi, "MimeType")
).text = "text/xml" ).text = "text/xml"
ctx = xmlsig.SignatureContext()
ctx.x509 = certificate # Sign the file and verify the sign.
ctx.public_key = certificate.public_key()
ctx.private_key = private_key
root.append(sign)
ctx.sign(sign) ctx.sign(sign)
ctx.verify(sign)
return etree.tostring(root, xml_declaration=True, encoding="UTF-8") return etree.tostring(root, xml_declaration=True, encoding="UTF-8")
signed_file_content = _sign_file( signed_file_content = _sign_file(

View File

@ -1,5 +1,5 @@
{% from "template_facturae_macros.xml" import administrative_center, address, contact %}<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> {% from "template_facturae_macros.xml" import administrative_center, address, contact %}<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<namespace:Facturae xmlns:namespace2="http://uri.etsi.org/01903/v1.2.2#" xmlns:namespace3="http://www.w3.org/2000/09/xmldsig#" xmlns:namespace="http://www.facturae.es/Facturae/2014/v3.2.1/Facturae"> <namespace:Facturae xmlns:namespace="http://www.facturae.es/Facturae/2014/v3.2.1/Facturae" xmlns:namespace2="http://uri.etsi.org/01903/v1.2.2#" xmlns:namespace3="http://www.w3.org/2000/09/xmldsig#">
<FileHeader> <FileHeader>
<SchemaVersion>3.2.1</SchemaVersion> <SchemaVersion>3.2.1</SchemaVersion>
<Modality>I</Modality> <Modality>I</Modality>

View File

@ -11,7 +11,7 @@
<!-- Schema for XML Signatures <!-- Schema for XML Signatures
http://www.w3.org/2000/09/xmldsig# http://www.w3.org/2000/09/xmldsig#
$Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $ $Revision: 1.2 $ on $Date: 2013-04-16 12:48:49 $ by $Author: denis $
Copyright 2001 The Internet Society and W3C (Massachusetts Institute Copyright 2001 The Internet Society and W3C (Massachusetts Institute
of Technology, Institut National de Recherche en Informatique et en of Technology, Institut National de Recherche en Informatique et en