122 lines
3.8 KiB
Go
122 lines
3.8 KiB
Go
package ctconfig
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/letsencrypt/boulder/config"
|
|
)
|
|
|
|
// LogShard describes a single shard of a temporally sharded
|
|
// CT log
|
|
type LogShard struct {
|
|
URI string
|
|
Key string
|
|
WindowStart time.Time
|
|
WindowEnd time.Time
|
|
}
|
|
|
|
// TemporalSet contains a set of temporal shards of a single log
|
|
type TemporalSet struct {
|
|
Name string
|
|
Shards []LogShard
|
|
}
|
|
|
|
// Setup initializes the TemporalSet by parsing the start and end dates
|
|
// and verifying WindowEnd > WindowStart
|
|
func (ts *TemporalSet) Setup() error {
|
|
if ts.Name == "" {
|
|
return errors.New("Name cannot be empty")
|
|
}
|
|
if len(ts.Shards) == 0 {
|
|
return errors.New("temporal set contains no shards")
|
|
}
|
|
for i := range ts.Shards {
|
|
if !ts.Shards[i].WindowEnd.After(ts.Shards[i].WindowStart) {
|
|
return errors.New("WindowStart must be before WindowEnd")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// pick chooses the correct shard from a TemporalSet to use for the given
|
|
// expiration time. In the case where two shards have overlapping windows
|
|
// the earlier of the two shards will be chosen.
|
|
func (ts *TemporalSet) pick(exp time.Time) (*LogShard, error) {
|
|
for _, shard := range ts.Shards {
|
|
if exp.Before(shard.WindowStart) {
|
|
continue
|
|
}
|
|
if !exp.Before(shard.WindowEnd) {
|
|
continue
|
|
}
|
|
return &shard, nil
|
|
}
|
|
return nil, fmt.Errorf("no valid shard available for temporal set %q for expiration date %q", ts.Name, exp)
|
|
}
|
|
|
|
// LogDescription contains the information needed to submit certificates
|
|
// to a CT log and verify returned receipts. If TemporalSet is non-nil then
|
|
// URI and Key should be empty.
|
|
type LogDescription struct {
|
|
URI string
|
|
Key string
|
|
SubmitFinalCert bool
|
|
|
|
*TemporalSet
|
|
}
|
|
|
|
// Info returns the URI and key of the log, either from a plain log description
|
|
// or from the earliest valid shard from a temporal log set
|
|
func (ld LogDescription) Info(exp time.Time) (string, string, error) {
|
|
if ld.TemporalSet == nil {
|
|
return ld.URI, ld.Key, nil
|
|
}
|
|
shard, err := ld.TemporalSet.pick(exp)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
return shard.URI, shard.Key, nil
|
|
}
|
|
|
|
// CTGroup represents a group of CT Logs. Although capable of holding logs
|
|
// grouped by any arbitrary feature, is today primarily used to hold logs which
|
|
// are all operated by the same legal entity.
|
|
type CTGroup struct {
|
|
Name string
|
|
Logs []LogDescription
|
|
}
|
|
|
|
// CTConfig is the top-level config object expected to be embedded in an
|
|
// executable's JSON config struct.
|
|
type CTConfig struct {
|
|
// Stagger is duration (e.g. "200ms") indicating how long to wait for a log
|
|
// from one operator group to accept a certificate before attempting
|
|
// submission to a log run by a different operator instead.
|
|
Stagger config.Duration
|
|
// LogListFile is a path to a JSON log list file. The file must match Chrome's
|
|
// schema: https://www.gstatic.com/ct/log_list/v3/log_list_schema.json
|
|
LogListFile string `validate:"required"`
|
|
// SCTLogs is a list of CT log names to submit precerts to in order to get SCTs.
|
|
SCTLogs []string `validate:"min=1,dive,required"`
|
|
// InfoLogs is a list of CT log names to submit precerts to on a best-effort
|
|
// basis. Logs are included here for the sake of wider distribution of our
|
|
// precerts, and to exercise logs that in the qualification process.
|
|
InfoLogs []string
|
|
// FinalLogs is a list of CT log names to submit final certificates to.
|
|
// This may include duplicates from the lists above, to submit both precerts
|
|
// and final certs to the same log.
|
|
FinalLogs []string
|
|
}
|
|
|
|
// LogID holds enough information to uniquely identify a CT Log: its log_id
|
|
// (the base64-encoding of the SHA-256 hash of its public key) and its human-
|
|
// readable name/description. This is used to extract other log parameters
|
|
// (such as its URL and public key) from the Chrome Log List.
|
|
type LogID struct {
|
|
Name string
|
|
ID string
|
|
SubmitFinal bool
|
|
}
|