mirror of
https://github.com/sonr-io/common.git
synced 2026-01-11 20:08:57 +00:00
81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
//go:build go1.19
|
|
|
|
package revoke
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"time"
|
|
)
|
|
|
|
// CRLSet associates a PKIX certificate list with the URL the CRL is
|
|
// fetched from.
|
|
var (
|
|
CRLSet = map[string]*x509.RevocationList{}
|
|
)
|
|
|
|
// fetchCRL fetches and parses a CRL.
|
|
func fetchCRL(url string) (*x509.RevocationList, error) {
|
|
resp, err := HTTPClient.Get(url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode >= 300 {
|
|
return nil, ErrFailedGetCRL
|
|
}
|
|
|
|
body, err := crlRead(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return x509.ParseRevocationList(body)
|
|
}
|
|
|
|
// check a cert against a specific CRL. Returns the same bool pair
|
|
// as revCheck, plus an error if one occurred.
|
|
func certIsRevokedCRL(cert *x509.Certificate, url string) (revoked, ok bool, err error) {
|
|
var crl *x509.RevocationList
|
|
|
|
crlLock.Lock()
|
|
|
|
if crl, ok = CRLSet[url]; ok && crl == nil {
|
|
ok = false
|
|
|
|
delete(CRLSet, url)
|
|
}
|
|
|
|
crlLock.Unlock()
|
|
|
|
shouldFetchCRL := !ok || !time.Now().Before(crl.NextUpdate)
|
|
|
|
issuer := getIssuer(cert)
|
|
|
|
if shouldFetchCRL {
|
|
if crl, err = fetchCRL(url); err != nil {
|
|
return false, false, err
|
|
}
|
|
|
|
// Check the CRL signature.
|
|
if issuer != nil {
|
|
if err = crl.CheckSignatureFrom(issuer); err != nil {
|
|
return false, false, err
|
|
}
|
|
}
|
|
|
|
crlLock.Lock()
|
|
CRLSet[url] = crl
|
|
crlLock.Unlock()
|
|
}
|
|
|
|
for _, rcert := range crl.RevokedCertificates {
|
|
if cert.SerialNumber.Cmp(rcert.SerialNumber) == 0 {
|
|
return true, true, err
|
|
}
|
|
}
|
|
|
|
return false, true, err
|
|
}
|