Registry / auth-security / ocspresponder

ocspresponder

JSON →
library0.5.0pypypi✓ verified 21d ago

ocspresponder is an RFC 6960 compliant OCSP Responder framework written in Python 3.5+. It provides a foundation for building an OCSP responder service, leveraging the ocspbuilder and asn1crypto libraries for cryptographic operations, and using Bottle for the HTTP server. It is currently in an alpha development stage (version 0.5.0) and is not recommended for production use.

pip install ocspresponder
INSTALL
IMPORT
SIG · OCSPRESPONDER
O
ocspresponder
auth-securitypythonv0.5.0
Install
1.9s avg
Import
272ms
Disk
19MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.5.0 · 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
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 21.1MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.9s · import 0.218s · 22MB
19MB installed
● package 19MB
Code
Verified usage

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)")
Debug
Known issues
breakingThe `ocspresponder` library is currently in 'Alpha' status and explicitly marked 'Don't use for production yet' on its PyPI page. Its API or internal workings may change significantly.
fix
Use for experimental purposes only. Monitor the project's development for a stable release suitable for production environments.
affects: 0.5.0 and earlier
gotchaMajor Certificate Authorities (e.g., Let's Encrypt) are phasing out OCSP support in favor of Certificate Revocation Lists (CRLs) due to privacy concerns and operational simplicity. While `ocspresponder` provides OCSP functionality, the broader ecosystem's shift may impact its long-term utility.
fix
Evaluate your specific use case to determine if OCSP remains a suitable revocation mechanism. Consider the implications of browsers and other clients potentially reducing or ceasing OCSP checks by 2025.
affects: All versions of ocspresponder, as this is an external ecosystem change.
gotchaThe library requires you to implement custom functions for `retrieve_certificate_status` and `retrieve_issuer_certificate`. These functions are critical for the responder's operation and must securely access and manage your certificate revocation data.
fix
Design and implement these custom functions carefully, ensuring robust database interaction, error handling, and security best practices for handling certificate status and issuer information.
affects: All versions
gotchaOCSP requests are typically sent over plain HTTP and can be vulnerable to interception and modification if not properly secured (e.g., through OCSP stapling or secure transport). Attackers could alter responses or block them, potentially leading to clients accepting revoked certificates.
fix
Implement OCSP stapling where possible, or ensure the communication channel to the OCSP responder is secured (e.g., within a trusted network or via HTTPS for the responder itself, although the OCSP request inside is often not encrypted). Be aware of the privacy implications of direct OCSP queries.
affects: All versions, as this is a protocol-level concern.
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'ocspresponder'
The `ocspresponder` library or one of its dependencies is not installed in the current Python environment.
fix
Install the library using pip: `pip install ocspresponder`
FileNotFoundError: [Errno 2] No such file or directory: 'path/to/issuer_cert.pem'
The `OCSPResponder` class was initialized with paths to certificate or key files that do not exist or are inaccessible.
fix
Ensure that `ISSUER_CERT`, `OCSP_CERT`, and `OCSP_KEY` variables point to valid and readable certificate and private key files, respectively, for your OCSP responder setup.
TypeError: OCSPResponder.__init__() missing 2 required positional arguments: 'validate' and 'get_certificate'
The `OCSPResponder` class constructor requires two custom functions, `validate` and `get_certificate`, to be passed as arguments, but they were omitted.
fix
Provide implementations for the `validate(serial: int)` and `get_certificate(serial: int)` functions and pass them during `OCSPResponder` instantiation, as shown in the library's usage examples.
asn1crypto.parser.ParseError: Expected an ASN.1 SET at <ASN1 object>, got INTEGER
One of the provided certificate or key files (`ISSUER_CERT`, `OCSP_CERT`, or `OCSP_KEY`) is malformed, corrupted, or not in the expected PEM/DER format, causing `asn1crypto` (a core dependency) to fail parsing it.
fix
Verify that your certificate and key files are correctly formatted (e.g., valid PEM or DER encoding) and are not corrupted. Tools like `openssl x509 -in your_cert.pem -text -noout` can help diagnose issues with certificate files.
Upgrade
Version history
0.5.0latest on PyPI · released May 2, 2016
Audit
Dependencies
ocspbuilderrequiredCore dependency for building OCSP responses.
asn1cryptorequiredCore dependency for ASN.1 parsing and serialization.
BottlerequiredHTTP server framework used by ocspresponder.
cryptographyoptionalCommonly used for cryptographic operations in Python PKI, implicitly relied upon by ocspbuilder/asn1crypto or directly in custom implementations.
mysql-connector-pythonoptionalRequired if using a MySQL database for certificate status and retrieval.
Agent activity
9 hits · last 30 days
node
6
Amazon
1
OpenAI (training)
1
Resources