Source code for satcfdi.create.w3.signature

import base64
import hashlib

from lxml import etree

from .ds import SignatureValueType, KeyInfoType, CanonicalizationMethodType, SignatureMethodType, ReferenceType, TransformsType, TransformType, \
    DigestMethodType, X509DataType, X509IssuerSerialType, SignedInfo, Signature
from .. import Signer
from ... import XElement


def _tobytes(element: etree.Element, exclusive=True) -> bytes:
    return etree.tostring(element, method='c14n', exclusive=exclusive)


def _digest(element: etree.Element, exclusive=True) -> str:
    element_digest = hashlib.sha1(
        _tobytes(element, exclusive)
    ).digest()
    return base64.b64encode(element_digest).decode()


[docs]def signature_c14n_sha1(signer: Signer, element: etree.Element, nsmap=None) -> XElement: digest = _digest(element, exclusive=False) signed_info = SignedInfo( canonicalization_method=CanonicalizationMethodType( algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315", ), signature_method=SignatureMethodType( algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" ), reference=ReferenceType( uri="", transforms=TransformsType( transform=TransformType( algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" ) ), digest_method=DigestMethodType( algorithm="http://www.w3.org/2000/09/xmldsig#sha1" ), digest_value=digest ) ) signed_info["_nsmap"] = nsmap signature = Signature( signed_info=signed_info, signature_value=SignatureValueType( signer.sign_sha1( _tobytes(signed_info.to_xml(), exclusive=False) ) ), key_info=KeyInfoType( x509data=X509DataType( x509issuer_serial=X509IssuerSerialType( x509issuer_name=signer.issuer(), x509serial_number=signer.serial_number ), x509certificate=signer.certificate_base64() ) ) ) signature["_nsmap"] = nsmap return signature