Skip to content

Commit

Permalink
Merge pull request #32 from Engenere/create-fake-certificate
Browse files Browse the repository at this point in the history
  • Loading branch information
renatonlima authored Mar 22, 2022
2 parents e47223e + 1c03c8a commit ad147b0
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/erpbrasil/assinatura/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

from erpbrasil.assinatura.assinatura import Assinatura # noqa: F401
from erpbrasil.assinatura.certificado import Certificado # noqa: F401
from erpbrasil.assinatura.misc import * # noqa: F401,F403
1 change: 1 addition & 0 deletions src/erpbrasil/assinatura/certificado.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def _encode_senha(self, senha):
else:
return senha


class ArquivoCertificado(object):
""" Classe para ser utilizada quando for necessário salvar o arquivo
temporariamente, garantindo a segurança que o mesmo sera salvo e apagado
Expand Down
85 changes: 85 additions & 0 deletions src/erpbrasil/assinatura/misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""
Miscellaneous tools for Assinatura.
"""
import datetime
from base64 import b64encode
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import BestAvailableEncryption
from cryptography.hazmat.primitives.serialization.pkcs12 import (
serialize_key_and_certificates,
)
from cryptography.x509.oid import NameOID


def create_fake_certificate_file(valid, passwd, issuer, country, subject):
"""Creating a fake certificate
This certificate is useful to be used in test cases,
it is not valid to test the transmission of 'Notas Fiscais' in the homologation environment.
:param valid: True or False
:param passwd: Some password
:param issuer: Some string, like EMISSOR A TESTE
:param country: Some country: BR
:param subject: Some string: CERTIFICADO VALIDO TESTE
:return: base64 file
"""
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)

public_key = private_key.public_key()
builder = x509.CertificateBuilder()

builder = builder.subject_name(
x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, subject),
x509.NameAttribute(NameOID.COUNTRY_NAME, country),
]
)
)

builder = builder.issuer_name(
x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, issuer),
x509.NameAttribute(NameOID.COUNTRY_NAME, country),
]
)
)

one_year = datetime.timedelta(365, 0, 0)
today = datetime.datetime.today()

if valid:
time_before = today
time_after = today + one_year
else:
time_before = today - one_year
time_after = today

builder = builder.not_valid_before(time_before)
builder = builder.not_valid_after(time_after)

builder = builder.serial_number(2009)

builder = builder.public_key(public_key)

certificate = builder.sign(
private_key=private_key,
algorithm=hashes.MD5(),
)

p12 = serialize_key_and_certificates(
name=subject.encode(),
key=private_key,
cert=certificate,
cas=None,
encryption_algorithm=BestAvailableEncryption(passwd.encode()),
)

return b64encode(p12)
4 changes: 2 additions & 2 deletions tests/test_erpbrasil_assinatura_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_assinatura_nfe_pdf():
}

try:
from endesive import pdf
from endesive import pdf # noqa: F401
except ImportError:
_logger.info(
"skipping test because https://github.com/m32/endesive"
Expand Down Expand Up @@ -73,7 +73,7 @@ def test_assinatura_multipla_pdf():
}

try:
from endesive import pdf
from endesive import pdf # noqa: F401
except ImportError:
_logger.info(
"skipping test because https://github.com/m32/endesive"
Expand Down
55 changes: 55 additions & 0 deletions tests/test_erpbrasil_fake_certificate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from unittest import TestCase
import datetime
from erpbrasil.assinatura.misc import create_fake_certificate_file
from erpbrasil.assinatura import certificado
from erpbrasil.assinatura.excecoes import CertificadoExpirado


class Tests(TestCase):
"""Simple test for fake certificate creation."""

def setUp(self):
self.cert_country = "BR"
self.cert_issuer_a = "EMISSOR A TESTE"
self.cert_issuer_b = "EMISSOR B TESTE"
self.cert_subject_valid = "CERTIFICADO VALIDO TESTE"
self.cert_date_exp = datetime.datetime.today() + datetime.timedelta(days=365)
self.cert_subject_invalid = "CERTIFICADO INVALIDO TESTE"
self.cert_passwd = "123456"
self.cert_name = "{} - {} - {} - Valid: {}".format(
"NF-E",
"A1",
self.cert_subject_valid,
self.cert_date_exp.strftime("%Y%M%d"),
)

self.certificate_valid = create_fake_certificate_file(
valid=True,
passwd=self.cert_passwd,
issuer=self.cert_issuer_a,
country=self.cert_country,
subject=self.cert_subject_valid,
)

self.certificate_invalid = create_fake_certificate_file(
valid=False,
passwd=self.cert_passwd,
issuer=self.cert_issuer_b,
country=self.cert_country,
subject=self.cert_subject_invalid,
)

def test_valid_certificate(self):
"""Check a valid certificate"""
cert = certificado.Certificado(self.certificate_valid, self.cert_passwd)
self.assertEqual(cert.emissor, self.cert_issuer_a)
self.assertEqual(cert.proprietario, self.cert_subject_valid)
self.assertEqual(
cert.fim_validade.strftime("%Y%M%d"),
self.cert_date_exp.strftime("%Y%M%d")
)

def test_invalid_certificate(self):
"""Check a invalid certificate"""
with self.assertRaises(CertificadoExpirado):
certificado.Certificado(self.certificate_invalid, self.cert_passwd)

0 comments on commit ad147b0

Please sign in to comment.