OCSP Builder (ocspbuilder)

0.10.2 · active · verified Sun Apr 12

ocspbuilder is a Python library designed to simplify the creation and signing of Online Certificate Status Protocol (OCSP) requests and responses for X.509 certificates. It acts as a higher-level abstraction over the `cryptography` library, focusing on the builder pattern for OCSP structures. The current stable version is 0.10.2. While not updated frequently, it provides stable functionality for OCSP operations.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to create both an OCSP request and then build a corresponding 'good' status OCSP response. It includes necessary certificate generation steps (using `cryptography`) to make the example runnable from scratch. Key steps involve using `OCSPRequestBuilder` to add certificates to be checked and extensions, and `OCSPResponseBuilder` to specify the status and sign the response with an appropriate responder certificate and key.

import datetime
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa

from ocspbuilder import OCSPRequestBuilder, OCSPResponseBuilder
from ocspbuilder.extension import Nonce

# --- 1. Generate dummy certificates for a runnable example ---
# In a real scenario, you would load these from files/database.

# CA Key and Cert
ca_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend())
ca_subject = x509.Name([x509.NameAttribute(x509.NameOID.COMMON_NAME, u"OCSP Test CA")])
ca_cert = (
    x509.CertificateBuilder()
    .subject_name(ca_subject)
    .issuer_name(ca_subject)
    .public_key(ca_key.public_key())
    .serial_number(x509.random_serial_number())
    .not_valid_before(datetime.datetime.utcnow())
    .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))
    .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
    .sign(ca_key, hashes.SHA256(), default_backend())
)

# Issued Cert Key and Cert (signed by CA)
issued_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend())
issued_subject = x509.Name([x509.NameAttribute(x509.NameOID.COMMON_NAME, u"OCSP Test Cert")])
issued_cert = (
    x509.CertificateBuilder()
    .subject_name(issued_subject)
    .issuer_name(ca_subject) # Signed by CA
    .public_key(issued_key.public_key())
    .serial_number(x509.random_serial_number())
    .not_valid_before(datetime.datetime.utcnow())
    .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))
    .add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)
    .sign(ca_key, hashes.SHA256(), default_backend())
)

# --- 2. Build an OCSP Request ---
request_builder = OCSPRequestBuilder()
request_builder = request_builder.add_cert(issued_cert, ca_cert) # Cert to check, and its issuer
request_builder = request_builder.add_extension(Nonce.build()) # Add a common extension

ocsp_request = request_builder.build()

print("OCSP Request built successfully.")
print(f"Request bytes length: {len(ocsp_request.public_bytes(encoding=serialization.Encoding.DER))}")

# --- 3. Build an OCSP Response (e.g., 'good' status) ---
# The OCSP responder needs its own certificate and private key to sign the response.
# For this example, we'll reuse the CA's key/cert as the responder.
# In a production environment, this would be a dedicated responder cert.

ocsp_responder_key = ca_key
ocsp_responder_cert = ca_cert

response_builder = OCSPResponseBuilder(ocsp_request) # Initialize with the received request
response_builder = response_builder.add_response(
    cert=issued_cert,
    issuer=ca_cert,
    cert_status=x509.ocsp.OCSPCertStatus.GOOD, # Example status
    this_update=datetime.datetime.utcnow(),
    next_update=datetime.datetime.utcnow() + datetime.timedelta(hours=1),
)

ocsp_response = response_builder.build(
    signer_certificate=ocsp_responder_cert,
    signer_private_key=ocsp_responder_key,
    hash_algorithm=hashes.SHA256() # Algorithm used to sign the response
)

print("OCSP Response built successfully.")
print(f"Response bytes length: {len(ocsp_response.public_bytes(encoding=serialization.Encoding.DER))}")

# Optional: Verify the response using cryptography directly
# This demonstrates that ocspbuilder outputs standard cryptography objects
parsed_response = x509.ocsp.load_der_ocsp_response(ocsp_response.public_bytes(encoding=serialization.Encoding.DER))
print(f"Number of responses in parsed OCSP response: {len(parsed_response.responses)}")
print(f"Status for first cert in response: {parsed_response.responses[0].certificate_status}")

view raw JSON →