"""DER helpers and signing pipeline (no YubiKey required).""" from datetime import datetime, timedelta, timezone from cryptography import x509 from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec from cryptography.x509.oid import NameOID from signing import _der_read_len, _der_seq, _split_cert_der from cryptography.hazmat.primitives.serialization import Encoding def _dummy_cert_der(): key = ec.generate_private_key(ec.SECP384R1()) name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "dummy.test")]) cert = ( x509.CertificateBuilder() .subject_name(name) .issuer_name(name) .public_key(key.public_key()) .serial_number(x509.random_serial_number()) .not_valid_before(datetime.now(timezone.utc)) .not_valid_after(datetime.now(timezone.utc) + timedelta(days=1)) .sign(key, hashes.SHA384()) ) return cert.public_bytes(Encoding.DER) def test_split_roundtrip(): der = _dummy_cert_der() tbs, alg, sig = _split_cert_der(der) assert alg[0] == 0x30 assert sig[0] == 0x03 # Reassembling the same parts reproduces the original certificate. reassembled = _der_seq(tbs + alg + sig) assert reassembled == der def test_der_read_len_short_and_long(): assert _der_read_len(b"\x05ABC", 0) == (5, 1) long_len = b"\x81\x10" assert _der_read_len(long_len + b"A" * 16, 0) == (16, 2) def test_build_leaf_cert_fails_cleanly_without_ca(): """Without the CA files the pipeline fails cleanly (no YubiKey available).""" import pytest from signing import build_leaf_cert with pytest.raises(FileNotFoundError): build_leaf_cert("nope.test", "", 365)