(root, certificate)
return signature_value.replace("\n", "")
Sign XML with PKCS #12
        :author: Victor Laskurain <blaskurain@binovo.es>
        :return: SignatureValue
Sign XML with PKCS #12
        :author: Victor Laskurain <blaskurain
Sign XML with PKCS #12 : author : Victor Laskurain <blaskurain
def sign(root, certificate):
        """
        Sign XML with PKCS #12
        :author: Victor Laskurain <blaskurain@binovo.es>
        :return: SignatureValue
        """

        def create_node_tree(root_node, elem_list):
            """Convierte una lista en XML.

            Cada elemento de la lista se interpretará de la siguiente manera:

            Si es un string se añadirá al texto suelto del nodo root.
            Si es una tupla/lista t se interpretará como sigue:
                t[0]  es el nombre del elemento a crear. Puede tener prefijo de espacio
                de nombres.
                t[1]  es la lista de atributos donde las posiciones pares son claves y
                los impares valores.
                t[2:] son los subelementos que se interpretan recursivamente
            """
            for elem_def in elem_list:
                if isinstance(elem_def, str):
                    root_node.text = (root_node.text or "") + elem_def
                else:
                    ns = ""
                    elemname = elem_def[0]
                    attrs = elem_def[1]
                    children = elem_def[2:]
                    if ":" in elemname:
                        ns, elemname = elemname.split(":")
                        ns = root_node.nsmap[ns]
                    node = xmlsig.utils.create_node(elemname, root_node, ns)
                    for attr_name, attr_value in zip(attrs[::2], attrs[1::2]):
                        node.set(attr_name, attr_value)
                    create_node_tree(node, children)

        doc_id = "id-" + str(uuid4())
        signature_id = "sig-" + doc_id
        kinfo_id = "ki-" + doc_id
        sp_id = "sp-" + doc_id
        signature = xmlsig.template.create(
            xmlsig.constants.TransformInclC14N,
            xmlsig.constants.TransformRsaSha256,
            signature_id,
        )
        ref = xmlsig.template.add_reference(
            signature, xmlsig.constants.TransformSha256, uri=""
        )
        xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
        xmlsig.template.add_reference(
            signature, xmlsig.constants.TransformSha256, uri="#" + kinfo_id
        )
        xmlsig.template.add_reference(
            signature, xmlsig.constants.TransformSha256, uri="#" + sp_id
        )
        ki = xmlsig.template.ensure_key_info(signature, name=kinfo_id)
        data = xmlsig.template.add_x509_data(ki)
        xmlsig.template.x509_data_add_certificate(data)
        xmlsig.template.add_key_value(ki)
        ctx = xmlsig.SignatureContext()
        ctx.x509 = certificate[1]
        ctx.public_key = ctx.x509.public_key()
        ctx.private_key = certificate[0]
        dslist = (
            "ds:Object",
            (),
            (
                "etsi:QualifyingProperties",
                ("Target", signature_id),
                (
                    "etsi:SignedProperties",
                    ("Id", sp_id),
                    (
                        "etsi:SignedSignatureProperties",
                        (),
                        ("etsi:SigningTime", (), datetime.now().isoformat()),
                        (
                            "etsi:SigningCertificateV2",
                            (),
                            (
                                "etsi:Cert",
                                (),
                                (
                                    "etsi:CertDigest",
                                    (),
                                    (
                                        "ds:DigestMethod",
                                        (
                                            "Algorithm",
                                            "http://www.w3.org/2000/09/xmldsig#sha256",
                                        ),
                                    ),
                                    (
                                        "ds:DigestValue",
                                        (),
                                        b64encode(
                                            ctx.x509.fingerprint(hashes.SHA256())
                                        ).decode(),
                                    ),
                                ),
                            ),
                        ),
                        (
                            "etsi:SignaturePolicyIdentifier",
                            (),
                            (
                                "etsi:SignaturePolicyId",
                                (),
                                (
                                    "etsi:SigPolicyId",
                                    (),
                                    (
                                        "etsi:Identifier",
                                        (),
                                        "http://ticketbai.eus/politicafirma",
                                    ),
                                    (
                                        "etsi:Description",
                                        (),
                                        "Política de Firma TicketBAI 1.0",
                                    ),
                                ),
                                (
                                    "etsi:SigPolicyHash",
                                    (),
                                    (
                                        "ds:DigestMethod",
                                        (
                                            "Algorithm",
                                            "http://www.w3.org/2000/09/xmldsig#sha256",
                                        ),
                                    ),
                                    (
                                        "ds:DigestValue",
                                        (),
                                        "lX1xDvBVAsPXkkJ7R07WCVbAm9e0H33I1sCpDtQNkbc=",
                                    ),
                                ),
                            ),
                        ),
                    ),
                ),
            ),
        )
        root.append(signature)
        create_node_tree(signature, [dslist])
        ctx.sign(signature)
        signature_value = signature.find(
            "ds:SignatureValue", namespaces=xmlsig.constants.NS_MAP
        ).text
        # RFC2045 - Base64 Content-Transfer-Encoding (page 25)
        # Any characters outside of the base64 alphabet are to be ignored in
        # base64-encoded data.
        return signature_value.replace("\n", "")
def sign ( root , certificate ) : def create_node_tree ( root_node , elem_list ) : """Convierte una lista en XML.

            Cada elemento de la lista se interpretará de la siguiente manera:

            Si es un string se añadirá al texto suelto del nodo root.
            Si es una tupla/lista t se interpretará como sigue:
                t[0]  es el nombre del elemento a crear. Puede tener prefijo de espacio
                de nombres.
                t[1]  es la lista de atributos donde las posiciones pares son claves y
                los impares valores.
                t[2:] son los subelementos que se interpretan recursivamente
            """ for elem_def in elem_list : if isinstance ( elem_def , str ) : root_node . text = ( root_node . text or "" ) + elem_def else : ns = "" elemname = elem_def [ 0 ] attrs = elem_def [ 1 ] children = elem_def [ 2 : ] if ":" in elemname : ns , elemname = elemname . split ( ":" ) ns = root_node . nsmap [ ns ] node = xmlsig . utils . create_node ( elemname , root_node , ns ) for attr_name , attr_value in zip ( attrs [ : : 2 ] , attrs [ 1 : : 2 ] ) : node . set ( attr_name , attr_value ) create_node_tree ( node , children ) doc_id = "id-" + str ( uuid4 ( ) ) signature_id = "sig-" + doc_id kinfo_id = "ki-" + doc_id sp_id = "sp-" + doc_id signature = xmlsig . template . create ( xmlsig . constants . TransformInclC14N , xmlsig . constants . TransformRsaSha256 , signature_id , ) ref = xmlsig . template . add_reference ( signature , xmlsig . constants . TransformSha256 , uri = "" ) xmlsig . template . add_transform ( ref , xmlsig . constants . TransformEnveloped ) xmlsig . template . add_reference ( signature , xmlsig . constants . TransformSha256 , uri = "#" + kinfo_id ) xmlsig . template . add_reference ( signature , xmlsig . constants . TransformSha256 , uri = "#" + sp_id ) ki = xmlsig . template . ensure_key_info ( signature , name = kinfo_id ) data = xmlsig . template . add_x509_data ( ki ) xmlsig . template . x509_data_add_certificate ( data ) xmlsig . template . add_key_value ( ki ) ctx = xmlsig . SignatureContext ( ) ctx . x509 = certificate [ 1 ] ctx . public_key = ctx . x509 . public_key ( ) ctx . private_key = certificate [ 0 ] dslist = ( "ds:Object" , ( ) , ( "etsi:QualifyingProperties" , ( "Target" , signature_id ) , ( "etsi:SignedProperties" , ( "Id" , sp_id ) , ( "etsi:SignedSignatureProperties" , ( ) , ( "etsi:SigningTime" , ( ) , datetime . now ( ) . isoformat ( ) ) , ( "etsi:SigningCertificateV2" , ( ) , ( "etsi:Cert" , ( ) , ( "etsi:CertDigest" , ( ) , ( "ds:DigestMethod" , ( "Algorithm" , "http://www.w3.org/2000/09/xmldsig#sha256" , ) , ) , ( "ds:DigestValue" , ( ) , b64encode ( ctx . x509 . fingerprint ( hashes . SHA256 ( ) ) ) . decode ( ) , ) , ) , ) , ) , ( "etsi:SignaturePolicyIdentifier" , ( ) , ( "etsi:SignaturePolicyId" , ( ) , ( "etsi:SigPolicyId" , ( ) , ( "etsi:Identifier" , ( ) , "http://ticketbai.eus/politicafirma" , ) , ( "etsi:Description" , ( ) , "Política de Firma TicketBAI 1.0", ) , ) , ( "etsi:SigPolicyHash" , ( ) , ( "ds:DigestMethod" , ( "Algorithm" , "http://www.w3.org/2000/09/xmldsig#sha256" , ) , ) , ( "ds:DigestValue" , ( ) , "lX1xDvBVAsPXkkJ7R07WCVbAm9e0H33I1sCpDtQNkbc=" , ) , ) , ) , ) , ) , ) , ) , ) root . append ( signature ) create_node_tree ( signature , [ dslist ] ) ctx . sign ( signature ) signature_value = signature . find ( "ds:SignatureValue" , namespaces = xmlsig . constants . NS_MAP ) . text # RFC2045 - Base64 Content-Transfer-Encoding (page 25) # Any characters outside of the base64 alphabet are to be ignored in # base64-encoded data. return signature_value . replace ( "\n" , "" )