import datetime
import traceback
import pytest
import synta
import synta.ext as ext
import synta.general_name as gn
import synta.oids as oids
def _make_ca_cert():
key = synta.PrivateKey.generate_ec("P-256")
name = synta.NameBuilder().common_name("Helper Test CA").build()
now = datetime.datetime(2025, 1, 1, tzinfo=datetime.timezone.utc)
later = datetime.datetime(2027, 1, 1, tzinfo=datetime.timezone.utc)
cert = (
synta.CertificateBuilder()
.issuer_name(name).subject_name(name)
.public_key(key.public_key).serial_number(1)
.not_valid_before_utc(now).not_valid_after_utc(later)
.add_extension(str(oids.BASIC_CONSTRAINTS), True, ext.basic_constraints(ca=True))
.add_extension(str(oids.KEY_USAGE), True, ext.key_usage(ext.KU_KEY_CERT_SIGN | ext.KU_CRL_SIGN))
.sign(key, "sha256")
)
return key, cert
def test_find_extension_value_present():
_, cert = _make_ca_cert()
ext_seq = cert.extensions_der
assert ext_seq is not None
value = synta.find_extension_value(ext_seq, "2.5.29.19")
assert value is not None
assert isinstance(value, bytes)
assert len(value) > 0
def test_find_extension_value_absent():
_, cert = _make_ca_cert()
ext_seq = cert.extensions_der
assert ext_seq is not None
value = synta.find_extension_value(ext_seq, "1.3.6.1.5.5.7.1.11")
assert value is None
def test_find_extension_value_with_oid_object():
_, cert = _make_ca_cert()
ext_seq = cert.extensions_der
assert ext_seq is not None
oid_obj = synta.ObjectIdentifier("2.5.29.19")
value = synta.find_extension_value(ext_seq, oid_obj)
assert value is not None
def test_find_extension_value_invalid_oid():
_, cert = _make_ca_cert()
ext_seq = cert.extensions_der
assert ext_seq is not None
with pytest.raises((ValueError, TypeError)):
synta.find_extension_value(ext_seq, "not.an.oid")
def test_encode_general_names_dns():
result = synta.encode_general_names([(gn.DNS_NAME, b"example.com")])
assert result is not None
assert isinstance(result, bytes)
assert result[0] == 0x30
def test_encode_general_names_multi():
entries = [
(gn.DNS_NAME, b"example.com"),
(gn.DNS_NAME, b"www.example.com"),
(gn.IP_ADDRESS, bytes([192, 168, 1, 1])),
]
result = synta.encode_general_names(entries)
assert result is not None
assert isinstance(result, bytes)
def test_encode_general_names_roundtrip():
entries = [(gn.DNS_NAME, b"roundtrip.example.com")]
encoded = synta.encode_general_names(entries)
assert encoded is not None
parsed = synta.parse_general_names(encoded)
assert len(parsed) == 1
tag, content = parsed[0]
assert tag == gn.DNS_NAME
assert content == b"roundtrip.example.com"
def test_encode_general_names_empty():
result = synta.encode_general_names([])
if result is not None:
assert isinstance(result, bytes)
def test_key_usage_bit_keyCertSign_set():
_, cert = _make_ca_cert()
ku_der = cert.get_extension_value_der("2.5.29.15")
assert ku_der is not None
assert synta.key_usage_bit(ku_der, 5) is True assert synta.key_usage_bit(ku_der, 6) is True assert synta.key_usage_bit(ku_der, 0) is False
def test_key_usage_bit_digitalSignature_set():
key = synta.PrivateKey.generate_ec("P-256")
name = synta.NameBuilder().common_name("Leaf").build()
now = datetime.datetime(2025, 1, 1, tzinfo=datetime.timezone.utc)
later = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc)
cert = (
synta.CertificateBuilder()
.issuer_name(name).subject_name(name)
.public_key(key.public_key).serial_number(2)
.not_valid_before_utc(now).not_valid_after_utc(later)
.add_extension(str(oids.KEY_USAGE), True, ext.key_usage(ext.KU_DIGITAL_SIGNATURE))
.sign(key, "sha256")
)
ku_der = cert.get_extension_value_der("2.5.29.15")
assert ku_der is not None
assert synta.key_usage_bit(ku_der, 0) is True assert synta.key_usage_bit(ku_der, 5) is False
def test_signing_algorithm_der_ec_sha256():
result = synta.signing_algorithm_der("1.2.840.10045.2.1", "sha256")
if result is not None:
assert isinstance(result, bytes)
assert result[0] == 0x30
def test_signing_algorithm_der_rsa_sha256():
result = synta.signing_algorithm_der("1.2.840.113549.1.1.1", "sha256")
if result is not None:
assert isinstance(result, bytes)
assert result[0] == 0x30
def test_signing_algorithm_der_unknown_key():
result = synta.signing_algorithm_der("1.2.3.4.5.6", "sha256")
assert result is None
def test_signing_algorithm_der_with_oid_object():
oid_obj = synta.ObjectIdentifier("1.2.840.113549.1.1.1")
result = synta.signing_algorithm_der(oid_obj, "sha256")
if result is not None:
assert isinstance(result, bytes)
def test_decode_public_key_info_ec():
key = synta.PrivateKey.generate_ec("P-256")
info = synta.decode_public_key_info(key.public_key.to_der())
assert isinstance(info, dict)
assert "algorithm_oid" in info
assert "key_bytes" in info
assert info["algorithm_oid"] == "1.2.840.10045.2.1"
def test_decode_public_key_info_ec_curve():
key = synta.PrivateKey.generate_ec("P-256")
info = synta.decode_public_key_info(key.public_key.to_der())
if "curve_nist_name" in info:
assert info["curve_nist_name"] == "P-256"
def test_decode_public_key_info_ed25519():
key = synta.PrivateKey.generate_ed25519()
info = synta.decode_public_key_info(key.public_key.to_der())
assert isinstance(info, dict)
assert info["algorithm_oid"] == "1.3.101.112"
def test_decode_public_key_info_invalid():
with pytest.raises(ValueError):
synta.decode_public_key_info(b"\x00" * 10)
def main():
tests = [
test_find_extension_value_present,
test_find_extension_value_absent,
test_find_extension_value_with_oid_object,
test_encode_general_names_dns,
test_encode_general_names_multi,
test_encode_general_names_roundtrip,
test_encode_general_names_empty,
test_key_usage_bit_keyCertSign_set,
test_key_usage_bit_digitalSignature_set,
test_signing_algorithm_der_ec_sha256,
test_signing_algorithm_der_rsa_sha256,
test_signing_algorithm_der_unknown_key,
test_signing_algorithm_der_with_oid_object,
test_decode_public_key_info_ec,
test_decode_public_key_info_ec_curve,
test_decode_public_key_info_ed25519,
test_decode_public_key_info_invalid,
]
passed = failed = 0
for t in tests:
try:
t()
print(f" ok {t.__name__}")
passed += 1
except Exception as e:
print(f" FAIL {t.__name__}: {e}")
traceback.print_exc()
failed += 1
print(f"\n{passed} passed, {failed} failed")
if failed:
raise SystemExit(1)
if __name__ == "__main__":
main()