Skip to content

submission: verify CT log list signatures#1786

Draft
1seal wants to merge 1 commit intogoogle:masterfrom
1seal:codex/ctgo-loglist-signatures
Draft

submission: verify CT log list signatures#1786
1seal wants to merge 1 commit intogoogle:masterfrom
1seal:codex/ctgo-loglist-signatures

Conversation

@1seal
Copy link
Copy Markdown
Contributor

@1seal 1seal commented Apr 22, 2026

summary

  • verify the built-in Chrome CT log list URLs against the published signature and public key before refreshing submission targets
  • add -loglist_sig_path and -loglist_public_key for deployments that want signature verification on custom log list sources
  • add unit tests for built-in verification wiring, successful signed refreshes, and signature failures

why

submission/loglist_refresher.go currently refreshes -loglist_path with loglist3.NewFromJSON, which means the submission server trusts the log URLs and public keys embedded in the JSON before validating the log list's integrity.

This change makes the default Chrome log list source fail closed on signature verification, while keeping custom sources explicit: operators can provide a signature path and pinned public key when they need a non-default signed log list.

validation

  • go test ./submission/...

@jdeblasio
Copy link
Copy Markdown

Chrome log list maintainer here (but not a c-t-go maintainer).

I don't support this change, at least not without significant modifications and understanding the motivation. Was there a cause for this change?

Most log list clients should not be checking signatures, and doing so will result a meaningful reduction in reliability. If this library absolutely needed signature verification, it should be using the combined .zip file rather than the .sig file independently. See this thread for details on why.

The only clients who really need to be validating their log list integrity to maintain their security guarantees are CT-enforcing clients. Chrome doesn't use this library (nor this log list endpoint), and other clients besides Chrome are not permitted to use the log list for CT enforcement. Clients using the list for other reasons should trust TLS to do its job -- authenticating the endpoint. As one example, a certificate submitter (e.g. a CA) that doesn't check its signatures could conceivably receive a log list not authorized by Chrome, and that could result in the submitter to assemble a set of SCTs that might cause the certificate(s) they're submitting to fail to validate in Chrome due to not including SCTs from recognized logs. While that's a potential DoS risk, it's not a security issue since the certificate was not trusted. Moreover, executing on this attack required compromising a TLS connection to Google's servers.

At some point, we're going to remove the .sig file entirely, and may remove the .zip at some point as well.

@1seal
Copy link
Copy Markdown
Contributor Author

1seal commented Apr 28, 2026

@jdeblasio thanks, this is very helpful context.

there wasn't a specific incident behind this change on my side; i was treating it as a hardening change. submission/loglist_refresher.go currently treats the fetched JSON as authoritative and immediately trusts the embedded log URLs and public keys, so i tried to make the built-in Chrome source fail closed if the list could not be authenticated.

your explanation changes the framing for me. for this submission client, a bad log list is mainly an availability / operational-correctness problem, not a CT-enforcement security boundary, so default signature verification adds fragility without buying much. i also missed the point that fetching .json and .sig independently is the wrong primitive here, and that clients which truly need integrity verification should not build on the detached .sig path.

given that, i think the default verification behavior in this PR is the wrong direction for this client, so i’m going to close it rather than push further on the built-in Chrome endpoints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants