certificates/ct/multilog.go
2019-02-12 16:55:01 -08:00

84 lines
1.9 KiB
Go

package ct
// MultiLog is the interface used to send certificates to multiple logs.
type MultiLog interface {
GetSCTs(asn1Data ...[]byte) ([]*SCT, error)
SubmitToLogs(asn1Data ...[]byte) ([]*SCT, error)
}
// MultiLogImpl is the implementation used to send certificates to multiple
// logs.
type MultiLogImpl struct {
clients []Client
configs []Config
}
type result struct {
sct *SCT
err error
uri string
}
// NewMultiLog returns a MultiLog with the given configuration.
func NewMultiLog(config []Config) (MultiLog, error) {
ml := new(MultiLogImpl)
for _, cfg := range config {
client, err := New(cfg)
if err != nil {
return nil, err
}
ml.clients = append(ml.clients, client)
}
return ml, nil
}
// GetSCTs submit the precertificate to the logs and returns the list of SCTs to
// embed into the certificate.
func (c *MultiLogImpl) GetSCTs(asn1Data ...[]byte) (scts []*SCT, err error) {
results := make(chan result, len(c.clients))
for i := range c.clients {
client := c.clients[i]
config := c.configs[i]
go func() {
sct, err := client.GetSCTs(asn1Data...)
results <- result{sct: sct, err: err, uri: config.URI}
}()
}
for i := 0; i < len(c.clients); i++ {
res := <-results
switch {
case res.sct != nil:
scts = append(scts, res.sct)
case res.err != nil && err != nil:
err = res.err
}
}
return scts, err
}
// SubmitToLogs submits the certificate to the certificate transparency logs.
func (c *MultiLogImpl) SubmitToLogs(asn1Data ...[]byte) (scts []*SCT, err error) {
results := make(chan result, len(c.clients))
for i := range c.clients {
client := c.clients[i]
config := c.configs[i]
go func() {
sct, err := client.SubmitToLogs(asn1Data...)
results <- result{sct: sct, err: err, uri: config.URI}
}()
}
for i := 0; i < len(c.clients); i++ {
res := <-results
switch {
case res.sct != nil:
scts = append(scts, res.sct)
case res.err != nil && err != nil:
err = res.err
}
}
return scts, err
}