Documentation ¶
Overview ¶
Package certmanager manages signed exchange certificates.
To get the certificate managed, the caller needs to specify the location of the PEM file and calls the Manager's Start method at minimum:
m := certmanager.NewManager(certmanager.Config{ RawChainSource: certmanager.WatchCertFile(certmanager.WatchConfig{ Path: "/path/to/your.pem", }) }) m.Start() defer m.Stop()
The above code lets the Manager check the PEM file every hour and retrieve the OCSP response from the OCSP responder as needed.
The Manager caches the certificate chain and the OCSP response into a disk if configured with a DiskCache. It enables them to be shared among multiple processes, e.g. with other webpackager instances, in order to reduce the OCSP responder's load.
Internals ¶
Manager consists of two components: Producer and Cache. Producer produces certificates and sends them to Manager continuously. Cache stores produced certificates somewhere and possibly allows sharing them beyond the current running process.
The certmanager package provides Augmentor as the canonical implementation of Producer, which is composed of RawChainSource and OCSPRespSource. It looks for the updated certificate chain and OCSP response at the right timings, and uses NewAugmentedChain to turn them into an AugmentedChain. The "timings" are controlled by RawChainSource and OCSPRespSource; see the GoDoc of those types for details.
BUG(tomokinat): Manager writes to Cache, but certmanager does not reuse the cached information yet.
Index ¶
- Variables
- type Augmentor
- type Cache
- type Config
- type FetchTiming
- type FetchTimingFunc
- type LocalCertFile
- type LocalCertFileConfig
- type Manager
- type MultiCertDiskCache
- type MultiCertDiskCacheConfig
- type OCSPClient
- type OCSPClientConfig
- type OCSPRespSource
- type Producer
- type RawChainSource
- type SingleCertDiskCache
- type SingleCertDiskCacheConfig
- Bugs
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultBackoff = backoff.Backoff{ Factor: 2, Jitter: true, Min: time.Second, Max: time.Hour, }
DefaultBackoff is the backoff used by OCSPClient by default.
var DefaultOCSPClient = NewOCSPClient(OCSPClientConfig{})
DefaultOCSPClient is an OCSPClient with the default configuration.
var ErrNotFound = errors.New("certmanager: no certificate chain found for the specified digest")
ErrNotFound is returned by Read if it is unable to find the AugmentedChain using the provided digest.
Functions ¶
This section is empty.
Types ¶
type Augmentor ¶
type Augmentor struct {
// contains filtered or unexported fields
}
Augmentor combines RawChainSource and OCSPRespSource to serve as a Producer.
func NewAugmentor ¶
func NewAugmentor(rcSource RawChainSource, orSource OCSPRespSource) *Augmentor
NewAugmentor creates and initializes a new Augmentor. orSource can be nil, in which case DefaultOCSPClient is used.
NewAugmentor does not start the production of AugmentedChains automatically. To start it, call Start.
func (*Augmentor) Out ¶
func (a *Augmentor) Out() <-chan *certchain.AugmentedChain
Out returns the channel to receive produced AugmentedChains.
type Cache ¶
type Cache interface { // Read returns an AugmentedChain with the provided digest. If it cannot // find such an AugmentedChain, it returns ErrNotFound. Read(digest string) (*certchain.AugmentedChain, error) // ReadLatest returns the latest version of the AugmentedChain. If it cannot // find such an AugmentedChain, it returns ErrNotFound. ReadLatest() (*certchain.AugmentedChain, error) // Write writes the AugmentedChain into the Cache. Write(ac *certchain.AugmentedChain) error }
Cache represents a storage to cache an AugmentedChain.
var NullCache Cache = &nullCache{}
NullCache is a dummy Cache that does nothing.
type Config ¶
type Config struct { // RawChainSource is used as part of a new Augmentor. // It may not be nil unless Producer is specified. RawChainSource RawChainSource // OCSPRespSource is used as part of a new Augmentor. // nil implies DefaultOCSPClient. OCSPRespSource OCSPRespSource // Producer allows specifying the Producer directly, especially using // a custom implementation. Producer takes precedence: RawChainSource // and OCSPRespSource will not be used if Producer is set non-nil. Producer Producer // Cache specifies where to cache the signed exchange certificates. // nil implies NullCache, i.e. no caching. Cache Cache }
Config configures Manager.
type FetchTiming ¶
type FetchTiming interface { // GetNextRun determines the nextRun return parameter. GetNextRun() futureevent.Event }
FetchTiming controls the frequency of the Fetch calls on RawChainSource or OCSPRespSource.
var FetchHourly FetchTiming = FetchAtIntervals(time.Hour)
FetchHourly makes Fetch called every hour.
func FetchAtIntervals ¶
func FetchAtIntervals(interval time.Duration) FetchTiming
FetchAtIntervals makes Fetch called at fixed intervals.
func FetchAtIntervalsWithEventFactory ¶
func FetchAtIntervalsWithEventFactory(interval time.Duration, factory futureevent.Factory) FetchTiming
FetchAtIntervalsWithEventFactory is like FetchAtIntervals but uses factory instead of futureevent.DefaultFactory.
func FetchOnSignal ¶
func FetchOnSignal(sig os.Signal) FetchTiming
FetchOnSignal makes Fetch called when signaled by sig.
func FetchOnlyOnce ¶
func FetchOnlyOnce() FetchTiming
FetchOnlyOnce makes Fetch called only once, not repeatedly.
type FetchTimingFunc ¶
type FetchTimingFunc func() futureevent.Event
FetchTimingFunc turns a function into a FetchTiming.
func (FetchTimingFunc) GetNextRun ¶
func (f FetchTimingFunc) GetNextRun() futureevent.Event
GetNextRun calls f().
type LocalCertFile ¶
type LocalCertFile struct {
LocalCertFileConfig
}
LocalCertFile is a RawChainSource which reads the certificate chain from a local file in the PEM format.
Example (Hourly) ¶
The following code creates a new LocalCertFile that reads cert.pem (roughly) every other hours.
package main import ( "time" "github.com/layer0-platform/webpackager/certchain/certmanager" ) func main() { c := certmanager.LocalCertFileConfig{ Path: "cert.pem", FetchTiming: certmanager.FetchAtIntervals(2 * time.Hour), } _ = certmanager.NewLocalCertFile(c) }
Output:
Example (Signal) ¶
The following code creates a new LocalCertFile that reads cert.pem every time the running process receives the USR1 signal.
package main import ( "syscall" "github.com/layer0-platform/webpackager/certchain/certmanager" ) func main() { c := certmanager.LocalCertFileConfig{ Path: "cert.pem", FetchTiming: certmanager.FetchOnSignal(syscall.SIGUSR1), } _ = certmanager.NewLocalCertFile(c) }
Output:
func NewLocalCertFile ¶
func NewLocalCertFile(c LocalCertFileConfig) *LocalCertFile
NewLocalCertFile creates and initializes a new LocalCertFile.
type LocalCertFileConfig ¶
type LocalCertFileConfig struct { // Path locates the PEM file containing the certificate chain. Path string // FetchTiming controls the frequency of checking for the certificate. // nil implies certmanager.FetchHourly. FetchTiming FetchTiming // AllowTestCert specifies whether to allow test certificates. // // LocalCertFile calls VerifyChain and VerifySXGCriteria to make sure // RawChain is valid for use with signed exchanges. If AllowTestCert // is set true, LocalCertFile skips VerifySXGCriteria and accepts any // RawChain as long as it is valid in terms of VerifyChain. AllowTestCert bool }
type Manager ¶
type Manager struct { Cache Cache // contains filtered or unexported fields }
Manager keeps a signed exchange certificate up-to-date. See the package document for details.
func NewManager ¶
NewManager creates and initializes a new Manager.
func (*Manager) GetAugmentedChain ¶
func (m *Manager) GetAugmentedChain() *certchain.AugmentedChain
GetAugmentedChain returns the AugmentedChain that m currently holds.
func (*Manager) Start ¶
Start starts managing the certificate. It starts Producer and waits for the first AugmentedChain, then kicks in a goroutine to keep Cache updated with the received AugmentedChains. The execution is blocked until the first AugmentedChain comes in.
To stop the management, call Stop.
func (*Manager) Stop ¶
func (m *Manager) Stop()
Stop stops the Manager m from managing the certificate: stops m.Producer and the cache updater goroutine spawned by Start.
If m is writing an AugmentedChain to m.Cache when Stop is called, that cache write continues on background. Stop returns without waiting for its completion.
type MultiCertDiskCache ¶
type MultiCertDiskCache struct {
MultiCertDiskCacheConfig
}
MultiCertDiskCache is a Cache on a local filesystem. It writes the certificate chain in the PEM format and the OCSP response in the DER format to separate files as specified by MultiCertDiskCacheConfig. It uses the digest of the certificate chain as the basename for the certificate and OCSP files.
func NewMultiCertDiskCache ¶
func NewMultiCertDiskCache(config MultiCertDiskCacheConfig) (*MultiCertDiskCache, error)
NewMultiCertDiskCache creates and initializes a new MultiCertDiskCache.
func (*MultiCertDiskCache) Read ¶
func (d *MultiCertDiskCache) Read(digest string) (*certchain.AugmentedChain, error)
Read reads the certificate chain and the OCSP response from local files and reproduces an AugmentedChain. Read uses digest as the base filename used to retrieve the elements needed to construct the AugmentedChain. Read returns a multierror.Error (hashicorp/go-multierror) to report as many problems as possible.
func (*MultiCertDiskCache) ReadLatest ¶
func (d *MultiCertDiskCache) ReadLatest() (*certchain.AugmentedChain, error)
ReadLatest returns the latest version of the AugmentedChain in the cache, ErrNotFound otherwise.
func (*MultiCertDiskCache) Write ¶
func (d *MultiCertDiskCache) Write(ac *certchain.AugmentedChain) error
Write writes the certificate chain and the OCSP response from ac into local files. It returns a multierror.Error (hashicorp/go-multierror) to report as many problems as possible.
type MultiCertDiskCacheConfig ¶
type MultiCertDiskCacheConfig struct { // CertDir locates the directory to write the certificate chain to. // If CertDir is empty, NewMultiCertDiskCache returns an error. CertDir string // LatestCertFile specifies the filename to be used for the latest // version of the certificate. The file will be located in CertDir. // If LatestCertFile is empty, NewMultiCertDiskCache returns an error. LatestCertFile string // LatestOCSPFile specifies the filename to be used for the latest // version of the OCSP. The file will be located in CertDir. // If LatestOCSPFile is empty, NewMultiCertDiskCache returns an error. LatestOCSPFile string // LockFile locates the lock file. Must be non-empty. The file will be // located in CertDir. If LockFile is empty, NewMultiCertDiskCache returns // an error. LockFile string }
MultiCertDiskCacheConfig configures DiskCache.
type OCSPClient ¶
type OCSPClient struct {
OCSPClientConfig
}
OCSPClient represents a client of OCSP over HTTP.
func NewOCSPClient ¶
func NewOCSPClient(config OCSPClientConfig) *OCSPClient
NewOCSPClient creates and initializes a new OCSPClient.
func (OCSPClient) Fetch ¶
func (c OCSPClient) Fetch(chain *certchain.RawChain, now func() time.Time) (ocspResp *certchain.OCSPResponse, nextRun futureevent.Event, err error)
Fetch sends an OCSP request to the OCSP responder at chain.OCSPServer and returns the parsed OCSP response, with a futureevent.Event to notify when this OCSPClient expects the next call of Fetch.
now is a function that returns the current time, usually time.Now. Fetch calls it after retrieving and parsing the OCSP response and examines the validity as of the returned time.
On success, nextRun will be set with the middle point between ThisUpdate and NextUpdate of the OCSP response or the cache expiry time of the HTTP response, whichever comes earlier. On failure, the next Fetch will be scheduled for a retry at the time determined based on c.RetryPolicy.
Keep in mind that a clock skew between the local machine and the OCSP server could cause a valid response to be judged invalid. To mitigate it, include some tweaks in the now function.
type OCSPClientConfig ¶
type OCSPClientConfig struct { // HTTPClient is an HTTP client used to send an OCSP request. // nil implies http.DefaultClient. HTTPClient *http.Client // RetryPolicy determines when to make a retry on fetch failure. // nil implies DefaultBackoff. RetryPolicy *backoff.Backoff // AllowTestCert specifies whether to allow certificates without // any OCSP URI. If AllowTestCert is set true, OCSPClient returns // DummyOCSPResponse for OCSP-less certificates. AllowTestCert bool // NewFutureEventAt is called by Fetch to create the nextRun return // parameter. nil implies futureevent.DefaultFactory. NewFutureEventAt futureevent.Factory }
OCSPClientConfig configures OCSPClient.
type OCSPRespSource ¶
type OCSPRespSource interface { // Fetch retrieves an OCSP response for chain and returns the parsed OCSP // response with a futureevent.Event to notify when the OCSPRespSource // expects the next call of Fetch. // // now is a function which returns the current time. Fetch calls it after // retriving and parsing the OCSP response and examines the validity as // of the returned time. time.Now will do in most of the time, but the // caller may want to use a different function in unit testing or to deal // with clock skews. // // nextRun is always non-nil and valid, even in the error case. Fetch(chain *certchain.RawChain, now func() time.Time) (ocspResp *certchain.OCSPResponse, nextRun futureevent.Event, err error) }
OCSPRespSource provides an OCSPResponse. It is designed to be called repeatedly: the Fetch method does not just return the OCSP response, but also instructs when it should be called again to receive the next update.
var DummyOCSPRespSource OCSPRespSource = &dummyOCSPRespSource{}
DummyOCSPRespSource always returns certchain.DummyOCSPResponse.
type Producer ¶
type Producer interface { // Out returns the channel to receive produced AugmentedChains. Out() <-chan *certchain.AugmentedChain // Start starts producing new AugmentedChains. Start() error // Stop stops producing new AugmentedChains. Stop() }
Producer produces a new AugmentedChain repeatedly and sends it through a channel every time Producer completes the production.
type RawChainSource ¶
type RawChainSource interface { // Fetch returns a new RawChain to replace chain with a futureevent.Event // to notify when the RawChainSource expects the next call of Fetch. // // chain can be nil. Fetch returns a valid RawChain, which the caller can // use as the initial one. // // now is a function which returns the current time. Fetch calls it after // retrieving and parsing the certificate chain and examines the validity // as of the returned time. time.Now will do in most of the time, but the // caller may want to use a different function in unit testing or to deal // with clock skews. // // Fetch may return chain as newChain if it is valid and still up-to-date. // // nextRun is always non-nil and valid, even in the error case. Fetch(chain *certchain.RawChain, now func() time.Time) (newChain *certchain.RawChain, nextRun futureevent.Event, err error) }
RawChainSource provides a RawChain. It is designed to be called repeatedly: the Fetch method does not just return the latest certificate chain, but also instructs when it should be called again to receive the next update.
type SingleCertDiskCache ¶
type SingleCertDiskCache struct {
SingleCertDiskCacheConfig
}
SingleCertDiskCache is a Cache on a local filesystem. It writes the certificate chain in the PEM format and the OCSP response in the DER format to separate files as specified by SingleCertDiskCacheConfig.
func NewSingleCertDiskCache ¶
func NewSingleCertDiskCache(config SingleCertDiskCacheConfig) *SingleCertDiskCache
NewSingleCertDiskCache creates and initializes a new SingleCertDiskCache.
func (*SingleCertDiskCache) Read ¶
func (d *SingleCertDiskCache) Read(digest string) (*certchain.AugmentedChain, error)
Read reads the certificate chain and the OCSP response from local files and reproduces an AugmentedChain. Read works only when d.CertPath and d.OCSPPath are both non-empty and otherwise returns an error. Read returns a multierror.Error (hashicorp/go-multierror) to report as many problems as possible.
func (*SingleCertDiskCache) ReadLatest ¶
func (d *SingleCertDiskCache) ReadLatest() (*certchain.AugmentedChain, error)
ReadLatest returns the cached AugmentedChain, otherwise it returns an error.
func (*SingleCertDiskCache) Write ¶
func (d *SingleCertDiskCache) Write(ac *certchain.AugmentedChain) error
Write writes the certificate chain and the OCSP response from ac into local files. It returns a multierror.Error (hashicorp/go-multierror) to report as many problems as possible.
type SingleCertDiskCacheConfig ¶
type SingleCertDiskCacheConfig struct { // CertPath locates the PEM file to write the certificate chain to. // If CertPath is empty, the certificate chain is not cached. CertPath string // OCSPPath locates the file to write the OCSP response DER bytes to. // If OCSPPath is empty, the OCSP response is not cached. OCSPPath string // LockPath locates the lock file. Must be non-empty. LockPath string }
SingleCertDiskCacheConfig configures SingleCertDiskCache.
Notes ¶
Bugs ¶
Manager writes to Cache, but certmanager does not reuse the cached information yet.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package acmeclient provides a RawChainSource to acquire a signed exchange certificate using the ACME protocol.
|
Package acmeclient provides a RawChainSource to acquire a signed exchange certificate using the ACME protocol. |
Package futureevent defines interface to handle future events.
|
Package futureevent defines interface to handle future events. |