import synta
def _alg_id_with_null(oid: synta.ObjectIdentifier) -> bytes:
inner = synta.Encoder(synta.Encoding.DER)
inner.encode_oid(oid)
inner.encode_null()
outer = synta.Encoder(synta.Encoding.DER)
outer.encode_sequence(inner.finish())
return bytes(outer.finish())
def _der_length(n: int) -> bytes:
if n < 0x80:
return bytes([n])
if n < 0x100:
return bytes([0x81, n])
return bytes([0x82, n >> 8, n & 0xFF])
_SHA1_ALG: bytes = _alg_id_with_null(synta.ObjectIdentifier("1.3.14.3.2.26"))
_SHA256_WITH_RSA_ALG: bytes = _alg_id_with_null(synta.oids.SHA256_WITH_RSA)
_OCSP_SUCCESS_DER = bytes.fromhex(
"308201c40a0100a08201bd308201b906092b0601050507300101048201aa3082"
"01a630818fa216041451faf8a55a16074dc0703456a9a831e6f1f8d1b8180f32"
"303236303331303136303033345a30643062303a300906052b0e03021a050004"
"14bf7052c8b9c0f760c89123e099815eb2c0394226041451faf8a55a16074dc0"
"703456a9a831e6f1f8d1b802012a8000180f32303236303130313030303030305a"
"30110a0f32303236303130313030303030305a300d06092a864886f70d01010b"
"050003820101004de5a70defb08fe67d2ae1c4ab1ce22db43707db4ca3b65537"
"a99cf799acbda8194697f4aaf51ab13d7c36ff45abbff19ebd1071d329b30058"
"025185837125cba733ae42413ab56899d408b934121b16d8325331392a343772"
"083daa11da186476ea1fb4201c7bc1ac71d380357ff78071b18ecdbfdd6b1c0c"
"0ab996dae5475d849d27b2c22780b4dc76371eaaaa487d11ed13d48bfd121c9f"
"847f82ff70bf0143977d06f3f59e70cd8332976058e8dcf23bc1cd2b520ddc36"
"5a61cc81d6e2e881719056d4db925eb4d86ab4f116f6fc376365c85912dea5b3"
"4983cea9efe51cfbcbbabef08263aa39bc5f1742e9ecf0986b09025b56ed15a2"
"a2f8a012fbaad5"
)
_OCSP_TRYLATER_DER = bytes.fromhex("30030a0103")
def section(title):
print(f"\n{'─' * 60}\n{title}\n{'─' * 60}")
def demo_successful_response():
section("Successful OCSP response")
resp = synta.OCSPResponse.from_der(_OCSP_SUCCESS_DER)
print(f" status: {resp.status}")
print(f" response_type_oid: {resp.response_type_oid}")
print(f" response_bytes: <{len(resp.response_bytes)} bytes>")
print(f" to_der(): <{len(resp.to_der())} bytes>")
assert resp.status == "successful"
assert resp.response_type_oid is not None
assert str(resp.response_type_oid) == "1.3.6.1.5.5.7.48.1.1"
assert resp.response_bytes is not None
def demo_trylater_response():
section("Non-successful OCSP response — tryLater")
resp = synta.OCSPResponse.from_der(_OCSP_TRYLATER_DER)
print(f" status: {resp.status}")
print(f" response_type_oid: {resp.response_type_oid!r} (None for error responses)")
print(f" response_bytes: {resp.response_bytes!r} (None for error responses)")
assert resp.status == "tryLater"
assert resp.response_type_oid is None
assert resp.response_bytes is None
def demo_all_status_values():
section("All OCSP response status strings")
status_values = [
(0, "successful"),
(1, "malformedRequest"),
(2, "internalError"),
(3, "tryLater"),
(5, "sigRequired"),
(6, "unauthorized"),
]
for code, name in status_values:
der = bytes([0x30, 0x03, 0x0a, 0x01, code])
resp = synta.OCSPResponse.from_der(der)
print(f" ENUMERATED({code}) → status={resp.status!r}")
assert resp.status == name
def demo_to_der_roundtrip():
section("to_der() round-trip")
resp = synta.OCSPResponse.from_der(_OCSP_SUCCESS_DER)
der2 = resp.to_der()
assert der2 == _OCSP_SUCCESS_DER
print(" to_der() round-trip: OK")
def demo_pem_roundtrip():
section("from_pem / to_pem round-trip")
resp = synta.OCSPResponse.from_der(_OCSP_SUCCESS_DER)
pem = synta.OCSPResponse.to_pem(resp)
assert pem.startswith(b"-----BEGIN OCSP RESPONSE-----")
print(f" to_pem(): {len(pem)} bytes")
resp2 = synta.OCSPResponse.from_pem(pem)
assert resp2.status == resp.status
assert resp2.response_bytes == resp.response_bytes
print(" from_pem() round-trip: OK")
def demo_ocsp_builder():
section("OCSPResponseBuilder — build a complete OCSPResponse")
name_der = synta.NameBuilder().common_name("Test CA").build()
name_hash = synta.digest("sha1", name_der)
key_hash = bytes(20)
serial = bytes([0x01])
single = synta.OCSPSingleResponse(
hash_algorithm_der=_SHA1_ALG,
issuer_name_hash=name_hash,
issuer_key_hash=key_hash,
serial=serial,
status=0, this_update="20260101000000Z",
next_update="20260701000000Z",
)
tbs = (
synta.OCSPResponseBuilder()
.responder_key_hash(key_hash)
.produced_at("20260101000000Z")
.add_response(single)
.build_tbs()
)
print(f" ResponseData DER: <{len(tbs)} bytes>")
sig = bytes(256)
ocsp_der = synta.OCSPResponseBuilder.assemble(tbs, _SHA256_WITH_RSA_ALG, sig)
print(f" OCSPResponse DER: <{len(ocsp_der)} bytes>")
resp = synta.OCSPResponse.from_der(ocsp_der)
assert resp.status == "successful", f"expected 'successful', got {resp.status!r}"
print(f" status: {resp.status}")
print(f" response_type_oid: {resp.response_type_oid}")
assert resp.response_type_oid is not None
assert str(resp.response_type_oid) == "1.3.6.1.5.5.7.48.1.1"
print(" OCSPResponseBuilder: OK")
single2 = synta.OCSPSingleResponse(
hash_algorithm_der=_SHA1_ALG,
issuer_name_hash=name_hash,
issuer_key_hash=key_hash,
serial=serial,
status=0,
this_update="20260101000000Z",
next_update="20260701000000Z",
)
tbs_name = (
synta.OCSPResponseBuilder()
.responder_name(name_der)
.produced_at("20260101000000Z")
.add_response(single2)
.build_tbs()
)
ocsp_name_der = synta.OCSPResponseBuilder.assemble(tbs_name, _SHA256_WITH_RSA_ALG, sig)
resp2 = synta.OCSPResponse.from_der(ocsp_name_der)
assert resp2.status == "successful"
print(f" responder_name variant: status={resp2.status!r} OK")
def demo_ocsp_request():
section("OCSPRequestBuilder — build an unsigned OCSPRequest")
name_der = synta.NameBuilder().common_name("Test CA").build()
name_hash = synta.digest("sha1", name_der)
key_hash = bytes(20)
serial = bytes([0x42])
spec = synta.OCSPCertIDSpec(
hash_algorithm_der=_SHA1_ALG,
issuer_name_hash=name_hash,
issuer_key_hash=key_hash,
serial=serial,
)
ocsp_der = synta.OCSPRequestBuilder().add_request(spec).build_tbs()
print(f" OCSPRequest DER: <{len(ocsp_der)} bytes>")
req = synta.OCSPRequest.from_der(ocsp_der)
assert len(req.request_list) == 1
cert_id = req.request_list[0]
assert cert_id.issuer_name_hash == name_hash
assert cert_id.issuer_key_hash == key_hash
assert cert_id.serial_number == int.from_bytes(serial, "big")
print(f" CertID: {cert_id!r} OK")
print(f" requestor_name: {req.requestor_name!r} (None for unsigned)")
print(f" request_extensions: {req.request_extensions!r}")
def demo_signed_ocsp_request():
section("OCSPRequestBuilder — signed request via build_tbs_inner + assemble")
spec = synta.OCSPCertIDSpec(
hash_algorithm_der=_SHA1_ALG,
issuer_name_hash=bytes(20),
issuer_key_hash=bytes(20),
serial=bytes([0x01]),
)
tbs_inner = synta.OCSPRequestBuilder().add_request(spec).build_tbs_inner()
print(f" TBSRequest DER: <{len(tbs_inner)} bytes>")
sig = bytes(32)
ocsp_der = synta.OCSPRequestBuilder.assemble(tbs_inner, _SHA256_WITH_RSA_ALG, sig)
print(f" Signed OCSPRequest DER: <{len(ocsp_der)} bytes>")
req = synta.OCSPRequest.from_der(ocsp_der)
assert len(req.request_list) == 1
print(" signed request round-trip: OK")
def demo_requestor_name_request():
section("OCSPRequestBuilder — with requestorName")
name_der = synta.NameBuilder().common_name("Requestor").build()
gn_der = bytes([0xa4]) + _der_length(len(name_der)) + name_der
spec = synta.OCSPCertIDSpec(
hash_algorithm_der=_SHA1_ALG,
issuer_name_hash=bytes(20),
issuer_key_hash=bytes(20),
serial=bytes([0x01]),
)
ocsp_der = (
synta.OCSPRequestBuilder()
.requestor_name(gn_der)
.add_request(spec)
.build_tbs()
)
req = synta.OCSPRequest.from_der(ocsp_der)
assert req.requestor_name is not None
print(f" requestorName present: <{len(req.requestor_name)} bytes> OK")
def main():
print("=" * 60)
print("Example 8: OCSP response and request parsing/building")
print("=" * 60)
demo_successful_response()
demo_trylater_response()
demo_all_status_values()
demo_to_der_roundtrip()
demo_pem_roundtrip()
demo_ocsp_builder()
demo_ocsp_request()
demo_signed_ocsp_request()
demo_requestor_name_request()
print("\nAll OCSP examples completed.")
if __name__ == "__main__":
main()