From 45d4be32e64aecedf7ddf949ed1f9bbaecc0ca4a Mon Sep 17 00:00:00 2001 From: Florian Bauer Date: Sat, 21 Jun 2025 19:03:10 +0000 Subject: [PATCH] feat: add ca endpoints Squashed commit of the following: * doc: add documentation for ca endpoint Signed-off-by: Florian Bauer * feat: add ca endpoints Signed-off-by: Florian Bauer See merge request https://ref.ci/fsrvcorp/pki/ocspcrl/-/merge_requests/6 --- README.md | 9 +++++++-- main.go | 19 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 98b0b8e..a645fd4 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,13 @@ OCSPCRL is a minimal implementation of both a OCSP and CRL server in Golang. It provides the following http endpoints: -- `/ocsp` - OCSP responder -- `/crl` - CRL responder +| 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 | All what you need is 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. diff --git a/main.go b/main.go index 71fda29..ba60dac 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/pem" + "errors" "fmt" "log" "net/http" @@ -164,23 +165,31 @@ func main() { w.Header().Set("Content-Type", "application/pkix-crl") pem.Encode(w, &pem.Block{Type: "X509 CRL", Bytes: crl.Raw}) }) + applicationRouter.HandleFunc("/ca", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/pkix-cert") + w.Write(caCertificate.Raw) + }) + applicationRouter.HandleFunc("/ca.pem", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/x-x509-ca-cert") + pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: caCertificate.Raw}) + }) applicationServer := &http.Server{Addr: config.applicationListenAddress, Handler: metrics.Middleware(applicationRouter)} - metricsSever := &http.Server{Addr: config.metricsListenAddress, Handler: promhttp.Handler()} + metricsServer := &http.Server{Addr: config.metricsListenAddress, Handler: promhttp.Handler()} applicationServerClosed := make(chan any) metricsServerClosed := make(chan any) go func() { log.Printf("starting application server on %+q", config.applicationListenAddress) - if listenError := applicationServer.ListenAndServe(); listenError != nil { + if listenError := applicationServer.ListenAndServe(); !errors.Is(listenError, http.ErrServerClosed) { log.Printf("application error: %v", listenError) } close(applicationServerClosed) }() go func() { log.Printf("starting metrics server on %+q", config.metricsListenAddress) - if listenError := metricsSever.ListenAndServe(); listenError != nil { - log.Printf("metrics error: %v", listenError) + if listenError := metricsServer.ListenAndServe(); !errors.Is(listenError, http.ErrServerClosed) { + log.Printf("metrics server error: %v", listenError) } close(metricsServerClosed) }() @@ -188,7 +197,7 @@ func main() { <-signalChan close(hupChan) applicationServer.Shutdown(nil) - metricsSever.Shutdown(nil) + metricsServer.Shutdown(nil) <-applicationServerClosed <-metricsServerClosed }