Skip to content

Commit

Permalink
extract revocationCache struct with mutex
Browse files Browse the repository at this point in the history
  • Loading branch information
mmetc committed May 28, 2024
1 parent 97e3d28 commit 209cceb
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 23 deletions.
60 changes: 60 additions & 0 deletions pkg/apiserver/middlewares/v1/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package v1

import (
"sync"
"time"

log "github.com/sirupsen/logrus"
)

type cacheEntry struct {
revoked bool
timestamp time.Time
}

type RevocationCache struct {
mu sync.RWMutex
cache map[string]cacheEntry
expiration time.Duration
}

func NewRevocationCache(expiration time.Duration) *RevocationCache {
return &RevocationCache{
cache: make(map[string]cacheEntry),
expiration: expiration,
}
}

func (rc *RevocationCache) Get(sn string, logger *log.Entry) (bool, bool) {
rc.mu.RLock()
entry, exists := rc.cache[sn]
rc.mu.RUnlock()

if !exists {
logger.Tracef("TLSAuth: no cached value for cert %s", sn)
return false, false
}

rc.mu.Lock()
if entry.timestamp.Add(rc.expiration).Before(time.Now()) {
logger.Debugf("TLSAuth: cached value for %s expired, removing from cache", sn)
delete(rc.cache, sn)
rc.mu.Unlock()

return false, false
}
rc.mu.Unlock()

logger.Debugf("TLSAuth: using cached value for cert %s: %t", sn, entry.revoked)

return entry.revoked, true
}

func (rc *RevocationCache) Set(sn string, revoked bool) {
rc.mu.Lock()
rc.cache[sn] = cacheEntry{
revoked: revoked,
timestamp: time.Now(),
}
rc.mu.Unlock()
}
28 changes: 5 additions & 23 deletions pkg/apiserver/middlewares/v1/tls_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,10 @@ import (
type TLSAuth struct {
AllowedOUs []string
CrlPath string
revocationCache map[string]cacheEntry
cacheExpiration time.Duration
revocationCache *RevocationCache
logger *log.Entry
}

type cacheEntry struct {
revoked bool
timestamp time.Time
}

func (ta *TLSAuth) ocspQuery(server string, cert *x509.Certificate, issuer *x509.Certificate) (*ocsp.Response, error) {
req, err := ocsp.CreateRequest(cert, issuer, &ocsp.RequestOptions{Hash: crypto.SHA256})
if err != nil {
Expand Down Expand Up @@ -187,27 +181,16 @@ func (ta *TLSAuth) isCRLRevoked(cert *x509.Certificate) (bool, bool) {

func (ta *TLSAuth) isRevoked(cert *x509.Certificate, issuer *x509.Certificate) (bool, error) {
sn := cert.SerialNumber.String()
if cacheValue, ok := ta.revocationCache[sn]; ok {
if time.Now().UTC().Sub(cacheValue.timestamp) < ta.cacheExpiration {
ta.logger.Debugf("TLSAuth: using cached value for cert %s: %t", sn, cacheValue.revoked)
return cacheValue.revoked, nil
}

ta.logger.Debugf("TLSAuth: cached value expired, removing from cache")
delete(ta.revocationCache, sn)
} else {
ta.logger.Tracef("TLSAuth: no cached value for cert %s", sn)
if revoked, ok := ta.revocationCache.Get(sn, ta.logger); ok {
return revoked, nil
}

revokedByOCSP, cacheOCSP := ta.isOCSPRevoked(cert, issuer)
revokedByCRL, cacheCRL := ta.isCRLRevoked(cert)
revoked := revokedByOCSP || revokedByCRL

if cacheOCSP && cacheCRL {
ta.revocationCache[sn] = cacheEntry{
revoked: revoked,
timestamp: time.Now().UTC(),
}
ta.revocationCache.Set(sn, revoked)
}

return revoked, nil
Expand Down Expand Up @@ -290,8 +273,7 @@ func (ta *TLSAuth) ValidateCert(c *gin.Context) (bool, string, error) {

func NewTLSAuth(allowedOus []string, crlPath string, cacheExpiration time.Duration, logger *log.Entry) (*TLSAuth, error) {
ta := &TLSAuth{
revocationCache: map[string]cacheEntry{},
cacheExpiration: cacheExpiration,
revocationCache: NewRevocationCache(cacheExpiration),
CrlPath: crlPath,
logger: logger,
}
Expand Down

0 comments on commit 209cceb

Please sign in to comment.