import synta
import synta.krb5 as krb5
def test_krb5_principal_name_oid():
oid = krb5.KRB5_PRINCIPAL_NAME_OID
assert str(oid) == "1.3.6.1.5.2.2"
assert list(oid.components()) == [1, 3, 6, 1, 5, 2, 2]
print(" ✓ KRB5_PRINCIPAL_NAME_OID: OK")
def test_nt_constants():
assert krb5.NT_UNKNOWN == 0
assert krb5.NT_PRINCIPAL == 1
assert krb5.NT_SRV_INST == 2
assert krb5.NT_SRV_HST == 3
assert krb5.NT_SRV_XHST == 4
assert krb5.NT_UID == 5
assert krb5.NT_X500_PRINCIPAL == 6
assert krb5.NT_SMTP_NAME == 7
assert krb5.NT_ENTERPRISE == 10
assert krb5.NT_WELLKNOWN == 11
assert krb5.NT_SRV_HST_DOMAIN == 12
print(" ✓ NT_* constants: OK")
def test_etype_constants():
assert krb5.ETYPE_DES_CBC_CRC == 1
assert krb5.ETYPE_DES_CBC_MD4 == 2
assert krb5.ETYPE_DES_CBC_MD5 == 3
assert krb5.ETYPE_DES3_CBC_MD5 == 5
assert krb5.ETYPE_DES3_CBC_SHA1 == 7
assert krb5.ETYPE_DES_HMAC_SHA1 == 8
assert krb5.ETYPE_DES3_CBC_SHA1_KD == 16
assert krb5.ETYPE_AES128_CTS_HMAC_SHA1_96 == 17
assert krb5.ETYPE_AES256_CTS_HMAC_SHA1_96 == 18
assert krb5.ETYPE_AES128_CTS_HMAC_SHA256_128 == 19
assert krb5.ETYPE_AES256_CTS_HMAC_SHA384_192 == 20
assert krb5.ETYPE_RC4_HMAC == 23
assert krb5.ETYPE_RC4_HMAC_EXP == 24
assert krb5.ETYPE_CAMELLIA128_CTS_CMAC == 25
assert krb5.ETYPE_CAMELLIA256_CTS_CMAC == 26
print(" ✓ ETYPE_* constants: OK")
def test_constructor_user_principal():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_PRINCIPAL, ["alice"])
assert p.realm == "EXAMPLE.COM"
assert p.name_type == krb5.NT_PRINCIPAL
assert list(p.components) == ["alice"]
print(" ✓ constructor (user principal): OK")
def test_constructor_service_inst():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_SRV_INST, ["krbtgt", "EXAMPLE.COM"])
assert p.realm == "EXAMPLE.COM"
assert p.name_type == krb5.NT_SRV_INST
assert list(p.components) == ["krbtgt", "EXAMPLE.COM"]
print(" ✓ constructor (service/inst): OK")
def test_constructor_rejects_non_ascii_realm():
try:
krb5.Krb5PrincipalName("RÉALM", krb5.NT_PRINCIPAL, ["alice"])
assert False, "expected ValueError"
except ValueError:
pass
print(" ✓ constructor rejects non-ASCII realm: OK")
def test_constructor_rejects_non_ascii_component():
try:
krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_PRINCIPAL, ["alïce"])
assert False, "expected ValueError"
except ValueError:
pass
print(" ✓ constructor rejects non-ASCII component: OK")
def test_roundtrip_user_principal():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_PRINCIPAL, ["alice"])
der = p.to_der()
assert isinstance(der, bytes)
q = krb5.Krb5PrincipalName.from_der(der)
assert q.realm == p.realm
assert q.name_type == p.name_type
assert list(q.components) == list(p.components)
print(" ✓ roundtrip (user principal): OK")
def test_roundtrip_tgt_service():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_SRV_INST, ["krbtgt", "EXAMPLE.COM"])
der = p.to_der()
q = krb5.Krb5PrincipalName.from_der(der)
assert q.realm == "EXAMPLE.COM"
assert q.name_type == krb5.NT_SRV_INST
assert list(q.components) == ["krbtgt", "EXAMPLE.COM"]
print(" ✓ roundtrip (TGT service): OK")
def test_roundtrip_host_principal():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_SRV_HST, ["host", "server.example.com"])
der = p.to_der()
q = krb5.Krb5PrincipalName.from_der(der)
assert q.realm == "EXAMPLE.COM"
assert q.name_type == krb5.NT_SRV_HST
assert list(q.components) == ["host", "server.example.com"]
print(" ✓ roundtrip (host principal): OK")
def test_roundtrip_enterprise():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_ENTERPRISE, ["user@domain.example"])
der = p.to_der()
q = krb5.Krb5PrincipalName.from_der(der)
assert list(q.components) == ["user@domain.example"]
print(" ✓ roundtrip (enterprise): OK")
KNOWN_GOOD_DER = bytes.fromhex(
"3031"
"a00d" "1b0b" "4558414d504c452e434f4d"
"a120"
"301e"
"a003" "020102"
"a117"
"3015"
"1b06" "6b7262746774"
"1b0b" "4558414d504c452e434f4d"
)
def test_decode_known_good_vector():
p = krb5.Krb5PrincipalName.from_der(KNOWN_GOOD_DER)
assert p.realm == "EXAMPLE.COM"
assert p.name_type == krb5.NT_SRV_INST
assert list(p.components) == ["krbtgt", "EXAMPLE.COM"]
print(" ✓ decode known-good DER vector: OK")
def test_encode_matches_known_good_vector():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_SRV_INST, ["krbtgt", "EXAMPLE.COM"])
der = p.to_der()
assert der == KNOWN_GOOD_DER, f"expected {KNOWN_GOOD_DER.hex()}, got {der.hex()}"
print(" ✓ encode matches known-good DER vector: OK")
def test_from_der_invalid_raises():
try:
krb5.Krb5PrincipalName.from_der(b"\x00\x00\x00")
assert False, "expected ValueError"
except (ValueError, Exception):
pass
print(" ✓ from_der(invalid) raises: OK")
def test_repr():
p = krb5.Krb5PrincipalName("EXAMPLE.COM", krb5.NT_PRINCIPAL, ["alice"])
r = repr(p)
assert "Krb5PrincipalName" in r
assert "EXAMPLE.COM" in r
assert "alice" in r
print(" ✓ __repr__: OK")
def test_equality():
a = krb5.Krb5PrincipalName("REALM", krb5.NT_PRINCIPAL, ["bob"])
b = krb5.Krb5PrincipalName("REALM", krb5.NT_PRINCIPAL, ["bob"])
c = krb5.Krb5PrincipalName("REALM", krb5.NT_PRINCIPAL, ["carol"])
assert a == b
assert not (a == c)
print(" ✓ __eq__: OK")
def test_import_via_synta_krb5():
import synta.krb5
assert hasattr(synta.krb5, "Krb5PrincipalName")
assert hasattr(synta.krb5, "NT_PRINCIPAL")
print(" ✓ import synta.krb5: OK")
def test_accessible_as_synta_attr():
import synta
assert hasattr(synta, "krb5")
assert hasattr(synta.krb5, "NT_SRV_INST")
print(" ✓ synta.krb5 attribute: OK")
if __name__ == "__main__":
tests = [
test_krb5_principal_name_oid,
test_nt_constants,
test_etype_constants,
test_constructor_user_principal,
test_constructor_service_inst,
test_constructor_rejects_non_ascii_realm,
test_constructor_rejects_non_ascii_component,
test_roundtrip_user_principal,
test_roundtrip_tgt_service,
test_roundtrip_host_principal,
test_roundtrip_enterprise,
test_decode_known_good_vector,
test_encode_matches_known_good_vector,
test_from_der_invalid_raises,
test_repr,
test_equality,
test_import_via_synta_krb5,
test_accessible_as_synta_attr,
]
print("Running synta.krb5 tests...")
failed = 0
for t in tests:
try:
t()
except Exception as e:
print(f" ✗ {t.__name__}: FAILED — {e}")
failed += 1
if failed:
print(f"\n{failed}/{len(tests)} tests FAILED")
raise SystemExit(1)
print(f"\nAll {len(tests)} tests passed.")