synta 0.1.12

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# CRMF Messages


`synta.crmf` provides RFC 4211 Certificate Request Message Format types used in CMP
certificate management.

```python
import synta.crmf as crmf
```

## CertReqMessages

A batch of Certificate Request Messages (`SEQUENCE OF CertReqMsg`, RFC 4211 §3).

```python
class CertReqMessages:
    @staticmethod
    def from_der(data: bytes) -> CertReqMessages: ...
    def to_der(self) -> bytes: ...
    requests: list[CertReqMsg]
    def __len__(self) -> int: ...
    def __iter__(self): ...
    def __getitem__(self, index: int) -> CertReqMsg: ...
```

## CertReqMsg

A single certificate request message (RFC 4211 §4).

```python
class CertReqMsg:
    cert_req_id: int               # certReqId integer
    cert_template_der: bytes       # DER bytes of the CertTemplate SEQUENCE
    popo_type: str | None          # Active ProofOfPossession arm name, or None
    # One of: "raVerified", "signature", "keyEncipherment", "keyAgreement"
    popo_der: bytes | None         # DER bytes of the ProofOfPossession CHOICE
    subject_der: bytes | None      # DER bytes of subject Name from CertTemplate
    issuer_der: bytes | None       # DER bytes of issuer Name from CertTemplate
```

## CertReqMsgBuilder

Fluent builder for a single `CertReqMsg`.

```python
class CertReqMsgBuilder:
    def __init__(self) -> None: ...
    def cert_req_id(self, id: int) -> CertReqMsgBuilder: ...
    def subject_name(self, name_der: bytes) -> CertReqMsgBuilder: ...
    def issuer_name(self, name_der: bytes) -> CertReqMsgBuilder: ...
    def public_key_der(self, spki_der: bytes) -> CertReqMsgBuilder: ...
    def popo_ra_verified(self) -> CertReqMsgBuilder: ...
    def publication_action(self, action: int) -> CertReqMsgBuilder: ...
    def add_pub_info(self, pub_method: int) -> CertReqMsgBuilder: ...
    def pub_location_uri(self, pub_method: int, uri: str) -> CertReqMsgBuilder: ...
    def pub_location_rfc822(self, pub_method: int, email: str) -> CertReqMsgBuilder: ...
    def pub_location_dns(self, pub_method: int, host: str) -> CertReqMsgBuilder: ...
    def pub_location_directory_name(self, pub_method: int, name_der: bytes) -> CertReqMsgBuilder: ...
    def build(self) -> CertReqMsg: ...
    # Raises ValueError if stored Name/SPKI bytes are invalid.
```

## CertReqMessagesBuilder

Fluent builder for a CRMF batch.

```python
class CertReqMessagesBuilder:
    def __init__(self) -> None: ...
    def add_request(self, req: CertReqMsg) -> CertReqMessagesBuilder: ...
    def build(self) -> CertReqMessages: ...
```

## Publication method constants

| Constant | Value | Meaning |
|---|---|---|
| `PUB_METHOD_DONT_CARE` | 0 | No publication preference |
| `PUB_METHOD_X500` | 1 | Publish in X.500 directory |
| `PUB_METHOD_WEB` | 2 | Publish via HTTP/HTTPS URI |
| `PUB_METHOD_LDAP` | 3 | Publish in LDAP directory |

## OID constants

| Constant | Description |
|---|---|
| `ID_REG_CTRL_REG_TOKEN` | Registration token control (RFC 4211 §6.1) |
| `ID_REG_CTRL_AUTHENTICATOR` | Authenticator control (RFC 4211 §6.2) |
| `ID_REG_CTRL_PKI_PUBLICATION_INFO` | PKI publication info control |
| `ID_REG_CTRL_PKI_ARCHIVE_OPTIONS` | PKI archive options control |
| `ID_REG_CTRL_OLD_CERT_ID` | Old certificate ID control |
| `ID_REG_CTRL_PROTOCOL_ENCR_KEY` | Protocol encryption key control |
| `ID_REG_INFO_UTF8_PAIRS` | UTF-8 pairs registration info |
| `ID_REG_INFO_CERT_REQ` | Certificate request registration info |

## Usage

```python
import synta.crmf as crmf

# Build a CRMF request
req = (
    crmf.CertReqMsgBuilder()
    .cert_req_id(1)
    .subject_name(subject_name_der)
    .public_key_der(spki_der)
    .popo_ra_verified()
    .build()
)

batch = crmf.CertReqMessagesBuilder().add_request(req).build()
batch_der = batch.to_der()

# Parse incoming CRMF
msgs = crmf.CertReqMessages.from_der(data)
for msg in msgs:
    print(f"id={msg.cert_req_id}, popo={msg.popo_type}")
    if msg.subject_der:
        import synta
        attrs = synta.parse_name_attrs(msg.subject_der)
        print(f"  subject: {attrs}")
```

See also [CMP Messages](cmp.md) for the CMP envelope that carries CRMF requests.