Skip to content

Commit f8be625

Browse files
RA/loglist: Allow submissions to test logs from all_log_list.json (#8157)
Allow use of test ("type": "test") CT logs for Informational and Final submissions. Add new RA configuration field "SubmitToTestLogs" to optionally include test CT logs for SCT submissions. Co-authored-by: beautifulentropy <[email protected]> --------- Co-authored-by: Samantha <[email protected]>
1 parent 1f88abb commit f8be625

File tree

5 files changed

+51
-16
lines changed

5 files changed

+51
-16
lines changed

cmd/boulder-ra/main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,13 @@ func main() {
227227
allLogs, err := loglist.New(c.RA.CTLogs.LogListFile)
228228
cmd.FailOnError(err, "Failed to parse log list")
229229

230-
sctLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.SCTLogs, loglist.Issuance)
230+
sctLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.SCTLogs, loglist.Issuance, c.RA.CTLogs.SubmitToTestLogs)
231231
cmd.FailOnError(err, "Failed to load SCT logs")
232232

233-
infoLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.InfoLogs, loglist.Informational)
233+
infoLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.InfoLogs, loglist.Informational, true)
234234
cmd.FailOnError(err, "Failed to load informational logs")
235235

236-
finalLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.FinalLogs, loglist.Informational)
236+
finalLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.FinalLogs, loglist.Informational, true)
237237
cmd.FailOnError(err, "Failed to load final logs")
238238

239239
ctp = ctpolicy.New(pubc, sctLogs, infoLogs, finalLogs, c.RA.CTLogs.Stagger.Duration, logger, scope)

ctpolicy/ctconfig/ctconfig.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@ type CTConfig struct {
2424
// This may include duplicates from the lists above, to submit both precerts
2525
// and final certs to the same log.
2626
FinalLogs []string
27+
// SubmitToTestLogs enables inclusion of "test" logs when obtaining SCTs.
28+
// This should only be used in test environments.
29+
SubmitToTestLogs bool
2730
}

ctpolicy/loglist/lintlist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func InitLintList(path string) error {
2222
return
2323
}
2424

25-
l, err = l.forPurpose(Validation)
25+
l, err = l.forPurpose(Validation, false)
2626
if err != nil {
2727
lintlist.err = err
2828
return

ctpolicy/loglist/loglist.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type Log struct {
4848
EndExclusive time.Time
4949
State loglist3.LogStatus
5050
Tiled bool
51+
Type string
5152
}
5253

5354
// usableForPurpose returns true if the log state is acceptable for the given
@@ -95,6 +96,7 @@ func newHelper(file []byte) (List, error) {
9596
Url: log.URL,
9697
State: log.State.LogStatus(),
9798
Tiled: false,
99+
Type: log.Type,
98100
}
99101

100102
if log.TemporalInterval != nil {
@@ -114,6 +116,7 @@ func newHelper(file []byte) (List, error) {
114116
Url: log.SubmissionURL,
115117
State: log.State.LogStatus(),
116118
Tiled: true,
119+
Type: log.Type,
117120
}
118121

119122
if log.TemporalInterval != nil {
@@ -133,13 +136,13 @@ func newHelper(file []byte) (List, error) {
133136
// given purpose. It returns an error if any of the given names are not found
134137
// in the starting list, or if the resulting list is too small to satisfy the
135138
// Chrome "two operators" policy.
136-
func (ll List) SubsetForPurpose(names []string, p purpose) (List, error) {
139+
func (ll List) SubsetForPurpose(names []string, p purpose, submitToTestLogs bool) (List, error) {
137140
sub, err := ll.subset(names)
138141
if err != nil {
139142
return nil, err
140143
}
141144

142-
res, err := sub.forPurpose(p)
145+
res, err := sub.forPurpose(p, submitToTestLogs)
143146
if err != nil {
144147
return nil, err
145148
}
@@ -171,17 +174,24 @@ func (ll List) subset(names []string) (List, error) {
171174
}
172175

173176
// forPurpose returns a new log list containing only those logs whose states are
174-
// acceptable for the given purpose. It returns an error if the purpose is
175-
// Issuance or Validation and the set of remaining logs is too small to satisfy
176-
// the Google "two operators" log policy.
177-
func (ll List) forPurpose(p purpose) (List, error) {
177+
// acceptable for the given purpose. Test logs are included only when
178+
// submitToTestLogs is true. It returns an error if the purpose is Issuance or
179+
// Validation and the set of remaining logs is too small to satisfy the Google
180+
// "two operators" log policy.
181+
func (ll List) forPurpose(p purpose, submitToTestLogs bool) (List, error) {
178182
res := make(List, 0)
179183
operators := make(map[string]struct{})
184+
185+
// Test logs in Chrome's all_logs_list.json omit the "state" field. loglist3
186+
// interprets this as "UndefinedLogStatus", which causes usableForPurpose()
187+
// to return false. To account for this, we skip this check for test logs.
180188
for _, log := range ll {
181-
if !usableForPurpose(log.State, p) {
189+
if log.Type == "test" && !submitToTestLogs {
190+
continue
191+
}
192+
if log.Type != "test" && !usableForPurpose(log.State, p) {
182193
continue
183194
}
184-
185195
res = append(res, log)
186196
operators[log.Operator] = struct{}{}
187197
}

ctpolicy/loglist/loglist_test.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestForPurpose(t *testing.T) {
5959
Log{Name: "Log A1", Operator: "A", State: loglist3.UsableLogStatus},
6060
Log{Name: "Log B1", Operator: "B", State: loglist3.UsableLogStatus},
6161
}
62-
actual, err := input.forPurpose(Issuance)
62+
actual, err := input.forPurpose(Issuance, false)
6363
test.AssertNotError(t, err, "should have two acceptable logs")
6464
test.AssertDeepEquals(t, actual, expected)
6565

@@ -71,14 +71,14 @@ func TestForPurpose(t *testing.T) {
7171
Log{Name: "Log C1", Operator: "C", State: loglist3.PendingLogStatus},
7272
Log{Name: "Log C2", Operator: "C", State: loglist3.ReadOnlyLogStatus},
7373
}
74-
_, err = input.forPurpose(Issuance)
74+
_, err = input.forPurpose(Issuance, false)
7575
test.AssertError(t, err, "should only have one acceptable log")
7676

7777
expected = List{
7878
Log{Name: "Log A1", Operator: "A", State: loglist3.UsableLogStatus},
7979
Log{Name: "Log C2", Operator: "C", State: loglist3.ReadOnlyLogStatus},
8080
}
81-
actual, err = input.forPurpose(Validation)
81+
actual, err = input.forPurpose(Validation, false)
8282
test.AssertNotError(t, err, "should have two acceptable logs")
8383
test.AssertDeepEquals(t, actual, expected)
8484

@@ -87,9 +87,31 @@ func TestForPurpose(t *testing.T) {
8787
Log{Name: "Log B1", Operator: "B", State: loglist3.QualifiedLogStatus},
8888
Log{Name: "Log C1", Operator: "C", State: loglist3.PendingLogStatus},
8989
}
90-
actual, err = input.forPurpose(Informational)
90+
actual, err = input.forPurpose(Informational, false)
9191
test.AssertNotError(t, err, "should have three acceptable logs")
9292
test.AssertDeepEquals(t, actual, expected)
93+
94+
input = List{
95+
Log{Name: "Log A1", Operator: "A", State: loglist3.UsableLogStatus},
96+
Log{Name: "Log B1", Operator: "B", State: loglist3.UsableLogStatus},
97+
Log{Name: "Log T1", Operator: "T", Type: "test", State: loglist3.UndefinedLogStatus},
98+
}
99+
expected = List{
100+
Log{Name: "Log A1", Operator: "A", State: loglist3.UsableLogStatus},
101+
Log{Name: "Log B1", Operator: "B", State: loglist3.UsableLogStatus},
102+
}
103+
actual, err = input.forPurpose(Issuance, false)
104+
test.AssertNotError(t, err, "should have two acceptable logs with submitToTestLogs=[false]")
105+
test.AssertDeepEquals(t, actual, expected)
106+
107+
expected = List{
108+
Log{Name: "Log A1", Operator: "A", State: loglist3.UsableLogStatus},
109+
Log{Name: "Log B1", Operator: "B", State: loglist3.UsableLogStatus},
110+
Log{Name: "Log T1", Operator: "T", Type: "test", State: loglist3.UndefinedLogStatus},
111+
}
112+
actual, err = input.forPurpose(Issuance, true)
113+
test.AssertNotError(t, err, "should have two acceptable logs with submitToTestLogs=[true]")
114+
test.AssertDeepEquals(t, actual, expected)
93115
}
94116

95117
func TestForTime(t *testing.T) {

0 commit comments

Comments
 (0)