Add initial implementation of a multilog.
parent
b766f49995
commit
963fe0fa91
@ -0,0 +1,84 @@
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue