-
Notifications
You must be signed in to change notification settings - Fork 33
OCSP responder (RFC 6960) #884
Description
Summary
Implement an OCSP (Online Certificate Status Protocol) responder endpoint (RFC 6960) so relying parties can query the revocation status of certificates issued by the Cosmian KMS CA in real time, without downloading full CRLs.
Impact
- TLS stacks, browsers, and PKI-aware applications check OCSP before trusting a certificate
- Without an OCSP responder, the Cosmian CA cannot be used as a trust anchor in environments that require live revocation checks (e.g., mutual TLS for KMIP clients)
- Enables OCSP stapling for TLS certificates issued by Cosmian, improving performance for relying parties
- Required for compliance with CA/Browser Forum Baseline Requirements when operating a publicly trusted CA
How revocation works in this codebase
The revoke_operation() in crate/server/src/core/operations/revoke.rs transitions a certificate's KMIP State to Compromised or Deactivated. The serial number of each certificate is computed in crate/server/src/core/operations/certify/mod.rs (create_subject_key_identifier_value()) and set as the X.509 serial number via x509_builder.set_serial_number(...).
The OCSP responder maps from the serial number in the incoming OCSP request to the matching certificate object's State to determine the revocation status.
Implementation plan
1. Serial-number-based lookup
Add a method to ObjectsStore in crate/interfaces/src/stores/objects_store.rs:
/// Find a certificate object by its X.509 serial number (hex-encoded or DER bytes).
async fn find_certificate_by_serial(
&self,
serial_hex: &str,
user: &str,
) -> InterfaceResult<Option<(String, Object, Attributes)>>;Implement in all three DB backends (SQLite, PostgreSQL, Redis-findex) by scanning the attributes JSON blob for the x509_cert.serial_number field, or by adding a dedicated cert_serial index column.
2. OCSP route handlers (crate/server/src/routes/ocsp/)
crate/server/src/routes/ocsp/
mod.rs ← scope registration
handler.rs ← GET + POST /ocsp/ handlers
build.rs ← OCSP response builder
GET /ocsp/{base64-request} and POST /ocsp/:
- Parse the ASN.1 OCSP request using
openssl::ocsp::OcspRequest(from theopensslcrate already in the workspace). - Extract the
CertIdfrom the request: issuer name hash, issuer key hash, serial number. - Verify the issuer hashes match the configured CA certificate (
ca_uid). - Look up the certificate by serial number via
find_certificate_by_serial(). - Determine status:
- Object not found →
unknown State::ActiveorState::PreActive→goodState::Compromised→revokedwithCRLReason::keyCompromiseState::DeactivatedorState::Destroyed→revokedwithCRLReason::cessationOfOperation
- Object not found →
- Build the
OcspBasicResponseusingopenssl::ocsp::OcspBasicResponse:thisUpdate= nownextUpdate= now +[ocsp].cache_ttl_secs
- Sign the response with the CA's private key via the existing
sign_operation()KMS call on theca_uidkey. - Return
200 OKwithContent-Type: application/ocsp-response.
3. Response caching
Cache signed OCSP responses in-memory:
// In KMS struct or a dedicated OcspCache
struct OcspCache {
entries: DashMap<String, (Bytes, Instant)>, // serial_hex → (signed_response, expires_at)
}On cache hit (not expired), return the cached response immediately without re-signing. Cache TTL configurable via [ocsp].cache_ttl_secs (default: 86400 = 24 h).
4. Config TOML
[ocsp]
enabled = false
ca_uid = "..." # UID of the CA certificate object in the KMS
cache_ttl_secs = 86400 # OCSP response validity window5. Scope registration (crate/server/src/routes/mod.rs)
Add the /ocsp scope alongside the existing routes, wrapped with the same auth middlewares.
Files to create / modify
| File | Change |
|---|---|
crate/interfaces/src/stores/objects_store.rs |
Add find_certificate_by_serial() |
crate/server_database/src/stores/sql/ |
Implement find_certificate_by_serial for SQLite + PostgreSQL |
crate/server_database/src/stores/redis/ |
Implement for Redis-findex backend |
crate/server/src/routes/ocsp/mod.rs |
New: scope registration |
crate/server/src/routes/ocsp/handler.rs |
New: GET + POST OCSP handlers |
crate/server/src/routes/ocsp/build.rs |
New: OCSP response builder + cache |
crate/server/src/routes/mod.rs |
Register /ocsp scope |
crate/server/src/config/ |
New [ocsp] config block |
Acceptance criteria
openssl ocsp -issuer ca.pem -cert leaf.pem -url http://kms.example.com/ocsp/returnsgoodfor an active certificate.- After calling
ckms certificates revoke <uid>, the sameopenssl ocspcall returnsrevoked. - A serial number not matching any known certificate returns
unknown. - Cached responses are served without re-signing within the TTL window.
- All OCSP routes return
404whenocsp.enabled = false.
References
- RFC 6960 (OCSP): https://tools.ietf.org/html/rfc6960
- OpenSSL OCSP API: https://docs.rs/openssl/latest/openssl/ocsp/
Effort: Small (2–3 weeks) | No prerequisites