github.com/ztalab/ZACA@v0.0.1/pkg/caclient/ocsp_mem_cache.go (about) 1 package caclient 2 3 import ( 4 "crypto/x509" 5 "encoding/hex" 6 "math" 7 "sync/atomic" 8 "time" 9 10 "github.com/pkg/errors" 11 "golang.org/x/crypto/ocsp" 12 13 "github.com/ztalab/ZACA/pkg/memorycacher" 14 "go.uber.org/zap" 15 ) 16 17 var _ OcspClient = &ocspMemCache{} 18 19 // ocspMemCache ... 20 type ocspMemCache struct { 21 cache *memorycacher.Cache 22 logger *zap.SugaredLogger 23 ocspURL string // ca server + /ocsp 24 } 25 26 // NewOcspMemCache ... 27 func NewOcspMemCache(logger *zap.SugaredLogger, ocspAddr string) (OcspClient, error) { 28 return &ocspMemCache{ 29 cache: memorycacher.New(30*time.Minute, memorycacher.NoExpiration, math.MaxInt64), 30 logger: logger, 31 ocspURL: ocspAddr, 32 }, nil 33 } 34 35 // Validate ... 36 func (of *ocspMemCache) Validate(leaf, issuer *x509.Certificate) (bool, error) { 37 if atomic.LoadInt64(&ocspBlockSign) == 1 { 38 return false, errors.New("ocsp Request disabled") 39 } 40 if leaf == nil || issuer == nil { 41 return false, errors.New("leaf/issuer Missing parameter") 42 } 43 lo := of.logger.With("sn", leaf.SerialNumber.String(), "aki", hex.EncodeToString(leaf.AuthorityKeyId), "id", leaf.URIs[0]) 44 // Cache fetch 45 if _, ok := of.cache.Get(leaf.SerialNumber.String()); ok { 46 return true, nil 47 } 48 ocspRequest, err := ocsp.CreateRequest(leaf, issuer, &ocspOpts) 49 if err != nil { 50 lo.Errorf("ocsp req create err: %s", err) 51 return false, errors.Wrap(err, "ocsp req Creation failed") 52 } 53 getOcspFunc := func() (interface{}, error) { 54 return SendOcspRequest(of.ocspURL, ocspRequest, leaf, issuer) 55 } 56 sgValue, err, _ := sg.Do("ocsp"+leaf.SerialNumber.String(), getOcspFunc) 57 if err != nil { 58 lo.Errorf("ocsp Request error: %v", err) 59 // Here, the authentication fails due to CA server. The request is allowed. Try again next time 60 return true, errors.Wrap(err, "ocsp Request error") 61 } 62 ocspResp, ok := sgValue.(*ocsp.Response) 63 if !ok { 64 lo.Error("single flight Parsing error") 65 return false, errors.New("single flight Parsing error") 66 } 67 lo.Debugf("Verify OCSP and the results: %v", ocspResp.Status) 68 if ocspResp.Status == int(ocsp.Success) { 69 of.cache.SetDefault(leaf.SerialNumber.String(), true) 70 return true, nil 71 } 72 lo.Warnf("Certificate OCSP validation invalid") 73 return false, errors.New("ocsp Authentication failed and the certificate was revoked") 74 } 75 76 func (of *ocspMemCache) Reset() { 77 of.cache.Flush() 78 }