# Krb5PrincipalName
`Krb5PrincipalName` encodes and decodes the `KRB5PrincipalName` structure (RFC 4556 ยง3.2.2)
used as an `OtherName` Subject Alternative Name value in PKINIT certificates.
## Class
```python
class Krb5PrincipalName:
def __init__(self, realm: str, name_type: int, components: list[str]) -> None: ...
# realm must be ASCII. name_type is one of the NT_* constants.
# All string arguments must be ASCII; raises ValueError otherwise.
@staticmethod
def from_der(data: bytes) -> Krb5PrincipalName: ...
def to_der(self) -> bytes: ...
realm: str # Kerberos realm (e.g. "EXAMPLE.COM")
name_type: int # One of the NT_* constants
components: list[str] # Name-string components
def __repr__(self) -> str: ...
def __eq__(self, other) -> bool: ...
```
## Usage
```python
import synta.krb5 as krb5
# Construct a host principal: host/server.example.com@EXAMPLE.COM
principal = krb5.Krb5PrincipalName(
realm="EXAMPLE.COM",
name_type=krb5.NT_SRV_HST,
components=["host", "server.example.com"],
)
der_bytes = principal.to_der()
# Parse from DER
parsed = krb5.Krb5PrincipalName.from_der(der_bytes)
print(parsed.realm) # "EXAMPLE.COM"
print(parsed.name_type) # 3 (NT_SRV_HST)
print(parsed.components) # ["host", "server.example.com"]
# Read from a PKINIT certificate SAN (OtherName entry)
import synta
import synta.general_name as gn
for san in cert.subject_alt_names():
if isinstance(san, gn.OtherName):
# san.type_id is the OID; san.value is the raw DER value bytes
if san.type_id == krb5.KRB5_PRINCIPAL_NAME_OID:
# value is the [0] EXPLICIT-wrapped KRB5PrincipalName
dec = synta.Decoder(san.value, synta.Encoding.DER)
explicit = dec.decode_explicit_tag(0)
kpn = krb5.Krb5PrincipalName.from_der(explicit.remaining_bytes())
print(f"realm={kpn.realm}, name_type={kpn.name_type}, components={kpn.components}")
```
## Encoding a principal name for certificate generation
```python
import synta
import synta.krb5 as krb5
# Build an otherName SAN entry for a PKINIT client certificate
kpn = krb5.Krb5PrincipalName(
realm="EXAMPLE.COM",
name_type=krb5.NT_PRINCIPAL,
components=["alice"],
)
kpn_der = kpn.to_der()
# Wrap in OtherName: SEQUENCE { type-id OID, value [0] EXPLICIT <kpn_der> }
inner = synta.Encoder(synta.Encoding.DER)
inner.encode_oid(krb5.KRB5_PRINCIPAL_NAME_OID)
inner.encode_explicit_tag(0, "Context", kpn_der)
outer = synta.Encoder(synta.Encoding.DER)
outer.encode_sequence(inner.finish())
other_name_der = outer.finish()
# The SAN builder does not have a dedicated other_name() method.
# Encode the SAN extension value manually using the Encoder:
enc = synta.Encoder(synta.Encoding.DER)
enc.encode_sequence(other_name_der) # wrap in outer SEQUENCE OF GeneralName
san_value_der = enc.finish()
# Then pass san_value_der as the extnValue to your certificate builder.
```
See also [Kerberos V5 Types](krb5.md) for principal-name type and encryption type constants,
and [PKINIT Types](krb5-pkinit.md) for the full PKINIT protocol structure set.