feat: implement multi CA serving

This commit is contained in:
T. R. Bernstein
2026-04-30 02:08:56 +02:00
parent 00ac7628d4
commit 4e4dd2eaae
3 changed files with 356 additions and 168 deletions

View File

@@ -1,17 +1,61 @@
# OCSP Server
OCSP Server is a minimal implementation of both a OCSP and CRL server in Golang, using a single CRL as the source for both interfaces.
Originally created by Florian Bauer and now adapted for Spacebar. It provides the following http endpoints:
OCSP Server is a minimal implementation of both an OCSP and CRL server in Golang, using a CRL as the source for both interfaces.
Originally created by Florian Bauer and now adapted for Spacebar. A single instance can serve any number of CAs (e.g. a root CA and several intermediates).
| Endpoint | Description |
|------------|----------------------------------------------------------|
| `/ocsp` | OCSP responder supporting both `GET` and `POST` requests |
| `/crl` | CRL responder in DER format |
| `/crl.pem` | CRL responder in PEM format |
| `/ca` | Issuer CA certificate in DER format |
| `/ca.pem` | Issuer CA certificate in PEM format |
## Configuration
You need to provide a CRL file, the root certificate and cert/key with extendedKeyUsage `OCSPSigning` to allow the OCSP server to sign the OCSP responses.
When using OCSP, the certificate is checked against the CRL for validity.
Point the server at a single directory that contains one subdirectory per CA. The subdirectory name is used as the route prefix.
Synchronization of the CAs CRL is out of scope of this project. You can use any mechanism to update the CRL file. Just notify the ocspcrl server process via `SIGHUP` signal to reload the CRL file.
```
cas/
├── root/
│ ├── ca.crt
│ ├── responder.crt
│ ├── key.pem
│ └── crl.pem
├── hr/
│ ├── ca.crt
│ ├── responder.crt
│ ├── key.pem
│ └── crl.pem
└── it/
├── ca.crt
├── responder.crt
├── key.pem
└── crl.pem
```
Each CA subdirectory must contain:
| File | Description |
|-----------------|--------------------------------------------------------------------------|
| `ca.crt` | The CA certificate (PEM) |
| `responder.crt` | The OCSP responder certificate with `extendedKeyUsage = OCSPSigning` |
| `key.pem` | The private key for the responder certificate (PEM) |
| `crl.pem` | The current CRL issued by the CA (PEM or DER) |
Run the server with:
```
ocspcrl --cas-directory /path/to/cas
```
## Endpoints
For every CA subdirectory `<route-prefix>`, the following endpoints are exposed:
| Endpoint | Content-Type | Description |
|-----------------------------|-----------------------------|----------------------------------------------------------|
| `<route-prefix>/ocsp` | (OCSP) | OCSP responder supporting both `GET` and `POST` requests |
| `<route-prefix>/ocsp/` | (OCSP) | OCSP responder supporting both `GET` and `POST` requests |
| `<route-prefix>/crl` | `application/pkix-cert` | CRL in DER form |
| `<route-prefix>/crl.pem` | `application/pkix-crl` | CRL in PEM form |
| `<route-prefix>/ca` | `application/pkix-cert` | CA certificate in DER form |
| `<route-prefix>/ca.pem` | `application/x-x509-ca-cert`| CA certificate in PEM form |
For example, with the layout above, the OCSP endpoint for the `hr` intermediate is `https://<host>/hr/ocsp` and its CRL is at `https://<host>/hr/crl.pem`.
## Reloading the CRLs
Synchronization of the CAs' CRLs is out of scope of this project. You can use any mechanism to update the CRL files. Notify the `ocspcrl` server process via `SIGHUP` to reload every CA's CRL from disk.