synta 0.2.0

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# X.509 Path Validation


`synta.x509` verifies RFC 5280 / CABF TLS server and client certificate chains.

```python
import synta.x509 as x509
```

## Classes

### TrustStore

A set of trusted root CA certificates used as trust anchors for chain verification.

```python
x509.TrustStore(ders: list[bytes])
```
Construct a `TrustStore` from a list of DER-encoded CA certificates.
Pass PEM bundles through `synta.pem_to_der()` first.

| Property | Type | Description |
|---|---|---|
| `len` | `int` | Number of trusted certificates in this store |

### CrlStore

A set of Certificate Revocation Lists for revocation checking.

```python
x509.CrlStore(ders: list[bytes])
```
Construct a `CrlStore` from a list of DER-encoded CRLs.
Certificates whose issuing CA has no matching CRL in the store are treated as not-revoked (soft-fail).

| Property | Type | Description |
|---|---|---|
| `len` | `int` | Number of CRLs in this store |

### OcspStore

A store of pre-fetched OCSP responses for revocation checking.

```python
x509.OcspStore(ocsp_ders: list[bytes])
```
Construct an `OcspStore` from a list of DER-encoded OCSP response byte strings
(the outer `OCSPResponse` SEQUENCE per RFC 6960).
Certificates for which no valid matching OCSP response is found are treated as not-revoked (soft-fail).

| Property | Type | Description |
|---|---|---|
| `len` | `int` | Number of OCSP responses in this store |

### VerificationPolicy

Policy parameters for chain verification.

```python
x509.VerificationPolicy(
    server_names: list[str] | None = None,
    name_match: str = "any",
    validation_time: float | None = None,
    max_chain_depth: int = 8,
    profile: str | None = None,
)
```

| Parameter | Type | Description |
|---|---|---|
| `server_names` | `list[str] \| None` | DNS names the certificate must cover |
| `name_match` | `str` | `"any"` (default) or `"all"` — whether the cert must match any or all supplied names |
| `validation_time` | `float \| None` | Unix timestamp for validity window check; `None` uses current time |
| `max_chain_depth` | `int` | Maximum allowed chain length; default `8` |
| `profile` | `str \| None` | Validation profile identifier |

### X509VerificationError

Raised on any chain or policy failure. Subclass of `Exception`.

```python
try:
    x509.verify_server_certificate(...)
except x509.X509VerificationError as exc:
    print(f"verification failed: {exc}")
```

## Functions

```python
x509.verify_server_certificate(
    leaf: bytes | Certificate,
    intermediates: list[bytes | Certificate],
    store: TrustStore,
    policy: VerificationPolicy,
    crls: CrlStore | None = None,
    ocsp: OcspStore | None = None,
) -> list[bytes]
```
Verify a TLS server certificate chain. Returns the verified chain as a list of
DER-encoded certificates in order from trust anchor to leaf.
Pass `crls=` for CRL-based revocation checking and/or `ocsp=` for OCSP-based checking.

```python
x509.verify_client_certificate(
    leaf: bytes | Certificate,
    intermediates: list[bytes | Certificate],
    store: TrustStore,
    policy: VerificationPolicy,
    crls: CrlStore | None = None,
    ocsp: OcspStore | None = None,
) -> list[bytes]
```
Verify a TLS client certificate chain. Same return type and keyword arguments as `verify_server_certificate`.

## Usage

```python
import synta
import synta.x509 as x509

# Load trust anchors from a PEM bundle
with open("roots.pem", "rb") as f:
    ders = synta.pem_to_der(f.read())
store = x509.TrustStore(ders)

# Verify a server certificate (single name)
with open("leaf.der", "rb") as f:
    leaf_der = f.read()
with open("intermediate.der", "rb") as f:
    intermediate_der = f.read()

policy = x509.VerificationPolicy(server_names=["example.com"])
chain  = x509.verify_server_certificate(leaf_der, [intermediate_der], store, policy)

for i, cert_der in enumerate(chain):
    cert = synta.Certificate.from_der(cert_der)
    role = "trust anchor" if i == 0 else ("leaf" if i == len(chain) - 1 else "CA")
    print(f"chain[{i}] ({role}): {cert.subject}")

# Multi-name any-match (cert must cover at least one name)
policy = x509.VerificationPolicy(
    server_names=["example.com", "www.example.com"],
    name_match="any",
)

# Multi-name all-match (cert must cover every name)
policy = x509.VerificationPolicy(
    server_names=["example.com", "api.example.com"],
    name_match="all",
)

# Error handling
try:
    chain = x509.verify_server_certificate(leaf_der, [], store, policy)
except x509.X509VerificationError as exc:
    print(f"verification failed: {exc}")
```

See also [Certificate](certificate.md) for `verify_issued_by` (single-issuer signature
check without a full chain build) and [Error Handling](../core/errors.md) for the exception
hierarchy.