Verified import paths — ran on the pinned version, not inferred.
OCSPResponder
✓ from ocspresponder import OCSPResponder
CertificateStatus
✓ from ocspresponder import CertificateStatus
This quickstart demonstrates how to instantiate the `OCSPResponder` class. It includes dummy certificate generation and simple functions for validating certificate status and retrieving issuer certificates. In a real application, `issuer_cert`, `ocsp_cert`, and `ocsp_key` would be loaded securely, and `retrieve_certificate_status` and `retrieve_issuer_certificate` would interact with a robust certificate database. The example also shows how it would be integrated into a Bottle web server.
import os
from datetime import datetime, timedelta
from typing import Optional
from ocspresponder import OCSPResponder, CertificateStatus
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
from cryptography import x509
from ocspbuilder import OCSPResponseBuilder
# NOTE: This quickstart uses dummy certificates and keys for demonstration.
# In a real scenario, these would be loaded from secure storage.
# Also, ocspresponder is currently alpha; not for production use.
# Generate dummy CA and OCSP responder certificates/keys for demonstration
def generate_dummy_certs():
ca_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
ca_subject = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"California"),
x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My CA"),
x509.NameAttribute(NameOID.COMMON_NAME, u"My Root 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.utcnow())
.not_valid_after(datetime.utcnow() + timedelta(days=365))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
.sign(ca_key, hashes.SHA256())
)
ocsp_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
ocsp_subject = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"California"),
x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My OCSP Responder"),
x509.NameAttribute(NameOID.COMMON_NAME, u"ocsp.example.com"),
])
ocsp_cert = (
x509.CertificateBuilder()
.subject_name(ocsp_subject)
.issuer_name(ca_subject)
.public_key(ocsp_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.utcnow())
.not_valid_after(datetime.utcnow() + timedelta(days=90))
.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)
.add_extension(x509.ExtendedKeyUsage([x509.ExtendedKeyUsageOID.OCSP_SIGNING]), critical=True)
.sign(ca_key, hashes.SHA256())
)
return ca_cert, ca_key, ocsp_cert, ocsp_key
CA_CERT, CA_KEY, OCSP_CERT, OCSP_KEY = generate_dummy_certs()
# Example data store for certificate statuses
# In a real application, this would be a database or other persistent store.
dummy_cert_db = {
12345: (CertificateStatus.good, None, CA_CERT.public_bytes(serialization.Encoding.PEM)),
67890: (CertificateStatus.revoked, datetime.utcnow() - timedelta(days=5), CA_CERT.public_bytes(serialization.Encoding.PEM))
}
# Custom function to validate a certificate serial number
def validate_cert_status(serial: int) -> (CertificateStatus, Optional[datetime]):
status, revoked_at, _ = dummy_cert_db.get(serial, (CertificateStatus.unknown, None, None))
return status, revoked_at
# Custom function to retrieve the issuer certificate for a given serial
def get_issuer_certificate(serial: int) -> Optional[bytes]:
# In a real scenario, you'd find the actual issuer of the certificate
# identified by 'serial'. For this dummy example, we return the CA_CERT.
_, _, issuer_cert_pem = dummy_cert_db.get(serial, (None, None, None))
return issuer_cert_pem
# Instantiate the OCSP Responder
responder = OCSPResponder(
issuer_cert=CA_CERT.public_bytes(serialization.Encoding.PEM),
ocsp_cert=OCSP_CERT.public_bytes(serialization.Encoding.PEM),
ocsp_key=OCSP_KEY.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
),
retrieve_certificate_status=validate_cert_status,
retrieve_issuer_certificate=get_issuer_certificate
)
print("OCSPResponder instantiated successfully.")
print("This is a framework. To run a server, you would integrate this into an HTTP server (e.g., Bottle).")
print("For example, with Bottle:")
print("from bottle import run, request, post")
print("@post('/ocsp')")
print("def ocsp_service():")
print(" return responder.handle_ocsp_request(request.body.read())")
print("run(host='localhost', port=8080)")