Skip to content

Commit

Permalink
Merge pull request #26 from akretion/remove-xmlsec
Browse files Browse the repository at this point in the history
Remove xmlsec
  • Loading branch information
renatonlima authored Mar 11, 2022
2 parents 5df1234 + 7c8cfca commit 8ec6f16
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.2.0
current_version = 1.3.0
commit = True
tag = True

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ Overview
:alt: PyPI Package latest release
:target: https://erpbrasilassinatura.readthedocs.io/en/latest/

.. |commits-since| image:: https://img.shields.io/github/commits-since/erpbrasil/erpbrasil.assinatura/v1.2.0...svg
.. |commits-since| image:: https://img.shields.io/github/commits-since/erpbrasil/erpbrasil.assinatura/v1.3.0...svg
:alt: Commits since latest release
:target: https://github.com/erpbrasil/erpbrasil.assinatura/compare/v1.2.0...master
:target: https://github.com/erpbrasil/erpbrasil.assinatura/compare/v1.3.0...master

.. |wheel| image:: https://img.shields.io/pypi/wheel/erpbrasil.assinatura.svg
:alt: PyPI Wheel
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
year = '2019'
author = 'Luis Felipe Mileo'
copyright = '{0}, {1}'.format(year, author)
version = release = '1.2.0'
version = release = '1.3.0'

pygments_style = 'trac'
templates_path = ['.']
Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pyopenssl==19.1.0
pytz>=2016.7
signxml==2.8.1
cryptography==3.3.2
signxml==2.8.2
pycrypto==2.6.1
endesive==2.0.1
chardet==3.0.4
xmlsec==1.3.8
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def read(*names, **kwargs):

setup(
name='erpbrasil.assinatura',
version='1.2.0',
version='1.3.0',
license='MIT license',
description='Assinatura de documentos com certificados digitais A1 e A3',
long_description='%s\n%s' % (
Expand Down
2 changes: 1 addition & 1 deletion src/erpbrasil/assinatura/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.2.0'
__version__ = '1.3.0'

from erpbrasil.assinatura.assinatura import Assinatura # noqa: F401
from erpbrasil.assinatura.certificado import Certificado # noqa: F401
141 changes: 60 additions & 81 deletions src/erpbrasil/assinatura/assinatura.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# coding=utf-8

from base64 import b64encode

import signxml
import xmlsec
from base64 import b64encode
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from endesive import pdf
from endesive import signer
from endesive import xades
from lxml import etree
from OpenSSL import crypto
from xmlsec import constants as consts
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5
from hashlib import sha1


class Assinatura(object):
Expand All @@ -22,6 +19,31 @@ def __init__(self, certificado):
self.chave_privada = certificado._chave
self.senha = certificado._senha

@classmethod
def digest(self, text):
hasher = sha1()
hasher.update(str(text).encode('utf-8'))
digest = hasher.digest()
return b64encode(digest).decode('utf-8')

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

root = etree.fromstring(arquivo)

signed_root = signer.sign(
root,
key=self.certificado.key,
cert=self.certificado._cert,
)

return etree.tostring(signed_root)

def assina_xml2(self, xml_element, reference, getchildren=False):
for element in xml_element.iter("*"):
if element.text is not None and not element.text.strip():
Expand Down Expand Up @@ -70,83 +92,26 @@ def assina_xml2(self, xml_element, reference, getchildren=False):
parent.append(signature)
return etree.tostring(signed_root, encoding=str)

def _checar_certificado(self):
if not self.chave_privada:
raise Exception("Certificado não existe.")

def assina_nfse(self, template):
self._checar_certificado()

key = xmlsec.Key.from_memory(
self.chave_privada,
format=xmlsec.constants.KeyDataFormatPem,
password=self.senha,
)

signature_node = xmlsec.template.create(
template,
c14n_method=consts.TransformInclC14N,
sign_method=consts.TransformRsaSha1,
)
template.append(signature_node)
ref = xmlsec.template.add_reference(
signature_node, consts.TransformSha1, uri=""
)

xmlsec.template.add_transform(ref, consts.TransformEnveloped)
xmlsec.template.add_transform(ref, consts.TransformInclC14N)

ki = xmlsec.template.ensure_key_info(signature_node)
xmlsec.template.add_x509_data(ki)

ctx = xmlsec.SignatureContext()
ctx.key = key
def assina_nfse(self, xml_etree):

ctx.key.load_cert_from_memory(self.cert,
consts.KeyDataFormatPem)

ctx.sign(signature_node)
return etree.tostring(template, encoding=str)

def assina_pdf(self, arquivo, dados_assinatura, altoritimo='sha256'):
return pdf.cms.sign(
datau=arquivo,
udct=dados_assinatura,
key=self.certificado.key,
cert=self.certificado.cert,
othercerts=self.certificado.othercerts,
algomd=altoritimo
signer = signxml.XMLSigner(
method=signxml.methods.enveloped,
signature_algorithm="rsa-sha1",
digest_algorithm='sha1',
c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
)

@staticmethod
def verifica_pdf(arquivo, certificados_de_confianca):
return pdf.verify(
data=arquivo,
trusted_cert_pems=certificados_de_confianca
signed_root = signer.sign(
xml_etree,
key=self.chave_privada,
cert=self.cert,
)

def assina_xml(self, arquivo):
def signproc(tosign, algosig):
key = self.certificado.key
signed_value_signature = key.sign(
tosign,
padding.PKCS1v15(),
getattr(hashes, algosig.upper())()
)
return signed_value_signature
signed_root = etree.tostring(signed_root, encoding=str)

cert = self.certificado.cert
certcontent = signer.cert2asn(cert).dump()
signed_root = signed_root.replace('\r', '').replace('\n', '')

cls = xades.BES()
doc = cls.enveloping(
'documento.xml', arquivo, 'application/xml',
cert, certcontent, signproc, False, True
)

return etree.tostring(
doc, encoding='UTF-8', xml_declaration=True, standalone=False
)
return signed_root

def assina_string(self, message):
private_key = self.certificado.key
Expand All @@ -160,10 +125,24 @@ def assina_string(self, message):
)
return signature

def assina_pdf(self, arquivo, dados_assinatura, algoritmo='sha256'):
return pdf.cms.sign(
datau=arquivo,
udct=dados_assinatura,
key=self.certificado.key,
cert=self.certificado.cert,
othercerts=self.certificado.othercerts,
algomd=algoritmo
)

def assina_tag(self, message):
chave_privada = self.certificado._pkcs12.get_privatekey()
assianado = crypto.sign(chave_privada, message, "SHA1")
return b64encode(assianado).decode()
privateKeyContent = (self.certificado._chave).decode('utf-8')
message = message.encode('utf-8')
message = SHA.new(message)
rsaKey = RSA.importKey(privateKeyContent)
signer = PKCS1_v1_5.new(rsaKey)
signature = signer.sign(message)
return b64encode(signature).decode()

def verificar_assinatura_string(self, message, signature):
public_key = self.certificado.key.public_key()
Expand Down

0 comments on commit 8ec6f16

Please sign in to comment.