Files
sowai-fiscal-svc/scripts/generate_test_cert.py
T

68 lines
2.8 KiB
Python

"""Task 6: one-shot generator for `tests/fixtures/test_cert.pfx` -- a
self-signed TEST-ONLY A1 certificate, NEVER a real one (design spec's "os 3
seguros de portabilidade", item (b)/(c) extended by the F2 emenda: goldens
ASSINADOS need a FIXED test certificate, committed as a binary fixture).
Re-running this script produces a DIFFERENT RSA key pair (key generation is
not seeded) -- that is fine and expected: this is meant to be run ONCE and
the output COMMITTED. The determinism `tests/test_signed_goldens.py` relies
on comes from every test run reusing the SAME committed `.pfx` file (so the
same private key signs the same canonicalized XML the same way every time,
RSA PKCS#1v1.5 having no random padding) -- NOT from this generator being
reproducible bit-for-bit across runs. Re-run only if the fixture needs to be
rotated, and regenerate `tests/goldens_signed/*.expected.xml`
(`scripts/generate_signed_goldens.py`) together with it, in the same commit.
uv run python scripts/generate_test_cert.py
"""
from datetime import datetime, timedelta, timezone
from pathlib import Path
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import pkcs12
from cryptography.x509.oid import NameOID
# Mesmo CNPJ do emitente usado em TODOS os casos golden da lib
# (`sowai_fiscal.goldens/*.input.json`) -- ver esse pacote se algum caso
# novo usar um CNPJ diferente; este script/fixture precisaria acompanhar.
CNPJ = "12345678000190"
PASSWORD = "test-cert-password"
OUT_PATH = Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "test_cert.pfx"
def main() -> None:
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
subject = issuer = x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, f"AUTOPECAS THIAGO LTDA:{CNPJ}"),
x509.NameAttribute(NameOID.SERIAL_NUMBER, CNPJ),
]
)
now = datetime.now(timezone.utc)
cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(issuer)
.public_key(key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(now - timedelta(days=1))
.not_valid_after(now + timedelta(days=3650))
.sign(key, hashes.SHA256())
)
pfx_bytes = pkcs12.serialize_key_and_certificates(
name=b"sowai-fiscal-svc-test",
key=key,
cert=cert,
cas=None,
encryption_algorithm=serialization.BestAvailableEncryption(PASSWORD.encode("utf-8")),
)
OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
OUT_PATH.write_bytes(pfx_bytes)
print(f"wrote {OUT_PATH} (cnpj={CNPJ}, password={PASSWORD!r})")
if __name__ == "__main__":
main()