From 3f58ac453b4115720deb84517ffcf7d423f14f29 Mon Sep 17 00:00:00 2001 From: Martin Hutchinson Date: Wed, 15 Jul 2026 11:03:55 +0000 Subject: [PATCH] [Docs] Better docs for CT functions Renamed Sunlight to Static CT, and added pointers to the RFC 6962 to Checkpoint conversion --- README.md | 4 ++++ log/README.md | 8 ++++++++ log/checkpoint.go | 3 +++ note/note_rfc6962.go | 8 ++++---- note/note_verifier_test.go | 2 +- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f160377..bd922ad 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ provided in the respective directories: The [`log checkpoint`](./log/README.md#checkpoint-format) represents a commitment to the state of a transparent log. +### RFC 6962 / Certificate Transparency Interoperability + +For interoperability with classic RFC 6962 logs, the [`note`](./note) package provides tools to convert Signed Tree Heads (STHs) to the checkpoint format and verify their signatures. See [`note_rfc6962.go`](./note/note_rfc6962.go) for details. + ## Support * Mailing list: https://groups.google.com/forum/#!forum/trillian-transparency - Slack: https://transparency-dev.slack.com/ ([invitation](https://transparency.dev/slack/)) diff --git a/log/README.md b/log/README.md index 887ce47..76284de 100644 --- a/log/README.md +++ b/log/README.md @@ -86,6 +86,14 @@ If you plan to use `otherdata` in your log, see the section on [merging checkpoi The first signature on a checkpoint should be from the log which issued it, but there MUST NOT be more than one signature from a log identity present on the checkpoint. +## RFC 6962 (Certificate Transparency) Interoperability + +If you need to work with classic RFC 6962 CT logs, you can convert their JSON Signed Tree Heads (STHs) to this checkpoint format. + +The conversion and verification tools are located in the [`note`](../note) package: +* [`note.RFC6962STHToCheckpoint`](../note/note_rfc6962.go) converts an STH to a signed checkpoint. +* [`note.NewRFC6962Verifier`](../note/note_rfc6962.go) creates a verifier for these checkpoint signatures. + ## Example An annotated example signed checkpoint in this format is shown below: diff --git a/log/checkpoint.go b/log/checkpoint.go index 3bbaacb..c7555b6 100644 --- a/log/checkpoint.go +++ b/log/checkpoint.go @@ -14,6 +14,9 @@ // Package log provides basic support for the common log checkpoint and proof // format described by the README in this directory. +// +// For converting classic RFC 6962 Signed Tree Heads (STH) to this checkpoint +// format, see note.RFC6962STHToCheckpoint in the github.com/transparency-dev/formats/note package. package log import ( diff --git a/note/note_rfc6962.go b/note/note_rfc6962.go index 4bc03db..7ed3a66 100644 --- a/note/note_rfc6962.go +++ b/note/note_rfc6962.go @@ -48,7 +48,7 @@ func RFC6962VerifierString(logURL string, pubK crypto.PublicKey) (string, error) return fmt.Sprintf("%s+%08x+%s", name, hash, base64.StdEncoding.EncodeToString(append([]byte{algRFC6962STH}, pubSer...))), nil } -// NewRFC6962Verifier creates a note verifier for Sunlight/RFC6962 checkpoint signatures. +// NewRFC6962Verifier creates a note verifier for Static CT/RFC6962 checkpoint signatures. func NewRFC6962Verifier(vkey string) (note.Verifier, error) { name, vkey, _ := strings.Cut(vkey, "+") hash16, key64, _ := strings.Cut(vkey, "+") @@ -90,7 +90,7 @@ type signedTreeHead struct { } // RFC6962STHToCheckpoint converts the provided RFC6962 JSON representation of a CT Signed Tree Head structure to -// a sunlight style signed checkpoint. +// a Static CT style signed checkpoint. // The passed in verifier must be an RFC6929Verifier containing the correct details for the log which signed the STH. func RFC6962STHToCheckpoint(j []byte, v note.Verifier) ([]byte, error) { var sth signedTreeHead @@ -134,11 +134,11 @@ func rfc6962Keyhash(name string, logID [32]byte) uint32 { return binary.BigEndian.Uint32(r) } -// rfc6962LogName returns a sunlight checkpoint compatible log name from the +// rfc6962LogName returns a Static CT checkpoint compatible log name from the // passed in CT log root URL. // // "For example, a log with submission prefix https://rome.ct.example.com/2024h1/ will use rome.ct.example.com/2024h1 as the checkpoint origin line" -// (see https://github.com/C2SP/C2SP/blob/main/sunlight.md#checkpoints) +// (see https://github.com/C2SP/C2SP/blob/main/static-ct-api.md#checkpoints) func rfc6962LogName(logURL string) string { logURL = strings.ToLower(logURL) logURL = strings.TrimPrefix(logURL, "http://") diff --git a/note/note_verifier_test.go b/note/note_verifier_test.go index f7da03b..771468f 100644 --- a/note/note_verifier_test.go +++ b/note/note_verifier_test.go @@ -82,7 +82,7 @@ func TestNewVerifier(t *testing.T) { name: "ECDSA works", key: sigStoreKey, }, { - name: "Sunlight works", + name: "Static CT works", key: "ct.googleapis.com/logs/us1/argon2024+7deb49d0+BTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABB25bKnLaZTFXOa2pgO70rjcVEMXKJkMBgFQHZ1kwFlGK9zIAx0FtC2oCfeZQe0E++VXuiYE9hFSzhRlOy92K8A=", }, } {