Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] add sign method for RPS additional sign for NFS-e Paulistana #47

Merged
merged 5 commits into from
May 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions src/erpbrasil/assinatura/assinatura.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@
_logger = logging.getLogger(__name__)


class XMLSignerWithSHA1(signxml.XMLSigner):
"""
Extension of the `XMLSigner` class that adds support for the SHA1 hash algorithm
to the XML signature process.
Note:
SHA1-based algorithms are not supported in the default configuration because
they are not secure, but in the NF-e project, other more modern algorithms
are still not accepted.
"""
def check_deprecated_methods(self):
"Override to disable deprecated Check"


class Assinatura(object):

def __init__(self, certificado):
Expand Down Expand Up @@ -48,14 +61,15 @@ def assina_xml2(self, xml_element, reference, getchildren=False):
if element.text is not None and not element.text.strip():
element.text = None

signer = signxml.XMLSigner(
signer = XMLSignerWithSHA1(
method=signxml.methods.enveloped,
signature_algorithm="rsa-sha1",
digest_algorithm='sha1',
c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
)

signer.namespaces = {"ds": "http://www.w3.org/2000/09/xmldsig#"}
signer.excise_empty_xmlns_declarations = True
signer.namespaces = {None: signxml.namespaces.ds}

ref_uri = ('#%s' % reference) if reference else None

Expand Down Expand Up @@ -91,7 +105,7 @@ def assina_xml2(self, xml_element, reference, getchildren=False):

def assina_nfse(self, xml_etree):

signer = signxml.XMLSigner(
signer = XMLSignerWithSHA1(
method=signxml.methods.enveloped,
signature_algorithm="rsa-sha1",
digest_algorithm='sha1',
Expand All @@ -103,11 +117,8 @@ def assina_nfse(self, xml_etree):
key=self.chave_privada,
cert=self.cert,
)

signed_root = etree.tostring(signed_root, encoding=str)

signed_root = signed_root.replace('\r', '').replace('\n', '')

return signed_root

def assina_string(self, message):
Expand All @@ -122,6 +133,27 @@ def assina_string(self, message):
)
return signature


def sign_pkcs1v15_sha1(self, data):
"""
Sign data using PKCS1v15 padding and SHA1 hash algorithm.

This method is specifically tailored for the NFSe Paulistana RPS signing process.

Args:
data (bytes): Data to be signed.

Returns:
bytes: Generated signature.
"""
private_key = self.certificado.key
signature = private_key.sign(
data,
padding.PKCS1v15(),
hashes.SHA1()
)
return signature

def assina_pdf(self, arquivo, dados_assinatura, algoritmo='sha256'):
try:
from endesive import pdf
Expand Down