Commit e081d8b5 authored by Matthew Holt's avatar Matthew Holt

Maintainence routine deletes old (expired) OCSP staple files

parent 8eefeb67
...@@ -89,7 +89,6 @@ func stapleOCSP(cert *Certificate, pemBundle []byte) error { ...@@ -89,7 +89,6 @@ func stapleOCSP(cert *Certificate, pemBundle []byte) error {
// First try to load OCSP staple from storage and see if // First try to load OCSP staple from storage and see if
// we can still use it. // we can still use it.
// TODO: Use Storage interface instead of disk directly // TODO: Use Storage interface instead of disk directly
ocspFolder := filepath.Join(caddy.AssetsPath(), "ocsp")
ocspFileName := cert.Names[0] + "-" + fastHash(pemBundle) ocspFileName := cert.Names[0] + "-" + fastHash(pemBundle)
ocspCachePath := filepath.Join(ocspFolder, ocspFileName) ocspCachePath := filepath.Join(ocspFolder, ocspFileName)
cachedOCSP, err := ioutil.ReadFile(ocspCachePath) cachedOCSP, err := ioutil.ReadFile(ocspCachePath)
......
package caddytls package caddytls
import ( import (
"io/ioutil"
"log" "log"
"os"
"path/filepath"
"time" "time"
"github.com/mholt/caddy"
"golang.org/x/crypto/ocsp" "golang.org/x/crypto/ocsp"
) )
...@@ -47,6 +52,7 @@ func maintainAssets(stopChan chan struct{}) { ...@@ -47,6 +52,7 @@ func maintainAssets(stopChan chan struct{}) {
case <-ocspTicker.C: case <-ocspTicker.C:
log.Println("[INFO] Scanning for stale OCSP staples") log.Println("[INFO] Scanning for stale OCSP staples")
UpdateOCSPStaples() UpdateOCSPStaples()
DeleteOldStapleFiles()
log.Println("[INFO] Done checking OCSP staples") log.Println("[INFO] Done checking OCSP staples")
case <-stopChan: case <-stopChan:
renewalTicker.Stop() renewalTicker.Stop()
...@@ -231,8 +237,49 @@ func UpdateOCSPStaples() { ...@@ -231,8 +237,49 @@ func UpdateOCSPStaples() {
certCacheMu.Unlock() certCacheMu.Unlock()
} }
// DeleteOldStapleFiles deletes cached OCSP staples that have expired.
// TODO: Should we do this for certificates too?
func DeleteOldStapleFiles() {
files, err := ioutil.ReadDir(ocspFolder)
if err != nil {
// maybe just hasn't been created yet; no big deal
return
}
for _, file := range files {
if file.IsDir() {
// wierd, what's a folder doing inside the OCSP cache?
continue
}
stapleFile := filepath.Join(ocspFolder, file.Name())
ocspBytes, err := ioutil.ReadFile(stapleFile)
if err != nil {
continue
}
resp, err := ocsp.ParseResponse(ocspBytes, nil)
if err != nil {
// contents are invalid; delete it
err = os.Remove(stapleFile)
if err != nil {
log.Printf("[ERROR] Purging corrupt staple file %s: %v", stapleFile, err)
}
}
if time.Now().After(resp.NextUpdate) {
// response has expired; delete it
err = os.Remove(stapleFile)
if err != nil {
log.Printf("[ERROR] Purging expired staple file %s: %v", stapleFile, err)
}
}
}
}
// freshOCSP returns true if resp is still fresh,
// meaning that it is not expedient to get an
// updated response from the OCSP server.
func freshOCSP(resp *ocsp.Response) bool { func freshOCSP(resp *ocsp.Response) bool {
// start checking OCSP staple about halfway through validity period for good measure // start checking OCSP staple about halfway through validity period for good measure
refreshTime := resp.ThisUpdate.Add(resp.NextUpdate.Sub(resp.ThisUpdate) / 2) refreshTime := resp.ThisUpdate.Add(resp.NextUpdate.Sub(resp.ThisUpdate) / 2)
return time.Now().Before(refreshTime) return time.Now().Before(refreshTime)
} }
var ocspFolder = filepath.Join(caddy.AssetsPath(), "ocsp")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment