# 27. `example_ms_pki.py` — Microsoft PKI (AD CS) extension types
[← Example index](index.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.
## Source
```python
#!/usr/bin/env python3
"""
Example 22: Microsoft PKI (AD CS) certificate extensions.
Demonstrates: synta.ms_pki.MSCSTemplateV2, synta.ms_pki.RequestClientInfo,
and the OID constants defined in the synta.ms_pki submodule.
"""
import synta
import synta.ms_pki as ms_pki
def section(title):
print(f"\n{'─' * 60}\n{title}\n{'─' * 60}")
# ── DER building helpers ──────────────────────────────────────
def _enc(fn):
"""Encode one element and return its DER bytes."""
enc = synta.Encoder(synta.Encoding.DER)
fn(enc)
return enc.finish()
def _seq(*parts):
"""Wrap raw TLV bytes in a SEQUENCE."""
enc = synta.Encoder(synta.Encoding.DER)
enc.encode_sequence(b"".join(parts))
return enc.finish()
def _explicit(n, content):
"""Wrap bytes in a [n] EXPLICIT context tag (constructed)."""
enc = synta.Encoder(synta.Encoding.DER)
enc.encode_explicit_tag(n, "Context", content)
return enc.finish()
def _oid(dotted):
"""Encode an OID in dot-notation and return its DER bytes."""
return _enc(lambda e: e.encode_oid(synta.ObjectIdentifier(dotted)))
def _int(n):
"""Encode a Python integer as an ASN.1 INTEGER and return DER bytes."""
return _enc(lambda e: e.encode_integer(n))
def _utf8(s):
"""Encode a Python str as an ASN.1 UTF8String and return DER bytes."""
return _enc(lambda e: e.encode_utf8_string(s))
# ── Pre-built DER test vectors ────────────────────────────────
# MSCSTemplateV2 — szOID_CERTIFICATE_TEMPLATE (1.3.6.1.4.1.311.21.7)
# Enterprise template OID: 1.3.6.1.4.1.311.21.8.<enterprise>.<template>
# Example uses a representative enterprise + template suffix.
_TMPL_OID_DER = _oid("1.3.6.1.4.1.311.21.8.12345678.1")
_TMPL_MAJOR_DER = _int(100) # templateMajorVersion = 100
_TMPL_MINOR_DER = _int(5) # templateMinorVersion = 5 (OPTIONAL)
# MSCSTemplateV2 with major version only (minorVersion absent)
TMPL_V2_NO_MINOR_DER = _seq(_TMPL_OID_DER, _TMPL_MAJOR_DER)
# MSCSTemplateV2 with both major and minor version
TMPL_V2_FULL_DER = _seq(_TMPL_OID_DER, _TMPL_MAJOR_DER, _TMPL_MINOR_DER)
# RequestClientInfo — szOID_REQUEST_CLIENT_INFO (1.3.6.1.4.1.311.21.20)
# All four OPTIONAL fields present:
# clientId [0] INTEGER = 2 (Xen auto-enrollment; placeholder)
# machineName [1] UTF8String
# userName [2] UTF8String
# processName [3] UTF8String
_CLIENT_ID_FIELD = _explicit(0, _int(2))
_MACHINE_NAME_FIELD = _explicit(1, _utf8("MYWORKSTATION"))
_USER_NAME_FIELD = _explicit(2, _utf8("DOMAIN\\alice"))
_PROCESS_NAME_FIELD = _explicit(3, _utf8("certreq.exe"))
REQ_CLIENT_INFO_FULL_DER = _seq(
_CLIENT_ID_FIELD,
_MACHINE_NAME_FIELD,
_USER_NAME_FIELD,
_PROCESS_NAME_FIELD,
)
# RequestClientInfo — only machineName present (all others absent)
REQ_CLIENT_INFO_PARTIAL_DER = _seq(_MACHINE_NAME_FIELD)
# RequestClientInfo — empty SEQUENCE (all OPTIONAL fields absent)
REQ_CLIENT_INFO_EMPTY_DER = b"\x30\x00"
# ── Demo functions ────────────────────────────────────────────
def demo_template_v2_major_only():
section("MSCSTemplateV2 — major version only (minorVersion absent)")
tmpl = ms_pki.MSCSTemplateV2.from_der(TMPL_V2_NO_MINOR_DER)
assert str(tmpl.template_id) == "1.3.6.1.4.1.311.21.8.12345678.1"
assert tmpl.template_major_version == 100
assert tmpl.template_minor_version is None
print(f" template_id: {tmpl.template_id}")
print(f" template_major_version: {tmpl.template_major_version}")
print(f" template_minor_version: {tmpl.template_minor_version}")
print(f" repr: {repr(tmpl)}")
def demo_template_v2_full():
section("MSCSTemplateV2 — with both major and minor version")
tmpl = ms_pki.MSCSTemplateV2.from_der(TMPL_V2_FULL_DER)
assert str(tmpl.template_id) == "1.3.6.1.4.1.311.21.8.12345678.1"
assert tmpl.template_major_version == 100
assert tmpl.template_minor_version == 5
print(f" template_id: {tmpl.template_id}")
print(f" template_major_version: {tmpl.template_major_version}")
print(f" template_minor_version: {tmpl.template_minor_version}")
print(f" repr: {repr(tmpl)}")
def demo_template_v2_roundtrip():
section("MSCSTemplateV2 — to_der() round-trip")
# Parse, re-encode, and re-parse. The recovered fields must be identical.
tmpl1 = ms_pki.MSCSTemplateV2.from_der(TMPL_V2_FULL_DER)
der2 = tmpl1.to_der()
tmpl2 = ms_pki.MSCSTemplateV2.from_der(der2)
assert der2 == TMPL_V2_FULL_DER
assert str(tmpl2.template_id) == str(tmpl1.template_id)
assert tmpl2.template_major_version == tmpl1.template_major_version
assert tmpl2.template_minor_version == tmpl1.template_minor_version
print(f" original DER: {TMPL_V2_FULL_DER.hex()}")
print(f" to_der() output: {der2.hex()}")
print(f" DER round-trip matches ✓")
print(f" template_id: {tmpl2.template_id}")
print(f" template_major_version: {tmpl2.template_major_version}")
print(f" template_minor_version: {tmpl2.template_minor_version}")
def demo_request_client_info_full():
section("RequestClientInfo — all four OPTIONAL fields present")
info = ms_pki.RequestClientInfo.from_der(REQ_CLIENT_INFO_FULL_DER)
# clientId: numeric enrollment type
assert info.client_id == 2
# machineName: NetBIOS / DNS machine name
assert info.machine_name == "MYWORKSTATION"
# userName: DOMAIN\user format
assert info.user_name == "DOMAIN\\alice"
# processName: enrolling process executable name
assert info.process_name == "certreq.exe"
print(f" client_id: {info.client_id}")
print(f" machine_name: {info.machine_name}")
print(f" user_name: {info.user_name}")
print(f" process_name: {info.process_name}")
print(f" repr: {repr(info)}")
def demo_request_client_info_partial():
section("RequestClientInfo — machineName only (other fields absent)")
info = ms_pki.RequestClientInfo.from_der(REQ_CLIENT_INFO_PARTIAL_DER)
assert info.client_id is None
assert info.machine_name == "MYWORKSTATION"
assert info.user_name is None
assert info.process_name is None
print(f" client_id: {info.client_id}")
print(f" machine_name: {info.machine_name}")
print(f" user_name: {info.user_name}")
print(f" process_name: {info.process_name}")
print(f" repr: {repr(info)}")
def demo_request_client_info_empty():
section("RequestClientInfo — empty SEQUENCE (all fields absent)")
info = ms_pki.RequestClientInfo.from_der(REQ_CLIENT_INFO_EMPTY_DER)
assert info.client_id is None
assert info.machine_name is None
assert info.user_name is None
assert info.process_name is None
print(f" client_id: {info.client_id}")
print(f" machine_name: {info.machine_name}")
print(f" user_name: {info.user_name}")
print(f" process_name: {info.process_name}")
print(f" all fields None ✓")
def demo_oid_constants():
section("OID constants — synta.ms_pki module")
# AD CS / Certificate Services OIDs (1.3.6.1.4.1.311.21.*)
print(f" ID_MS_CERTSRV_CA_VERSION: {ms_pki.ID_MS_CERTSRV_CA_VERSION}")
print(f" ID_MS_CERTSRV_PREVIOUS_CERT_HASH:{ms_pki.ID_MS_CERTSRV_PREVIOUS_CERT_HASH}")
print(f" ID_MS_CRL_VIRTUAL_BASE: {ms_pki.ID_MS_CRL_VIRTUAL_BASE}")
print(f" ID_MS_CRL_NEXT_PUBLISH: {ms_pki.ID_MS_CRL_NEXT_PUBLISH}")
print(f" ID_MS_ENTERPRISE_OID_ROOT: {ms_pki.ID_MS_ENTERPRISE_OID_ROOT}")
print(f" ID_MS_REQUEST_CLIENT_INFO: {ms_pki.ID_MS_REQUEST_CLIENT_INFO}")
print(f" ID_MS_ENCRYPTED_KEY_HASH: {ms_pki.ID_MS_ENCRYPTED_KEY_HASH}")
print(f" ID_MS_CERTSRV_CROSSCA_VERSION: {ms_pki.ID_MS_CERTSRV_CROSSCA_VERSION}")
# Extended key usage OIDs (1.3.6.1.4.1.311.10.3.*)
print(f" ID_MS_KP_CA_EXCHANGE: {ms_pki.ID_MS_KP_CA_EXCHANGE}")
print(f" ID_MS_KP_KEY_RECOVERY_AGENT: {ms_pki.ID_MS_KP_KEY_RECOVERY_AGENT}")
print(f" ID_MS_KP_CTL_USAGE_SIGNING: {ms_pki.ID_MS_KP_CTL_USAGE_SIGNING}")
print(f" ID_MS_KP_TIME_STAMP_SIGNING: {ms_pki.ID_MS_KP_TIME_STAMP_SIGNING}")
print(f" ID_MS_KP_EFS_CRYPTO: {ms_pki.ID_MS_KP_EFS_CRYPTO}")
print(f" ID_MS_KP_EFS_RECOVERY: {ms_pki.ID_MS_KP_EFS_RECOVERY}")
print(f" ID_MS_KP_KEY_RECOVERY: {ms_pki.ID_MS_KP_KEY_RECOVERY}")
print(f" ID_MS_KP_DOCUMENT_SIGNING: {ms_pki.ID_MS_KP_DOCUMENT_SIGNING}")
print(f" ID_MS_KP_LIFETIME_SIGNING: {ms_pki.ID_MS_KP_LIFETIME_SIGNING}")
print(f" ID_MS_AUTO_ENROLL_CTL_USAGE: {ms_pki.ID_MS_AUTO_ENROLL_CTL_USAGE}")
print(f" ID_MS_APPLICATION_CERT_POLICIES: {ms_pki.ID_MS_APPLICATION_CERT_POLICIES}")
# Verify a few known OID string values
assert str(ms_pki.ID_MS_CERTSRV_CA_VERSION) == "1.3.6.1.4.1.311.21.1"
assert str(ms_pki.ID_MS_ENTERPRISE_OID_ROOT) == "1.3.6.1.4.1.311.21.8"
assert str(ms_pki.ID_MS_REQUEST_CLIENT_INFO) == "1.3.6.1.4.1.311.21.20"
assert str(ms_pki.ID_MS_KP_CTL_USAGE_SIGNING) == "1.3.6.1.4.1.311.10.3.1"
assert str(ms_pki.ID_MS_KP_EFS_CRYPTO) == "1.3.6.1.4.1.311.10.3.4"
assert str(ms_pki.ID_MS_AUTO_ENROLL_CTL_USAGE) == "1.3.6.1.4.1.311.20.1"
print(f" selected OID string values verified ✓")
def main():
print("=" * 60)
print("Example 22: Microsoft PKI (AD CS) certificate extensions")
print("=" * 60)
demo_template_v2_major_only()
demo_template_v2_full()
demo_template_v2_roundtrip()
demo_request_client_info_full()
demo_request_client_info_partial()
demo_request_client_info_empty()
demo_oid_constants()
print("\nAll MS PKI examples completed.")
if __name__ == "__main__":
main()
```