# Example Programs
Thirty-four runnable programs in `examples/` exercise every binding documented
in this guide. Each program is self-contained and runs with:
```bash
uv run python3 examples/example_<name>.py
```
from the repository root (after `maturin develop`).
## 1. `example_pem_helpers.py` — PEM/DER conversion
[Source](example_pem_helpers.md) · [`example_pem_helpers.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_pem_helpers.py)
Bindings: `pem_to_der`, `der_to_pem`, `Certificate.from_pem`, `Certificate.to_pem`,
`CertificationRequest.from_pem`, `CertificationRequest.to_pem`,
`CertificateList.from_pem`, `CertificateList.to_pem`.
- Round-trip a single PEM certificate block through `pem_to_der` / `der_to_pem` (`pem_to_der` always returns `list[bytes]`).
- Show `pem_to_der` with a multi-block PEM chain.
- Use `Certificate.from_pem` on a single block and on a two-certificate chain.
- Use `Certificate.to_pem` on a single cert and a list of certs.
## 2. `example_certificate_fields.py` — All Certificate properties
[Source](example_certificate_fields.md) · [`example_certificate_fields.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_certificate_fields.py)
Bindings: `Certificate.from_der`, `Certificate.full_from_der`, all `Certificate`
properties (`serial_number`, `version`, `issuer`, `issuer_raw_der`, `subject`,
`subject_raw_der`, `not_before`, `not_after`, `signature_algorithm`,
`signature_algorithm_oid`, `signature_algorithm_params`, `signature_value`,
`public_key_algorithm`, `public_key_algorithm_oid`, `public_key_algorithm_params`,
`public_key`, `tbs_bytes`), and `Certificate.to_der()` method.
- Parse the same certificate with `from_der` (lazy) and `full_from_der` (eager).
- Print every property with its Python type.
- Verify `to_der()` round-trip (re-parse the returned bytes).
- Show `signature_algorithm_params` is `None` for Ed25519 and non-`None` for RSA.
## 3. `example_certificate_extensions.py` — Extension access, SAN parsing, and ext builders
[Source](example_certificate_extensions.md) · [`example_certificate_extensions.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_certificate_extensions.py)
Bindings: `Certificate.subject_alt_names`, `Certificate.extensions_der`,
`Certificate.get_extension_value_der`, `synta.general_name` tag constants,
`synta.parse_general_names`, `synta.parse_name_attrs`,
`synta.oids.SUBJECT_ALT_NAME`, `synta.oids.BASIC_CONSTRAINTS`,
`synta.oids.SUBJECT_KEY_IDENTIFIER`, `Decoder.decode_sequence`, `Decoder.peek_tag`,
`Decoder.decode_implicit_tag`, `Decoder.decode_explicit_tag`,
`Decoder.remaining_bytes`, `Decoder.decode_raw_tlv`, `Decoder.is_empty`;
`synta.ext.SubjectAlternativeNameBuilder` (alias `SAN`),
`synta.ext.ExtendedKeyUsageBuilder` (alias `EKU`),
`synta.ext.AuthorityInformationAccessBuilder` (alias `AIA`),
`synta.ext.basic_constraints`, `synta.ext.key_usage`,
`synta.ext.subject_key_identifier`, `synta.ext.authority_key_identifier`,
`synta.ext.KU_*` bitmask constants, `synta.ext.KEYID_*` method constants.
- Call `cert.subject_alt_names()` for high-level SAN access; dispatch on
`synta.general_name` constants (`gn.DNS_NAME`, `gn.IP_ADDRESS`, etc.);
use `ipaddress.ip_address(content)` for IP rendering.
- Verify that a certificate without a SAN extension returns an empty list.
- Access `extensions_der` and iterate the raw extension TLVs.
- Look up individual extensions by `get_extension_value_der`.
- Parse SAN entries manually with `peek_tag` / `decode_implicit_tag`
as a lower-level alternative to `subject_alt_names()`.
- Demonstrate `peek_tag` for CHOICE dispatch; `remaining_bytes` for primitive implicit values.
- Look up BasicConstraints and decode the cA BOOLEAN.
- Build SAN DER with `SubjectAlternativeNameBuilder` (two dNSName, rfc822Name, iPAddress); verify
with short alias `SAN`; build EKU DER with `ExtendedKeyUsageBuilder` (serverAuth+clientAuth);
build AIA DER with `AuthorityInformationAccessBuilder` (OCSP+caIssuers); use short aliases.
- Encode `basic_constraints(ca=False)` (empty SEQUENCE) and `basic_constraints(ca=True, path_length=0)`.
- Encode `key_usage(KU_KEY_CERT_SIGN | KU_CRL_SIGN)` and `key_usage(KU_DIGITAL_SIGNATURE)`.
- Compute `subject_key_identifier` with RFC 5280 and RFC 7093 method 1 from SPKI DER;
compute `authority_key_identifier` from issuer SPKI DER.
## 4. `example_certificate_pyca.py` — PyCA interoperability
[Source](example_certificate_pyca.md) · [`example_certificate_pyca.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_certificate_pyca.py)
Bindings: `Certificate.to_pyca`, `Certificate.from_pyca`.
- Parse a DER certificate with synta, then call `.to_pyca()` for cryptographic operations.
- Load a PyCA certificate, convert to synta with `from_pyca()`, and compare fields.
- Show `ImportError` message when `cryptography` is absent (caught and printed).
## 5. `example_csr.py` — PKCS#10 CSR parsing
[Source](example_csr.md) · [`example_csr.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_csr.py)
Bindings: `CertificationRequest.from_der`, `CertificationRequest.from_pem`,
`CertificationRequest.to_pem`, and all `CertificationRequest` properties.
- Parse a CSR from DER and print every field.
- Round-trip through PEM with `from_pem` / `to_pem`.
- Verify `subject_raw_der` by re-decoding it as a raw Name SEQUENCE.
## 6. `example_certificate_builder.py` — X.509 certificate building
[Source](example_certificate_builder.md) · [`example_certificate_builder.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_certificate_builder.py)
Bindings: `CertificateBuilder` (`issuer_name`, `subject_name`, `public_key`,
`public_key_der`, `serial_number`, `not_valid_before_utc`, `not_valid_after_utc`,
`add_extension`, `sign`, `sign_unsigned`); `NameBuilder`; `PrivateKey.generate_ec`;
`PublicKey.to_der`; `synta.ext.SubjectAlternativeNameBuilder`,
`synta.ext.ExtendedKeyUsageBuilder`, `synta.ext.basic_constraints`,
`synta.ext.key_usage`, `synta.ext.subject_key_identifier`,
`synta.ext.authority_key_identifier`, `synta.ext.KU_*` bitmask constants.
- Generate a self-signed CA certificate with `PrivateKey.generate_ec("P-256")`,
`NameBuilder`, and `CertificateBuilder` (basicConstraints CA:TRUE, keyUsage
keyCertSign+cRLSign, subjectKeyIdentifier); verify DER round-trip.
- Issue a leaf certificate signed by the CA key with `issuer_name` from
`ca_cert.subject_raw_der`, SAN from `SubjectAlternativeNameBuilder`, EKU
from `ExtendedKeyUsageBuilder` (serverAuth), basicConstraints CA:FALSE,
authorityKeyIdentifier, and keyUsage digitalSignature+keyEncipherment.
- Demonstrate `public_key_der()` setter: pass pre-encoded SPKI DER bytes directly
(zero re-encoding); verify `cert.subject_public_key_info_der` round-trip.
- Show `sign_unsigned()` (RFC 9925): confirm `signature_algorithm_oid` is
`id-alg-unsigned` (1.3.6.1.5.5.7.6.36) and `signature_value` is empty.
## 7. `example_crl.py` — CRL parsing and building
[Source](example_crl.md) · [`example_crl.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_crl.py)
Bindings: `CertificateList.from_der`, `CertificateList.from_pem`,
`CertificateList.to_pem`, and all `CertificateList` properties
(`issuer`, `issuer_raw_der`, `this_update`, `next_update`, `signature_algorithm`,
`signature_algorithm_oid`, `signature_value`, `revoked_count`, `crl_number`);
`CertificateListBuilder` (`issuer`, `signature_algorithm`, `this_update`,
`next_update`, `revoke`, `build`, `assemble`); `NameBuilder`.
- Parse a CRL and print issuer, dates, algorithm, revoked count.
- Show `next_update` is `None` for CRLs that omit the field.
- Round-trip through `to_pem` / `from_pem`.
- Build a CRL from scratch with `CertificateListBuilder`: set issuer name via
`NameBuilder`, add two revoked entries with `revoke()` (one with keyCompromise
reason, one unspecified), call `build()` for the TBSCertList, assemble with a
dummy signature via `assemble()`; verify `revoked_count == 2`.
- Show `crl_number` returns `None` when the CRL Number extension is absent.
## 8. `example_ocsp.py` — OCSP parsing and building
[Source](example_ocsp.md) · [`example_ocsp.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_ocsp.py)
Bindings: `OCSPResponse.from_der`, `OCSPResponse.from_pem`, `OCSPResponse.to_pem`,
and all `OCSPResponse` properties; `OCSPResponseBuilder` (`responder_name`,
`responder_key_hash`, `produced_at`, `add_response`, `build_tbs`, `assemble`);
`OCSPSingleResponse`; `OCSPRequest.from_der`, `OCSPRequest.from_pem`, `OCSPRequest.to_der`,
and all `OCSPRequest` properties (`request_list`, `requestor_name`, `request_extensions`);
`CertID` properties (`hash_algorithm_oid`, `issuer_name_hash`, `issuer_key_hash`,
`serial_number`); `OCSPRequestBuilder` (`add_request`, `requestor_name`, `build_tbs`,
`build_tbs_inner`, `assemble`); `OCSPCertIDSpec`; `NameBuilder`.
- Parse a successful OCSP response; print `status`, `response_type_oid`, length of `response_bytes`.
- Parse a non-successful response (e.g. `tryLater`); confirm `response_bytes` is `None`.
- Round-trip through `to_pem` / `from_pem`.
- Build an OCSP response from scratch with `OCSPResponseBuilder`: create a
`OCSPSingleResponse` entry (SHA-1 name hash of issuer name, fixed key hash,
status=good), set `responder_key_hash`, call `build_tbs()`, assemble with a
dummy signature; verify `status == "successful"` and response OID.
- Demonstrate the `responder_name` variant using a DER Name from `NameBuilder`.
- Build an unsigned `OCSPRequest` with `OCSPRequestBuilder`: create an `OCSPCertIDSpec`
(SHA-1 issuer name hash, fixed key hash, serial), call `build_tbs()`, parse the result
back with `OCSPRequest.from_der`, and verify all `CertID` fields.
- Demonstrate the signed-request path: call `build_tbs_inner()`, assemble with a dummy
signature via `assemble()`, parse back and confirm `request_list` length.
- Demonstrate `requestor_name` on `OCSPRequestBuilder` using a DER Name from `NameBuilder`.
## 9. `example_pkcs7.py` — PKCS#7 certificate bundles
[Source](example_pkcs7.md) · [`example_pkcs7.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_pkcs7.py)
Bindings: `load_der_pkcs7_certificates`, `load_pem_pkcs7_certificates`.
- Load a `.p7b` file and print the subject of each extracted certificate.
- Demonstrate PEM-encoded PKCS#7 with `load_pem_pkcs7_certificates`.
- Show `ValueError` for non-PKCS#7 input.
## 10. `example_pkcs12.py` — PKCS#12 archive parsing and creation
[Source](example_pkcs12.md) · [`example_pkcs12.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_pkcs12.py)
Bindings: `load_pkcs12_certificates`, `load_pkcs12_keys`, `load_pkcs12`,
`create_pkcs12`.
- Parse a password-less PKCS#12 file; print subjects of extracted certificates.
- Extract private keys using `load_pkcs12_keys`; show raw PKCS#8 DER length.
- Extract both with `load_pkcs12`; show the `(certs, keys)` tuple.
- Parse an AES-256-CBC encrypted PKCS#12 with a password.
- Show `ValueError` for wrong password (encrypted case, with `openssl` feature).
- Build a PFX from extracted certificates using `create_pkcs12` without a password.
- Build a password-protected PFX with `create_pkcs12` (requires `openssl` feature).
- Build a cert+key PFX bundle.
- Roundtrip: build an archive then parse it back and verify the extracted certificates.
## 11. `example_pki_blocks.py` — Format-agnostic PKI reader
[Source](example_pki_blocks.md) · [`example_pki_blocks.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_pki_blocks.py)
Bindings: `read_pki_blocks`.
- Pass PEM, DER, PKCS#7, and PKCS#12 bytes to `read_pki_blocks` and print the
`(label, len(der))` tuples returned.
- Show PKCS#12 password handling.
## 12. `example_objectidentifier.py` — ObjectIdentifier constructors and operations
[Source](example_objectidentifier.md) · [`example_objectidentifier.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_objectidentifier.py)
Bindings: `ObjectIdentifier(str)`, `ObjectIdentifier.from_components`,
`ObjectIdentifier.from_der_value`, `ObjectIdentifier.components`,
`ObjectIdentifier.__eq__`, `ObjectIdentifier.__hash__`,
`Decoder.decode_oid`, `Encoder.encode_oid`, `Encoder.encode_oid_object`.
- Construct OIDs via all three constructors; verify they compare equal.
- Show `__eq__` working against a dotted string.
- Use OIDs as dict keys (demonstrate hashability).
- Round-trip through `encode_oid` / `decode_oid`.
- Show `from_der_value` with the raw content bytes from an implicit-tag context.
## 13. `example_oids_catalog.py` — `synta.oids` constant groups
[Source](example_oids_catalog.md) · [`example_oids_catalog.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_oids_catalog.py)
Bindings: every constant in `synta.oids` and `synta.oids.attr`,
plus the helper functions `identify_signature_algorithm`,
`identify_public_key_algorithm`.
- Print algorithm OIDs (RSA, EC, EdDSA, ML-DSA, ML-KEM).
- Print hash OIDs (SHA-2, SHA-3).
- Print SLH-DSA OIDs.
- Print prefix OIDs and demonstrate `components()`-based prefix matching.
- Print X.509v3 extension OIDs.
- Print EKU OIDs.
- Print PKINIT OIDs.
- Print MS PKI OIDs.
- Print all nine PKCS#9 attribute OIDs (`PKCS9_EMAIL_ADDRESS`, `PKCS9_CONTENT_TYPE`,
`PKCS9_MESSAGE_DIGEST`, `PKCS9_SIGNING_TIME`, `PKCS9_COUNTERSIGNATURE`,
`PKCS9_CHALLENGE_PASSWORD`, `PKCS9_EXTENSION_REQUEST`, `PKCS9_FRIENDLY_NAME`,
`PKCS9_LOCAL_KEY_ID`).
- Print every `synta.oids.attr` DN attribute OID with its RFC 4514 label.
## 14. `example_time_types.py` — UtcTime and GeneralizedTime
[Source](example_time_types.md) · [`example_time_types.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_time_types.py)
Bindings: `UtcTime(…)`, `UtcTime` properties (`year`, `month`, `day`, `hour`,
`minute`, `second`), `GeneralizedTime(…)`, `GeneralizedTime` properties,
`Encoder.encode_utc_time`, `Encoder.encode_utc_time_object`,
`Encoder.encode_generalized_time`, `Encoder.encode_generalized_time_object`,
`Decoder.decode_utc_time`, `Decoder.decode_generalized_time`.
- Construct both time types and inspect every property.
- Round-trip each through encode / decode; verify string representations.
- Show millisecond sub-second precision on `GeneralizedTime`.
- Show `ValueError` for out-of-range UTCTime year (< 1950 or > 2049).
- Demonstrate `encode_utc_time_object` and `encode_generalized_time_object` variants.
## 15. `example_integer_advanced.py` — Integer edge cases and bigint
[Source](example_integer_advanced.md) · [`example_integer_advanced.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_integer_advanced.py)
Bindings: `Integer(int)`, `Integer.from_bytes`, `Integer.from_u64`,
`Integer.to_int`, `Integer.to_i128`, `Integer.to_bytes`,
`Encoder.encode_integer` (bigint path), `Encoder.encode_integer_object`.
- Construct integers via all three constructors.
- Show `to_int()` succeeds for small values; raises `OverflowError` for 20-byte serials.
- Use `to_i128()` for up to 16-byte values (i128 max = 2¹²⁷−1); show `OverflowError` beyond that.
- Use `to_bytes()` for arbitrary-precision big-endian representation.
- Encode a 20-byte certificate serial number via `encode_integer(large_python_int)`.
- Verify `encode_integer_object` round-trip.
## 16. `example_string_types_advanced.py` — Alternative string constructors
[Source](example_string_types_advanced.md) · [`example_string_types_advanced.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_string_types_advanced.py)
Bindings: `TeletexString.from_latin1`, `TeletexString.from_str`,
`GeneralString.from_ascii`, `GeneralString.from_str`,
`UniversalString.from_bytes`, `BmpString.from_bytes`,
plus `to_bytes()` / `as_str()` on each.
- Construct `TeletexString` from bytes and Latin-1 strings; `GeneralString` from bytes and ASCII strings.
- Construct `UniversalString` and `BmpString` from raw UCS-4/UCS-2 byte buffers.
- Show `ValueError` when non-BMP code points are passed to `BmpString`.
- Round-trip each through the encoder / decoder.
## 17. `example_decoder_advanced.py` — Advanced Decoder operations
[Source](example_decoder_advanced.md) · [`example_decoder_advanced.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_decoder_advanced.py)
Bindings: `Decoder.decode_set`, `Decoder.peek_tag`, `Decoder.decode_raw_tlv`,
`Decoder.remaining_bytes`, `Decoder.decode_implicit_tag`, `Decoder.position`,
`Decoder.remaining`, `Decoder.is_empty`, `Decoder.decode_any_str`.
- Build a hand-crafted SET and decode it with `decode_set`.
- Use `peek_tag` in a loop to drive CHOICE dispatch.
- Capture unknown elements with `decode_raw_tlv`.
- Use `decode_implicit_tag` + `remaining_bytes` to decode a primitive implicit type
(e.g. `[2] IMPLICIT IA5String` for a dNSName GeneralName).
- Show `position()` and `remaining()` advancing through multi-element input.
- Use `decode_any_str()` to decode a mixed-string SEQUENCE without tag inspection.
## 18. `example_encoder_advanced.py` — Advanced Encoder operations
[Source](example_encoder_advanced.md) · [`example_encoder_advanced.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_encoder_advanced.py)
Bindings: `Encoder.encode_implicit_tag`, `Encoder.encode_set`,
`Encoder.encode_explicit_tag`, `Encoder.encode_sequence`,
and all `_object` variants not demonstrated elsewhere.
- Build a SET containing two PrintableStrings using `encode_set`.
- Encode an implicit context tag `[2] IMPLICIT IA5String` (dNSName).
- Encode a nested structure: SEQUENCE { [0] EXPLICIT SEQUENCE { INTEGER } }.
- Demonstrate every `_object` encode variant with a typed object sourced from a decode.
- Show `ValueError` for unknown tag class strings.
## 19. `example_krb5_principal.py` — Kerberos principal names
[Source](example_krb5_principal.md) · [`example_krb5_principal.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_krb5_principal.py)
Bindings: `synta.krb5.Krb5PrincipalName`, `synta.krb5.KRB5_PRINCIPAL_NAME_OID`,
and every `NT_*` constant.
- Construct `Krb5PrincipalName` instances for each name type (`NT_PRINCIPAL`,
`NT_SRV_INST`, `NT_SRV_HST`, `NT_ENTERPRISE`, `NT_WELLKNOWN`).
- Encode each with `to_der()` and decode back with `from_der()`.
- Verify realm, name_type, and components survive the round-trip.
- Show `__eq__` and `__repr__`.
- Print `KRB5_PRINCIPAL_NAME_OID` and demonstrate it matches `synta.oids.PKINIT_SAN`.
- Show `ValueError` for non-ASCII realm or component.
## 20. `example_krb5_pkinit.py` — PKINIT protocol classes
[Source](example_krb5_pkinit.md) · [`example_krb5_pkinit.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_krb5_pkinit.py)
Bindings: `EncryptionKey`, `Checksum`, `KDFAlgorithmId`, `IssuerAndSerialNumber`,
`ExternalPrincipalIdentifier`, `PKAuthenticator`, `AuthPack`, `PaPkAsReq`,
`DHRepInfo`, `KDCDHKeyInfo`, `ReplyKeyPack`, `PaPkAsRep`.
For each class: parse hand-crafted DER bytes with `from_der`, access every property,
and print a summary of key values.
## 21. `example_error_handling.py` — Exception catalogue
[Source](example_error_handling.md) · [`example_error_handling.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_error_handling.py)
Bindings: `synta.SyntaError`, `ValueError`, `OverflowError`, `EOFError`.
- Inspect `SyntaError` as a module exception class (MRO, `issubclass` check).
- Demonstrate `EOFError` from empty input, tag-only input, and truncated value in `Decoder`.
- Demonstrate `ValueError` from tag mismatch (decoding BOOLEAN as INTEGER).
- Demonstrate `ValueError` from DER constraint violations (non-canonical BOOLEAN, non-minimal INTEGER).
- Demonstrate `OverflowError` from `Integer.to_int()` and `to_i128()` on values exceeding the target type.
- Demonstrate `ValueError` from constructor validation: `BmpString` with a non-BMP character,
`GeneralizedTime` with an invalid month, `ObjectIdentifier` with a malformed string,
`Krb5PrincipalName` with a non-ASCII realm, `GeneralString.from_ascii` with a non-ASCII character.
## 22. `example_cms_encrypted_data.py` — CMS EncryptedData round-trip
[Source](example_cms_encrypted_data.md) · [`example_cms_encrypted_data.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_cms_encrypted_data.py)
Bindings: `synta.cms.EncryptedData`, `synta.cms.ID_AES128_CBC`,
`synta.cms.ID_AES192_CBC`, `synta.cms.ID_AES256_CBC`.
Requires the `openssl` Cargo feature (`maturin develop --features openssl`).
- Create an `EncryptedData` with `EncryptedData.create` (AES-128-CBC) and inspect
all properties: `version`, `content_type`, `content_encryption_algorithm_oid`,
`content_encryption_algorithm_params` (IV extraction), `encrypted_content`.
- Decrypt → replace text in plaintext → re-encrypt with a fresh random IV;
verify the round-trip with `to_der()` / `from_der()`.
- Encrypt with each of AES-128/192/256-CBC using `ID_AES128_CBC`,
`ID_AES192_CBC`, `ID_AES256_CBC`; confirm random IV differs across calls.
- Verify synta-produced ciphertext with `openssl enc -d` (synta → openssl interop).
- Inspect the `EncryptedData` DER structure with `openssl asn1parse`.
- Encrypt raw bytes with `openssl enc -e`, wrap in an `EncryptedData` DER
by hand, parse with `from_der`, and decrypt with synta (openssl → synta interop).
## 23. `example_x509_verify.py` — X.509 certificate chain verification
[Source](example_x509_verify.md) · [`example_x509_verify.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_x509_verify.py)
Bindings: `synta.x509.TrustStore`, `synta.x509.VerificationPolicy`,
`synta.x509.verify_server_certificate`, `synta.x509.verify_client_certificate`,
`synta.x509.X509VerificationError`.
Requires the `openssl` Cargo feature (`maturin develop --features openssl`).
- Build a self-signed root CA DER in memory with `openssl req -x509` and load it
into a `TrustStore`; print `store.len` and `repr(store)`.
- Verify a leaf certificate signed by that root with `verify_server_certificate`;
print the chain length and each certificate's subject with `synta.Certificate.from_der`.
- Demonstrate `VerificationPolicy` variants: single name, multi-name `any`, multi-name
`all`, fixed `validation_time`, `max_chain_depth`, `profile="rfc5280"`.
- Demonstrate client certificate verification with `verify_client_certificate`.
- Show that `X509VerificationError` is raised when the trust store does not contain
the issuer, the server name does not match the SAN, and the validation time is
outside the validity window.
## 24. `example_general_name.py` — Typed GeneralName API
[Source](example_general_name.md) · [`example_general_name.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_general_name.py)
Bindings: `synta.general_name.DNSName`, `synta.general_name.IPAddress`,
`synta.general_name.RFC822Name`, `synta.general_name.OtherName`,
`synta.general_name.UniformResourceIdentifier`, `synta.parse_general_names`.
- Call `cert.subject_alt_names()` on a certificate with four SANs (two
`dNSName`, one `iPAddress`, one `rfc822Name`); dispatch by `isinstance`.
- Use `cert.general_names(oid)` to retrieve SANs by extension OID.
- Use `synta.parse_general_names(san_der)` for low-level tag/bytes access.
- Demonstrate integer tag constants (`gn.DNS_NAME`, `gn.IP_ADDRESS`, etc.).
## 25. `example_pkixalgs.py` — RFC 3279 algorithm parameter types
[Source](example_pkixalgs.md) · [`example_pkixalgs.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_pkixalgs.py)
Bindings: `synta.pkixalgs.DssParms`, `synta.pkixalgs.ECParameters`,
`synta.pkixalgs.EcdsaSigValue`, `synta.pkixalgs.DssSigValue` and OID constants.
- Parse `DssParms` (DSA domain parameters P/Q/G) from hand-crafted DER; verify round-trip.
- Parse `ECParameters` in `namedCurve` form; access `arm` and `named_curve_oid`.
- Parse `EcdsaSigValue` (r and s components of an ECDSA signature).
- Use OID constants: `ID_DSA`, `ID_EC_PUBLIC_KEY`, `ECDSA_WITH_SHA256`, `PRIME256V1`.
## 26. `example_ac.py` — RFC 5755 Attribute Certificates
[Source](example_ac.md) · [`example_ac.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_ac.py)
Bindings: `synta.ac.AttributeCertificate` and related OID constants.
- Build a minimal RFC 5755 v2 Attribute Certificate from scratch in DER.
- Access all eight `AttributeCertificate` properties: `version`, `holder`,
`issuer`, `signature_algorithm`, `serial_number`, `not_before`, `not_after`,
`attributes`.
- Demonstrate OID constants: `ID_AT_ROLE`, `ID_PE_AC_AUDIT_IDENTITY`,
`ID_CE_SUBJECT_DIRECTORY_ATTRIBUTES`.
## 27. `example_ms_pki.py` — Microsoft PKI (AD CS) extension types
[Source](example_ms_pki.md) · [`example_ms_pki.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_ms_pki.py)
Bindings: `synta.ms_pki.MSCSTemplateV2`, `synta.ms_pki.RequestClientInfo`
and OID constants.
- Parse `MSCSTemplateV2` with major version only and with both versions; verify
`template_id`, `template_major_version`, `template_minor_version`, and
`to_der()` round-trip.
- Parse `RequestClientInfo` with all four fields present, with partial fields,
and from an empty SEQUENCE.
- Print all nineteen OID constants with their dot-notation values.
## 28. `example_spnego.py` — SPNEGO negotiation tokens (RFC 4178)
[Source](example_spnego.md) · [`example_spnego.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_spnego.py)
Bindings: `synta.spnego.NegTokenInit`, `synta.spnego.NegTokenResp`,
`synta.spnego.NegotiationToken`, `NEG_STATE_*` constants, `SPNEGO_OID`.
> **DER encoding note:** GssapiSpnego.asn1 uses `DEFINITIONS IMPLICIT TAGS`.
> The example builds all test vectors using IMPLICIT encoding helpers.
- Parse `NegTokenInit` with `mech_types` (two OIDs) and `mech_token`; verify
each property and confirm `req_flags`/`mech_list_mic` are absent.
- Parse an empty `NegTokenInit` SEQUENCE; verify `mech_types == []`.
- Parse `NegotiationToken` in the `negTokenInit` CHOICE arm (`0xa0`) and the
`negTokenResp` arm (`0xa1`).
- Parse a GSSAPI-wrapped token (`0x60` APPLICATION tag) and verify that
`from_der` strips the OID prefix automatically.
- Parse `NegTokenResp` with `neg_state` 3 (`NEG_STATE_REQUEST_MIC`) and a
`response_token`; verify `supported_mech` and `mech_list_mic`.
- Verify all four `NEG_STATE_*` integer constants and `SPNEGO_OID`.
## 29. `example_crmf.py` — CRMF certificate request messages
[Source](example_crmf.md) · [`example_crmf.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_crmf.py)
Bindings: `CertReqMsgBuilder`, `CertReqMessagesBuilder`, `CertReqMessages.from_der`,
`CertReqMsg.from_der`; OID constants from `synta.crmf`.
- Build a `CertReqMsg` with `CertReqMsgBuilder`: set subject name via `NameBuilder`,
add a `SubjectPublicKeyInfo` DER, set validity, and call `build()`.
- Assemble a batch with `CertReqMessagesBuilder.add(msg).build()`.
- DER round-trip via `CertReqMessages.from_der`; iterate the batch and inspect
each request's `cert_req_id`, subject, and public key fields.
- Print OID constants from `synta.crmf`.
## 30. `example_cmp.py` — CMP certificate management messages
[Source](example_cmp.md) · [`example_cmp.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_cmp.py)
Bindings: `CMPMessageBuilder`, `CMPMessage.from_der`; OID constants from `synta.cmp`.
- Build a `pkiConf` message with `CMPMessageBuilder`: set `sender_rfc822`,
`recipient_directory_name`, `transaction_id`, call `body_pkiconf()`, and `build()`.
- Build an `ir` (Initialization Request) that wraps a `CertReqMessages` body.
- DER round-trip via `CMPMessage.from_der`; inspect `pvno`, `body_type`,
`sender_der`, and nonce fields.
- Print OID constants from `synta.cmp`.
## 31. `example_mtc.py` — Merkle Tree Certificates
[Source](example_mtc.md) · [`example_mtc.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_mtc.py)
Bindings: `synta.mtc.ProofNode`, `synta.mtc.Subtree`, `synta.mtc.SubtreeProof`,
`synta.mtc.InclusionProof`, `synta.mtc.LogID`, `synta.mtc.CosignerID`,
`synta.mtc.Checkpoint`, `synta.mtc.SubtreeSignature`,
`synta.mtc.MerkleTreeCertEntry`, `synta.mtc.LandmarkID`.
- Parse `ProofNode` (left and right variants); verify `is_left` and `hash`.
- Parse `Subtree`; verify `start`, `end`, and `value`.
- Parse `SubtreeProof` with both subtree lists; verify element count.
- Parse `InclusionProof`; verify `log_entry_index`, `tree_size`, and path length.
- Parse `LogID`; verify `hash_algorithm_oid` and `public_key_der`.
- Parse `CosignerID`; verify `issuer_der` and `serial_number`.
- Parse `Checkpoint`; verify all five properties (`log_id`, `tree_size`, `tree_minimum_index`, `root_value`, `timestamp`).
- Parse `SubtreeSignature`; verify `cosigner`, `subtree`, `checkpoint`, `signature_algorithm_oid`, and `signature`.
- Parse `MerkleTreeCertEntry` in the `TbsCertEntry` CHOICE arm; verify
`tbs_cert_entry` with `issuer_der` and `subject_der`.
- Verify `repr()` output for `LandmarkID`.
## 32. `example_name_constraints.py` — NameConstraints extension (RFC 5280 §4.2.1.10)
[Source](example_name_constraints.md) · [`example_name_constraints.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_name_constraints.py)
Bindings: `synta.ext.NameConstraintsBuilder` (alias `NC`),
`synta.oids.NAME_CONSTRAINTS`, `Certificate.get_extension_value_der`,
`CertificateBuilder.add_extension`, `PrivateKey.generate_ec`, `NameBuilder`.
- Build a `NameConstraints` value with `permit_dns` (with and without a leading dot),
`exclude_dns`, `permit_ip` (8-byte IPv4 address+mask), `exclude_ip`,
and `permit_rfc822` using the `NC` alias.
- Verify the DER structure: decode the outer SEQUENCE and confirm the
`[0] IMPLICIT` (permittedSubtrees) and `[1] IMPLICIT` (excludedSubtrees)
CONSTRUCTED context tags via `Decoder`.
- Show that `permit_*`-only and `exclude_*`-only builders produce DER with
only the relevant IMPLICIT field present.
- Build a self-signed CA certificate with `NameConstraints` marked critical
(as required by RFC 5280 §4.2.1.10); look it up with
`get_extension_value_der(oids.NAME_CONSTRAINTS)`; walk `extensions_der`
to confirm the critical flag is set; verify DER round-trip.
- Confirm that `NC` (short alias) and `NameConstraintsBuilder` (full class
name) produce identical DER.
## 33. `example_acme_rfc8737.py` — ACME RFC 8737 TLS-ALPN challenge
[Source](example_acme_rfc8737.md) · [`example_acme_rfc8737.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_acme_rfc8737.py)
See [`example_acme_rfc8737.md`](example_acme_rfc8737.md) for details.
## 34. `example_schema.py` — ASN.1 structure definitions with `synta.schema`
[Source](example_schema.md) · [`example_schema.py` on Codeberg](https://codeberg.org/abbra/synta/src/branch/main/examples/example_schema.py)
Bindings: `synta.schema.asn1_sequence`, `synta.schema.asn1_choice`,
`synta.schema.asn1_field`.
- Define a CHOICE type with `@asn1_choice` over two time variants (`UtcTime`,
`GeneralizedTime`); encode and decode each variant; verify active field.
- Define a SEQUENCE with `@asn1_sequence` nesting the CHOICE type; verify
round-trip and that dataclass `__eq__` and `__repr__` are preserved.
- Show optional `[0] EXPLICIT` and `[2] IMPLICIT` tagged fields with
`asn1_field()`; verify absent fields decode as `None`.
- Encode a `List[synta.IA5String]` field as SEQUENCE OF; verify element count
and values after decoding.
- Show `ValueError` when encoding a CHOICE with all fields `None`.
- Show `ValueError` when encoding a SEQUENCE with a required field set to `None`.
- Show `TypeError` when `@asn1_sequence` is applied before `@dataclass`.