Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ strategy:
tryNextResponseThreshold: 500ms # Start submitting to the next log after this long.
slowResponseThreshold: 2s # Mark a response as "slow" after this long.
httpTimeout: 15s # HTTP client timeout for log submissions.
testLogListFilename: "" # Path to a log list JSON file that replaces the built-in test logs.
testLogListFilename: "" # Path to a log list JSON file that replaces the built-in test TLS logs. Every log must set "log_type": "test".

sthMonitor:
refreshInterval: 30s # How often to fetch each log's latest STH/checkpoint.
Expand Down Expand Up @@ -189,7 +189,7 @@ logging:
| `strategy.submission.tryNextResponseThreshold` | `500ms` | Time to wait before speculatively starting a submission to the next log. |
| `strategy.submission.slowResponseThreshold` | `2s` | Time after which a response is recorded as "slow" for future dispreferal. |
| `strategy.submission.httpTimeout` | `15s` | HTTP client timeout for submissions to CT logs. |
| `strategy.testLogListFilename` | _(empty)_ | Path to a [v3 log list JSON](https://www.gstatic.com/ct/log_list/v3/log_list_schema.json) file. When set, its logs replace the test logs derived from `ctloglists`, and are used for `test_tls_logs.json` and for submissions that request test logs. Chain validation is skipped for logs with no known accepted roots, so the log itself decides whether to accept a submission. |
| `strategy.testLogListFilename` | _(empty)_ | Path to a [v3 log list JSON](https://www.gstatic.com/ct/log_list/v3/log_list_schema.json) file. When set, its logs replace the test TLS logs derived from `ctloglists`, and are used for `test_tls_logs.json` and for TLS certificate submissions that request test logs. Every log (and tiled log) in the file must set `"log_type": "test"`; ctsubmit refuses to start otherwise. Chain validation is skipped for logs with no known accepted roots, so the log itself decides whether to accept a submission. |

#### STH Monitor

Expand Down
8 changes: 8 additions & 0 deletions loglists/customTestLogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ func validateLogList(logList *loglist3.LogList) error {
if log.URL == "" {
return fmt.Errorf("log %q: url is required", log.Description)
}
// Every custom log must be a test log, so it can never leak into the usable/active log lists.
if log.Type != "test" {
return fmt.Errorf("log %q: log_type must be \"test\", got %q", log.Description, log.Type)
}
if err := validateLogID(log.LogID, log.Key); err != nil {
return fmt.Errorf("log %q: %w", log.Description, err)
}
Expand All @@ -81,6 +85,10 @@ func validateLogList(logList *loglist3.LogList) error {
if tiledLog.MonitoringURL == "" {
return fmt.Errorf("tiled log %q: monitoring_url is required", tiledLog.Description)
}
// Every custom log must be a test log, so it can never leak into the usable/active log lists.
if tiledLog.Type != "test" {
return fmt.Errorf("tiled log %q: log_type must be \"test\", got %q", tiledLog.Description, tiledLog.Type)
}
if err := validateLogID(tiledLog.LogID, tiledLog.Key); err != nil {
return fmt.Errorf("tiled log %q: %w", tiledLog.Description, err)
}
Expand Down
21 changes: 15 additions & 6 deletions loglists/customTestLogs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func writeCustomTestLogList(t *testing.T, timestamp string) (string, [sha256.Siz
"key": base64.StdEncoding.EncodeToString(spki),
"url": "https://custom.test.log.example.com/",
"mmd": 86400,
"log_type": "test",
},
},
},
Expand Down Expand Up @@ -187,25 +188,33 @@ func TestValidateLogList(t *testing.T) {
wantError bool
}{
"valid log": {
logList: newLogList(&loglist3.Log{LogID: logID[:], Key: spki, URL: "https://log.example.com/"}, nil),
logList: newLogList(&loglist3.Log{LogID: logID[:], Key: spki, URL: "https://log.example.com/", Type: "test"}, nil),
},
"valid tiled log": {
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, SubmissionURL: "https://log.example.com/", MonitoringURL: "https://log.example.com/"}),
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, SubmissionURL: "https://log.example.com/", MonitoringURL: "https://log.example.com/", Type: "test"}),
},
"log without url": {
logList: newLogList(&loglist3.Log{LogID: logID[:], Key: spki}, nil),
logList: newLogList(&loglist3.Log{LogID: logID[:], Key: spki, Type: "test"}, nil),
wantError: true,
},
"log without test marker": {
logList: newLogList(&loglist3.Log{LogID: logID[:], Key: spki, URL: "https://log.example.com/"}, nil),
wantError: true,
},
"tiled log without submission_url": {
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, MonitoringURL: "https://log.example.com/"}),
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, MonitoringURL: "https://log.example.com/", Type: "test"}),
wantError: true,
},
"tiled log without monitoring_url": {
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, SubmissionURL: "https://log.example.com/"}),
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, SubmissionURL: "https://log.example.com/", Type: "test"}),
wantError: true,
},
"tiled log without test marker": {
logList: newLogList(nil, &loglist3.TiledLog{LogID: logID[:], Key: spki, SubmissionURL: "https://log.example.com/", MonitoringURL: "https://log.example.com/"}),
wantError: true,
},
"log_id does not match key": {
logList: newLogList(&loglist3.Log{LogID: make([]byte, sha256.Size), Key: spki, URL: "https://log.example.com/"}, nil),
logList: newLogList(&loglist3.Log{LogID: make([]byte, sha256.Size), Key: spki, URL: "https://log.example.com/", Type: "test"}, nil),
wantError: true,
},
}
Expand Down