Install & Compatibility
Where this runs
tested against v0.10.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 20.7MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.5s · import 0.170s · 21MB
19MB installed
● package 19MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
OCSPRequestBuilder
✓ from ocspbuilder import OCSPRequestBuilder
OCSPResponseBuilder
✓ from ocspbuilder import OCSPResponseBuilder
Nonce
✓ from ocspbuilder.extension import Nonce
Common OCSP extensions are available in the `ocspbuilder.extension` module.
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}")
Debug
Known issues
gotcha`ocspbuilder` primarily operates on `cryptography.x509.Certificate` and related objects for inputs (e.g., keys, certificates), not raw PEM/DER encoded bytes or strings. Users must first parse their certificate data into `cryptography` objects.fixEnsure all certificate and key inputs are instances of `cryptography.x509.Certificate`, `cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`, etc., before passing them to `ocspbuilder` methods.
affects: All
gotchaThe library simplifies OCSP message construction but does not manage the entire certificate chain validation or selection of the correct OCSP responder certificate. Users are responsible for providing the correct issuer certificate for requests and the correct OCSP responder certificate/key pair for signing responses.fixCarefully manage your certificate infrastructure and ensure the correct issuer and responder certificates/keys are used for `OCSPRequestBuilder.add_cert()` and `OCSPResponseBuilder.build()` respectively to ensure valid OCSP messages.
affects: All
gotchaWhile `ocspbuilder` provides a stable API, its core functionality is deeply integrated with the `cryptography` library. Significant breaking changes or API shifts within `cryptography` (especially in `x509.ocsp` modules) could indirectly require updates to `ocspbuilder` or user code, even if `ocspbuilder` itself doesn't change.fixMonitor `cryptography` release notes for breaking changes. If issues arise after a `cryptography` upgrade, check for a newer `ocspbuilder` version or adjust `cryptography`-related code if the `ocspbuilder` abstraction is insufficient.
affects: All
gotchaThe PyPI metadata for `ocspbuilder` states `requires_python: None`, which can lead to ambiguity. GitHub CI/CD tests indicate compatibility with Python 3.7 through 3.10. Users on newer Python versions (e.g., 3.11+) should verify compatibility, as it largely depends on the `cryptography` dependency's support for those versions.fixTest `ocspbuilder` in your target Python environment, especially if using Python versions newer than 3.10. Ensure your installed `cryptography` version supports your Python version.
affects: Potentially Python 3.11+
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'ocspbuilder'
The 'ocspbuilder' library is not installed in your Python environment or is not accessible from the current environment.
fixInstall the library using pip: `pip install ocspbuilder`
ValueError: Certificate and key do not match
When signing an OCSP response, the provided private key does not correspond to the public key within the responder certificate.
fixEnsure that the `private_key` argument passed to the `sign()` method corresponds to the `responder_cert` provided to the `responder_id()` method of the `OCSPResponseBuilder`.
OCSP response status: UNAUTHORIZED
The OCSP responder server rejected the request, often because the hashing algorithm used in the request (e.g., SHA256) is not supported or expected by the responder, which might only support older algorithms like SHA1.
fixWhen building an OCSP request using `OCSPRequestBuilder().add_certificate()` or `add_response()`, try using a different hashing algorithm, such as `hashes.SHA1()` from the `cryptography` library, if the responder is known to be older or has specific requirements.
ValueError: You cannot set produced_at on OCSP responses at this time.
The `ocspbuilder` library automatically sets the `produced_at` timestamp to the current UTC time when the `sign()` method is called, and does not allow manual override.
fixRemove any explicit attempts to set the `produced_at` field on the OCSP response, as it is handled internally by the library.
Upgrade
Version history
0.10.2latest on PyPI · released Jul 29, 2016
Audit
Dependencies
cryptographyrequiredCore cryptographic operations for X.509 certificates, keys, and OCSP structures.