synta 0.1.11

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# CRL and OCSP Response Builders


`CertificateListBuilder`, `OCSPResponseBuilder`, and `OCSPSingleResponse` are top-level `synta` exports for
constructing DER-encoded X.509 CRL and OCSP response structures. Both follow the same
pattern: build the unsigned TBS blob, sign it externally, then call `assemble` to wrap the
signature into the final structure.

## CertificateListBuilder

Fluent builder for RFC 5280 §5 `TBSCertList`.

```python
class CertificateListBuilder:
    def __init__(self) -> None: ...

    def issuer(self, name_der: bytes) -> CertificateListBuilder: ...
    # Set the issuer Name from pre-encoded DER bytes.

    def this_update(self, time: str) -> CertificateListBuilder: ...
    # Set thisUpdate ("YYYYMMDDHHmmssZ" or "YYMMDDHHmmssZ").

    def next_update(self, time: str) -> CertificateListBuilder: ...
    # Set optional nextUpdate (same format as this_update).

    def revoke(
        self,
        serial: bytes,
        revocation_date: str,
        reason: int | None = None,
    ) -> CertificateListBuilder: ...
    # Add a revoked certificate entry.
    # serial is the big-endian DER INTEGER value bytes.
    # reason is an optional CRL reason code (0–10).

    def signature_algorithm(self, alg_der: bytes) -> CertificateListBuilder: ...
    # Set the AlgorithmIdentifier DER for TBSCertList.signature.

    def build(self) -> bytes: ...
    # Build the DER-encoded TBSCertList SEQUENCE.
    # Raises ValueError if any required field is absent or encoding fails.

    @staticmethod
    def assemble(tbs_der: bytes, sig_alg_der: bytes, signature: bytes) -> bytes: ...
    # Assemble a complete DER-encoded CertificateList.
    # tbs_der:    TBSCertList bytes from build().
    # sig_alg_der: outer AlgorithmIdentifier SEQUENCE TLV.
    # signature:  raw signature bytes (BIT STRING value).
    # Raises ValueError if DER encoding fails.
```

### Example

```python,ignore
import synta

name_der = synta.NameBuilder().common_name("Test CA").build()
alg_der  = bytes.fromhex("300d06092a864886f70d01010b0500")  # sha256WithRSAEncryption

tbs = (
    synta.CertificateListBuilder()
    .issuer(name_der)
    .signature_algorithm(alg_der)
    .this_update("20240101120000Z")
    .revoke(bytes([1]), "20231201000000Z", 1)   # reason 1 = keyCompromise
    .build()
)
# Sign tbs externally, then assemble:
# crl_der = synta.CertificateListBuilder.assemble(tbs, alg_der, sig_bytes)
```

---

## OCSPSingleResponse

Parameters for a single OCSP response entry. Pass an instance to
`OCSPResponseBuilder.add_response`.

```python
class OCSPSingleResponse:
    def __init__(
        self,
        hash_algorithm_der: bytes,
        issuer_name_hash: bytes,
        issuer_key_hash: bytes,
        serial: bytes,
        status: int,
        this_update: str,
        next_update: str | None = None,
    ) -> None: ...
    # hash_algorithm_der: pre-encoded AlgorithmIdentifier DER TLV (e.g. SHA-1).
    # issuer_name_hash:   raw hash of the issuer Name DER bytes.
    # issuer_key_hash:    raw hash of the issuer subjectPublicKey BIT STRING value.
    # serial:             big-endian DER INTEGER value bytes of the target certificate.
    # status:             0 = good, 1 = revoked, 2 = unknown.
    # this_update:        "YYYYMMDDHHmmssZ" format.
    # next_update:        optional "YYYYMMDDHHmmssZ" format.
```

---

## OCSPResponseBuilder

Fluent builder for RFC 6960 §4.2.1 `ResponseData`. Set exactly one of `responder_name` or
`responder_key_hash` before calling `build_tbs`.

```python
class OCSPResponseBuilder:
    def __init__(self) -> None: ...

    def responder_name(self, name_der: bytes) -> OCSPResponseBuilder: ...
    # Set responderID byName from a pre-encoded DER Name SEQUENCE TLV.

    def responder_key_hash(self, key_hash: bytes) -> OCSPResponseBuilder: ...
    # Set responderID byKey from raw key-hash bytes (OCTET STRING value).

    def produced_at(self, time: str) -> OCSPResponseBuilder: ...
    # Set producedAt time ("YYYYMMDDHHmmssZ").

    def add_response(self, response: OCSPSingleResponse) -> OCSPResponseBuilder: ...
    # Add a SingleResponse entry built with OCSPSingleResponse.

    def build_tbs(self) -> bytes: ...
    # Build the DER-encoded ResponseData SEQUENCE.
    # Raises ValueError if any required field is absent or encoding fails.

    @staticmethod
    def assemble(tbs_der: bytes, sig_alg_der: bytes, signature: bytes) -> bytes: ...
    # Assemble a complete DER-encoded OCSPResponse.
    # tbs_der:    ResponseData bytes from build_tbs().
    # sig_alg_der: outer AlgorithmIdentifier SEQUENCE TLV.
    # signature:  raw signature bytes (BIT STRING value).
    # Raises ValueError if DER encoding fails.
```

### Example

```python,ignore
import synta, hashlib

# AlgorithmIdentifier for SHA-1 (id-sha1, no parameters)
SHA1_ALG_DER = bytes.fromhex("300702050002014c")  # simplified; use a real encoder in production

resp = synta.OCSPSingleResponse(
    hash_algorithm_der=SHA1_ALG_DER,
    issuer_name_hash=hashlib.sha1(issuer_name_der).digest(),
    issuer_key_hash=hashlib.sha1(issuer_key_bytes).digest(),
    serial=b"\x01",       # serial number DER INTEGER value
    status=0,             # good
    this_update="20240101120000Z",
    next_update="20240201120000Z",
)

tbs = (
    synta.OCSPResponseBuilder()
    .responder_key_hash(hashlib.sha1(issuer_key_bytes).digest())
    .produced_at("20240101120000Z")
    .add_response(resp)
    .build_tbs()
)
# Sign tbs externally, then assemble:
# ocsp_der = synta.OCSPResponseBuilder.assemble(tbs, sig_alg_der, sig_bytes)
```

See also [X.509 Extension Value Builders](ext-builders.md), [OCSP](ocsp.md), and
[Certificate, CSR, and Name Builders](cert-builders.md) for the `NameBuilder` used in
`CertificateListBuilder.issuer()`.