Cache issuer certificates retrieved from static-ct-api logs
This commit is contained in:
parent
958e7a9efb
commit
6151cb26da
|
@ -93,6 +93,23 @@ func (s *FilesystemState) RemoveSTH(ctx context.Context, logID LogID, sth *cttyp
|
||||||
return removeSTHFromDir(sthsDirPath, sth)
|
return removeSTHFromDir(sthsDirPath, sth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FilesystemState) StoreIssuer(ctx context.Context, fingerprint *[32]byte, issuer []byte) error {
|
||||||
|
filePath := filepath.Join(s.StateDir, "issuers", hex.EncodeToString(fingerprint[:]))
|
||||||
|
return writeFile(filePath, issuer, 0666)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FilesystemState) LoadIssuer(ctx context.Context, fingerprint *[32]byte) ([]byte, error) {
|
||||||
|
filePath := filepath.Join(s.StateDir, "issuers", hex.EncodeToString(fingerprint[:]))
|
||||||
|
issuer, err := os.ReadFile(filePath)
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return nil, nil
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return issuer, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FilesystemState) NotifyCert(ctx context.Context, cert *DiscoveredCert) error {
|
func (s *FilesystemState) NotifyCert(ctx context.Context, cert *DiscoveredCert) error {
|
||||||
var notifiedPath string
|
var notifiedPath string
|
||||||
var paths *certPaths
|
var paths *certPaths
|
||||||
|
|
|
@ -142,22 +142,34 @@ func (client *logClient) ReconstructTree(ctx context.Context, sth *cttypes.Signe
|
||||||
}
|
}
|
||||||
|
|
||||||
type issuerGetter struct {
|
type issuerGetter struct {
|
||||||
|
state StateProvider
|
||||||
logGetter ctclient.IssuerGetter
|
logGetter ctclient.IssuerGetter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ig *issuerGetter) GetIssuer(ctx context.Context, fingerprint *[32]byte) (issuer []byte, err error) {
|
func (ig *issuerGetter) GetIssuer(ctx context.Context, fingerprint *[32]byte) ([]byte, error) {
|
||||||
// TODO-2 check cache
|
if issuer, err := ig.state.LoadIssuer(ctx, fingerprint); err != nil {
|
||||||
err = withRetry(ctx, 7, func() error {
|
log.Printf("error loading cached issuer %x (issuer will be retrieved from log instead): %s", *fingerprint, err)
|
||||||
|
} else if issuer != nil {
|
||||||
|
return issuer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var issuer []byte
|
||||||
|
if err := withRetry(ctx, 7, func() error {
|
||||||
|
var err error
|
||||||
issuer, err = ig.logGetter.GetIssuer(ctx, fingerprint)
|
issuer, err = ig.logGetter.GetIssuer(ctx, fingerprint)
|
||||||
return err
|
return err
|
||||||
})
|
}); err != nil {
|
||||||
if err == nil {
|
return nil, err
|
||||||
// TODO-2 insert into cache
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
if err := ig.state.StoreIssuer(ctx, fingerprint, issuer); err != nil {
|
||||||
|
log.Printf("error caching issuer %x (issuer will be re-retrieved from log in the future): %s", *fingerprint, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return issuer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLogClient(ctlog *loglist.Log) (ctclient.Log, ctclient.IssuerGetter, error) {
|
func newLogClient(config *Config, ctlog *loglist.Log) (ctclient.Log, ctclient.IssuerGetter, error) {
|
||||||
switch {
|
switch {
|
||||||
case ctlog.IsRFC6962():
|
case ctlog.IsRFC6962():
|
||||||
logURL, err := url.Parse(ctlog.URL)
|
logURL, err := url.Parse(ctlog.URL)
|
||||||
|
@ -186,6 +198,7 @@ func newLogClient(ctlog *loglist.Log) (ctclient.Log, ctclient.IssuerGetter, erro
|
||||||
log: ctlog,
|
log: ctlog,
|
||||||
client: client,
|
client: client,
|
||||||
}, &issuerGetter{
|
}, &issuerGetter{
|
||||||
|
state: config.State,
|
||||||
logGetter: client,
|
logGetter: client,
|
||||||
}, nil
|
}, nil
|
||||||
default:
|
default:
|
||||||
|
@ -194,7 +207,7 @@ func newLogClient(ctlog *loglist.Log) (ctclient.Log, ctclient.IssuerGetter, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func monitorLogContinously(ctx context.Context, config *Config, ctlog *loglist.Log) (returnedErr error) {
|
func monitorLogContinously(ctx context.Context, config *Config, ctlog *loglist.Log) (returnedErr error) {
|
||||||
client, issuerGetter, err := newLogClient(ctlog)
|
client, issuerGetter, err := newLogClient(config, ctlog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,14 @@ type StateProvider interface {
|
||||||
// Remove an STH so it is no longer returned by LoadSTHs.
|
// Remove an STH so it is no longer returned by LoadSTHs.
|
||||||
RemoveSTH(context.Context, LogID, *cttypes.SignedTreeHead) error
|
RemoveSTH(context.Context, LogID, *cttypes.SignedTreeHead) error
|
||||||
|
|
||||||
|
// Store a DER-encoded issuer certificate with the given fingerprint for
|
||||||
|
// retrieval by LoadIssuer. Returns nil if the issuer has already been stored.
|
||||||
|
StoreIssuer(context.Context, *[32]byte, []byte) error
|
||||||
|
|
||||||
|
// Retrieve a DER-encoded issuer certificate previously stored with StoreIssuer.
|
||||||
|
// Returns nil, nil if this issuer certificate has not been stored.
|
||||||
|
LoadIssuer(context.Context, *[32]byte) ([]byte, error)
|
||||||
|
|
||||||
// Called when a certificate matching the watch list is discovered.
|
// Called when a certificate matching the watch list is discovered.
|
||||||
NotifyCert(context.Context, *DiscoveredCert) error
|
NotifyCert(context.Context, *DiscoveredCert) error
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ func prepareStateDir(stateDir string) error {
|
||||||
return fmt.Errorf("%s was created by a newer version of certspotter; upgrade to the latest version of certspotter or remove this directory to start from scratch", stateDir)
|
return fmt.Errorf("%s was created by a newer version of certspotter; upgrade to the latest version of certspotter or remove this directory to start from scratch", stateDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, subdir := range []string{"certs", "logs", "healthchecks"} {
|
for _, subdir := range []string{"certs", "logs", "healthchecks", "issuers"} {
|
||||||
if err := os.Mkdir(filepath.Join(stateDir, subdir), 0777); err != nil && !errors.Is(err, fs.ErrExist) {
|
if err := os.Mkdir(filepath.Join(stateDir, subdir), 0777); err != nil && !errors.Is(err, fs.ErrExist) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue