synta-python
Table of Contents generated with DocToc
Python extension module crate for the synta ASN.1 library.
Overview
This crate builds the _synta native extension module using PyO3 and
maturin. It exposes the synta ASN.1 encoder/decoder and the
synta-certificate X.509 parser to Python 3.8+ through a low-overhead Rust-native API.
The resulting module is imported as synta._synta and re-exported through the synta
Python package. End-users should refer to python/README.md and
docs/PYTHON_BINDINGS.md for usage documentation.
Module Structure
| Source file | Contents |
|---|---|
src/lib.rs |
Module registration, Encoding enum, pem_to_der, der_to_pem, top-level exports |
src/decoder.rs |
Decoder class wrapping synta::Decoder; includes decode_any_str() |
src/encoder.rs |
Encoder class wrapping synta::Encoder |
src/types.rs |
Python wrappers for all ASN.1 primitive types |
src/error.rs |
SyntaError Python exception |
src/certificate.rs |
PKI types: ObjectIdentifier, Certificate, CertificationRequest, CertificateList, OCSPResponse, PKCS loaders, synta.oids / synta.oids.attr submodules |
src/pkinit.rs |
PKINIT classes: EncryptionKey, Checksum, KDFAlgorithmId, PKAuthenticator, AuthPack, PaPkAsReq/Rep, etc. |
src/krb5.rs |
synta.krb5 submodule registration: Krb5PrincipalName, PKINIT classes, NT_* constants |
All PyO3 bindings live directly in synta-python. The synta-certificate and synta-krb5
library crates have no PyO3 dependency; their types are wrapped here in src/certificate.rs
and src/pkinit.rs respectively.
Python module hierarchy
synta top-level module (_synta extension)
├── Encoding enum: DER / BER / CER
├── SyntaError exception
├── Decoder / Encoder streaming ASN.1 codec
├── Integer, OctetString, BitString, Boolean, Real, Null
├── UtcTime, GeneralizedTime
├── Utf8String, PrintableString, IA5String, NumericString,
│ TeletexString, VisibleString, GeneralString,
│ UniversalString, BmpString
├── TaggedElement, RawElement
├── ObjectIdentifier OID type (from synta-certificate)
├── Certificate, CertificationRequest,
│ CertificateList, OCSPResponse
├── load_der_pkcs7_certificates, load_pem_pkcs7_certificates,
│ load_pkcs12_certificates, load_pkcs12_keys, read_pki_blocks
├── parse_general_names parse SEQUENCE OF GeneralName → list[tuple[int, bytes]]
├── parse_name_attrs parse Name DER → list[tuple[str, str]]
├── pem_to_der, der_to_pem
├── synta.general_name GeneralName tag constants
│ ├── OTHER_NAME (0), RFC822_NAME (1), DNS_NAME (2), X400_ADDRESS (3)
│ ├── DIRECTORY_NAME (4), EDI_PARTY_NAME (5), URI (6)
│ ├── IP_ADDRESS (7), REGISTERED_ID (8)
├── synta.krb5 Kerberos V5 / PKINIT submodule
│ ├── Krb5PrincipalName
│ ├── EncryptionKey, Checksum, KDFAlgorithmId
│ ├── IssuerAndSerialNumber, ExternalPrincipalIdentifier
│ ├── PKAuthenticator, AuthPack, PaPkAsReq
│ ├── DHRepInfo, KDCDHKeyInfo, ReplyKeyPack, PaPkAsRep
│ ├── KRB5_PRINCIPAL_NAME_OID
│ └── NT_UNKNOWN … NT_SRV_HST_DOMAIN
└── synta.oids well-known OID constants
├── ML_DSA_44/65/87, ML_KEM_512/768/1024
├── SLH_DSA_SHA2_*/SHAKE_* (12 variants)
├── ED25519, ED448
├── RSA_ENCRYPTION, SHA*_WITH_RSA, RSA
├── EC_PUBLIC_KEY, ECDSA_WITH_SHA*, ECDSA, EC_CURVE_*
├── SHA224/256/384/512, SHA512_224/256
├── SHA3_224/256/384/512, SHAKE128/256
├── SUBJECT_KEY_IDENTIFIER, KEY_USAGE, SUBJECT_ALT_NAME,
│ ISSUER_ALT_NAME, BASIC_CONSTRAINTS,
│ CRL_DISTRIBUTION_POINTS, CERTIFICATE_POLICIES,
│ AUTHORITY_KEY_IDENTIFIER, EXTENDED_KEY_USAGE,
│ AUTHORITY_INFO_ACCESS, CT_PRECERT_SCTS
├── KP_SERVER_AUTH, KP_CLIENT_AUTH, KP_CODE_SIGNING,
│ KP_EMAIL_PROTECTION, KP_TIME_STAMPING,
│ KP_OCSP_SIGNING, ANY_EXTENDED_KEY_USAGE
├── PKINIT_SAN, PKINIT_KP_CLIENT_AUTH, PKINIT_KP_KDC,
│ PKINIT_AUTH_DATA, PKINIT_DHKEY_DATA, PKINIT_RKEY_DATA,
│ PKINIT_KDF, PKINIT_KDF_SHA1/256/384/512
├── MS_SAN_UPN, MS_CERTIFICATE_TEMPLATE_NAME,
│ MS_CERTIFICATE_TEMPLATE, MS_KP_SMARTCARD_LOGON,
│ MS_NTDS_REPLICATION
├── 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
├── identify_signature_algorithm(oid) -> str
├── identify_public_key_algorithm(oid) -> str | None
├── ec_curve_short_name(oid) -> str | None
├── ec_curve_nist_name(oid) -> str | None
├── ec_curve_key_bits(oid) -> int | None
├── extension_oid_name(oid) -> str
└── synta.oids.attr DN attribute OIDs
└── COMMON_NAME, COUNTRY, STATE, LOCALITY,
ORGANIZATION, ORG_UNIT, ORG_IDENTIFIER,
STREET, SURNAME, GIVEN_NAME, INITIALS,
TITLE, SERIAL_NUMBER, EMAIL_ADDRESS,
USER_ID, DOMAIN_COMPONENT
Building
The extension module is built with maturin. The workspace pyproject.toml points to this
crate automatically.
# Install maturin (once)
# Development install into active virtualenv
# Build release wheel
# Install built wheel
Requirements:
- Rust toolchain (1.70 or later)
- Python 3.8 or later (abi3 stable ABI; compatible with CPython 3.8–3.14+)
- maturin 1.x
Testing
# Run the Python test suite from the workspace root
# Or via the CI helper script
Dependencies
| Crate | Role |
|---|---|
synta |
Core ASN.1 encoder/decoder |
synta-certificate |
X.509 PKI types + OID constants |
synta-krb5 |
Kerberos V5 / PKINIT types |
pyo3 0.26 |
Python/Rust interop (abi3-py38 feature) |
Performance Design
- Input bytes are borrowed:
PyDecoderholds aPy<PyBytes>reference and passes a&[u8]slice to the Rust decoder — no copy of the input buffer. - Python string caching:
CertificatestoresOnceLock<Py<PyString>>for each string field. The first access constructs the Python object; subsequent calls useclone_ref()(~0.3 µs for all fields together). - Zero-copy certificate fields:
issuer,subject, andextensionsare stored as raw DER byte spans inside the RustCertificate; the Python binding wraps them inPyByteson first access. - Lazy decode: field values are decoded on demand rather than at parse time.
See docs/performance.md and python/README.md for benchmark numbers.
Cargo Features
| Feature | Description |
|---|---|
extension-module |
Required by PyO3 for native extension module builds (set via maturin) |
abi3-py38 |
Builds against the stable Python 3.8 ABI for broad wheel compatibility |
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.