# Module Layout
## Extension module layout
The `synta` Python package is delivered as three separate native extension
modules. End users only need `import synta`; the subsystem modules are loaded
automatically by `python/synta/__init__.py`.
| `_synta.abi3.so` | maturin (`synta-python` crate) | Core types, X.509/PKI, CMS, OIDs, and all submodules that live in `_synta` |
| `_krb5.abi3.so` | cargo (`synta-python-krb5` crate) | `synta.krb5` and `synta.spnego` |
| `_mtc.abi3.so` | cargo (`synta-python-mtc` crate) | `synta.mtc` |
`synta-python-common` is a Rust `rlib` (no Python module of its own) that is
statically linked into each cdylib. It provides `SyntaErr` (error bridging),
`install_submodule` (registers a `PyModule` in `sys.modules`), and `opt_py_list`.
### Type identity across module boundaries
`synta.ObjectIdentifier` and `synta.SyntaError` are defined only in `_synta.so`.
At init time each subsystem module imports `synta._synta` from `sys.modules` and
caches a reference to `ObjectIdentifier` via `OnceLock<Py<PyType>>`. All OID
values returned from `_krb5` or `_mtc` are instances of that cached class, so
`isinstance(oid, synta.ObjectIdentifier)` returns `True` regardless of which
`.so` produced the value.
### Import order guarantee
`python/synta/__init__.py` imports `synta._synta` first, then imports
`synta._krb5` and `synta._mtc`. The subsystem modules assert that `synta._synta`
is already in `sys.modules` and raise `ImportError` if it is not. Importing a
subsystem module directly without first doing `import synta` is therefore not
supported.
## Crate-to-module mapping
| `synta` | `_synta.abi3.so` | `Encoding`, `Decoder`, `Encoder`, all primitive types |
| `synta-certificate` | `_synta.abi3.so` | `ObjectIdentifier`, `Certificate`, `CertificationRequest`, `CertificateList`, `OCSPResponse`, `PublicKey`, `PrivateKey`, `CertificateBuilder`, `CsrBuilder`, `NameBuilder`, `CertificateListBuilder`, `OCSPResponseBuilder`, `OCSPSingleResponse`, `synta.ext`, `synta.oids`, PKCS#7/12 loaders, `synta.pkixalgs`, `synta.ac`, `synta.crmf`, `synta.cmp`, `synta.pkcs8`, `synta.pkcs9`, `synta.kem`; `OpensslSignatureVerifier` |
| `synta-krb5` | `_krb5.abi3.so` | `synta.krb5`: `Krb5PrincipalName`, PKINIT classes, `NT_*`/`ETYPE_*` constants |
| `synta-mtc` | `_mtc.abi3.so` | `synta.mtc`: all Merkle Tree Certificate types |
| `synta-x509-verification` | `_synta.abi3.so` | `synta.x509`: `TrustStore`, `CrlStore`, `VerificationPolicy`, chain verification functions |
| `synta-python-common` | (rlib, no module) | `SyntaErr`, `install_submodule`, `opt_py_list` — statically linked into all cdylibs |
The package surface visible to Python is defined in `python/synta/__init__.py`,
which re-exports everything from `_synta` and binds `krb5`, `mtc`, and `spnego`
as attributes of the top-level `synta` namespace.
## Full module tree
```
synta # top-level package
├── Encoder # ASN.1 encoder
├── SyntaError # exception class
├── __version__ # str, e.g. "0.1.0"
│
├── Integer # primitive types
├── OctetString
├── ObjectIdentifier
├── BitString
├── Boolean
├── Real
├── Null
├── UtcTime
├── GeneralizedTime
├── Utf8String
├── PrintableString
├── IA5String
├── NumericString
├── TeletexString
├── VisibleString
├── GeneralString
├── UniversalString
├── BmpString
├── TaggedElement
├── RawElement
│
├── Certificate # PKI types
├── CertificationRequest
├── CertificateList
├── OCSPResponse
├── PublicKey # backend-agnostic key types (RSA, EC, EdDSA, ML-DSA, ML-KEM)
├── PrivateKey
├── CertificateBuilder # X.509 v3 certificate builder
├── CsrBuilder # PKCS#10 CSR builder
├── NameBuilder # X.509 distinguished name builder
├── CertificateListBuilder # RFC 5280 CRL TBS builder
├── OCSPResponseBuilder # RFC 6960 OCSP TBS builder
├── OCSPSingleResponse # single OCSP response entry (passed to OCSPResponseBuilder)
│
├── pem_to_der() # PEM helpers
├── der_to_pem()
│
├── load_der_pkcs7_certificates() # PKCS#7 / PKCS#12 loaders
├── load_pem_pkcs7_certificates()
├── load_pkcs12_certificates()
├── load_pkcs12_keys()
├── load_pkcs12()
├── read_pki_blocks()
│
├── ext # synta.ext submodule — extension value builders
│ ├── basic_constraints(), key_usage()
│ ├── subject_key_identifier(), authority_key_identifier() # require openssl feature
│ ├── KEYID_RFC5280, KEYID_RFC7093M1, … # key-id method constants
│ ├── KU_DIGITAL_SIGNATURE, KU_KEY_CERT_SIGN, … # key-usage bitmask constants
│ ├── SubjectAlternativeNameBuilder (alias: SAN)
│ ├── AuthorityInformationAccessBuilder (alias: AIA)
│ ├── ExtendedKeyUsageBuilder (alias: EKU)
│ ├── NameConstraintsBuilder (alias: NC)
│ ├── CRLDistributionPointsBuilder (alias: CDP)
│ ├── IssuerAlternativeNameBuilder (alias: IAN)
│ ├── IssuingDistributionPointBuilder (alias: IDP)
│ └── CertificatePoliciesBuilder (alias: CP)
│
├── general_name # synta.general_name submodule
│ ├── OTHER_NAME, RFC822_NAME, DNS_NAME, X400_ADDRESS
│ ├── DIRECTORY_NAME, EDI_PARTY_NAME, URI
│ ├── IP_ADDRESS, REGISTERED_ID (integer tag constants)
│ ├── OtherName, RFC822Name, DNSName, X400Address
│ ├── DirectoryName, EDIPartyName
│ └── UniformResourceIdentifier, IPAddress, RegisteredID
│
├── oids # synta.oids submodule
│ ├── RSA_ENCRYPTION, SHA256_WITH_RSA, ...
│ ├── EC_PUBLIC_KEY, EC_CURVE_P256, ...
│ ├── ED25519, ED448, ML_DSA_44, ...
│ ├── SUBJECT_ALT_NAME, BASIC_CONSTRAINTS, ...
│ ├── KP_SERVER_AUTH, KP_CLIENT_AUTH, ...
│ ├── PKINIT_SAN, PKINIT_KP_CLIENT_AUTH, ...
│ ├── MS_SAN_UPN, MS_KP_SMARTCARD_LOGON, ...
│ └── attr # synta.oids.attr submodule
│ ├── COMMON_NAME, ORGANIZATION, COUNTRY, ...
│ └── ...
│
├── krb5 # synta.krb5 submodule [from _krb5.abi3.so]
│ ├── KRB5_PRINCIPAL_NAME_OID
│ ├── NT_UNKNOWN, NT_PRINCIPAL, NT_SRV_INST, ...
│ ├── Krb5PrincipalName
│ ├── EncryptionKey
│ ├── Checksum
│ ├── KDFAlgorithmId
│ ├── IssuerAndSerialNumber
│ ├── ExternalPrincipalIdentifier
│ ├── PKAuthenticator
│ ├── AuthPack
│ ├── PaPkAsReq
│ ├── DHRepInfo
│ ├── KDCDHKeyInfo
│ ├── ReplyKeyPack
│ └── PaPkAsRep
│
├── pkixalgs # synta.pkixalgs submodule (RFC 3279)
│ ├── DssParms, DssSigValue, EcdsaSigValue, ECParameters
│ └── ID_DSA, ID_EC_PUBLIC_KEY, ECDSA_WITH_SHA256, PRIME256V1, ...
│
├── ac # synta.ac submodule (RFC 5755)
│ ├── AttributeCertificate # parse / PEM / verify_issued_by
│ ├── AttributeCertificateBuilder
│ └── ID_AT_ROLE, ID_AT_CLEARANCE, ID_PE_AC_AUDIT_IDENTITY, ...
│
├── crmf # synta.crmf submodule (RFC 4211)
│ ├── CertReqMessages, CertReqMsg
│ ├── CertReqMsgBuilder, CertReqMessagesBuilder
│ ├── PUB_METHOD_DONT_CARE, PUB_METHOD_X500, PUB_METHOD_WEB, PUB_METHOD_LDAP
│ └── ID_REG_CTRL_REG_TOKEN, ID_REG_CTRL_AUTHENTICATOR, ...
│
├── cmp # synta.cmp submodule (RFC 9810)
│ ├── CMPMessage
│ ├── CMPMessageBuilder
│ └── ID_PASSWORD_BASED_MAC, ID_DHBASED_MAC, ID_KP_CM_KGA, ...
│
├── pkcs8 # synta.pkcs8 submodule (RFC 5958 / PKCS#8)
│ ├── OneAsymmetricKey # parse DER-encoded private-key envelope
│ └── PrivateKeyInfo # alias for OneAsymmetricKey
│
├── pkcs9 # synta.pkcs9 submodule (RFC 2985 / PKCS#9)
│ ├── ID_PKCS_9, ID_EMAIL_ADDRESS, ID_CONTENT_TYPE, ID_MESSAGE_DIGEST
│ ├── ID_SIGNING_TIME, ID_COUNTERSIGNATURE, ID_CHALLENGE_PASSWORD
│ └── ID_EXTENSION_REQUEST, ID_FRIENDLY_NAME, ID_LOCAL_KEY_ID, ...
│
├── kem # synta.kem submodule (RFC 9629 / FIPS 203)
│ ├── KEMRecipientInfo # KEM recipient structure in CMS EnvelopedData
│ ├── CMSORIforKEMOtherInfo # KDF input structure for KEMRecipientInfo
│ ├── ID_ML_KEM_512, ID_ML_KEM_768, ID_ML_KEM_1024
│ └── ID_ORI, ID_ORI_KEM
│
├── spnego # synta.spnego submodule (RFC 4178) [from _krb5.abi3.so]
│ ├── NegTokenInit # initiator proposal (mech_types, mech_token, …)
│ ├── NegTokenResp # acceptor response (neg_state, supported_mech, …)
│ ├── NegotiationToken # CHOICE wrapper; from_der handles GSSAPI 0x60 form
│ ├── NEG_STATE_ACCEPT_COMPLETED, NEG_STATE_ACCEPT_INCOMPLETE
│ ├── NEG_STATE_REJECT, NEG_STATE_REQUEST_MIC
│ └── SPNEGO_OID # "1.3.6.1.5.5.2"
│
├── ms_pki # synta.ms_pki submodule (Microsoft AD CS)
│ ├── MSCSTemplateV2 # id-ms-certificate-template (OID 1.3.6.1.4.1.311.21.7)
│ ├── RequestClientInfo # id-ms-request-Client-Info (OID 1.3.6.1.4.1.311.21.20)
│ └── ID_MS_CERTSRV_CA_VERSION, ID_MS_KP_CA_EXCHANGE, ID_MS_KP_EFS_CRYPTO, …
│
├── mtc # synta.mtc submodule [from _mtc.abi3.so]
│ ├── ProofNode, Subtree, SubtreeProof, InclusionProof
│ ├── LogID, CosignerID, Checkpoint, SubtreeSignature
│ ├── TbsCertificateLogEntry, MerkleTreeCertEntry
│ ├── LandmarkID, StandaloneCertificate, LandmarkCertificate
│ └── (all classes parsed via from_der; names are raw DER, pass to parse_name_attrs)
│
└── x509 # synta.x509 submodule (RFC 5280 / CABF path validation)
├── TrustStore # trusted root CA store (DER bytes)
├── CrlStore # CRL revocation checking store (DER bytes)
├── OcspStore # pre-fetched OCSP response store (DER bytes)
├── VerificationPolicy # server_names, name_match, validation_time, max_chain_depth, profile
├── X509VerificationError # raised on any chain or policy failure
├── verify_server_certificate(leaf, intermediates, store, policy, crls=None, ocsp=None) → list[bytes]
└── verify_client_certificate(leaf, intermediates, store, policy, crls=None, ocsp=None) → list[bytes]
```