or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

dirhash.mdgosumcheck.mdindex.mdmodfile.mdmodule.mdnote.mdsemver.mdstorage.mdsumdb.mdtlog.mdzip.md
tile.json

gosumcheck.mddocs/

gosumcheck - Checksum Verification Command

Command gosumcheck is a command-line utility that checks a go.sum file against a go.sum database server.

Overview

gosumcheck is a proof-of-concept command-line tool for verifying go.sum files against a checksum database. It is meant as a demonstration and should not be used in production scripts or continuous integration testing.

Important Limitations:

  • Does not cache any downloaded information between runs
  • Does not detect server misbehavior or HTTPS man-in-the-middle attacks
  • Does not set any exit status to report problems
  • Each run is expensive as it re-downloads all necessary data

For production use, use the sumdb package to implement a proper client with caching and security checks.

Installation

go install golang.org/x/mod/gosumcheck@latest

Or build from source:

git clone https://go.googlesource.com/mod
cd mod/gosumcheck
go build

Usage

gosumcheck [-h H] [-k key] [-u url] [-v] go.sum

Flags

-h H

Changes the tile height (default 8). The tile height determines the size of transparency log tiles downloaded from the server. Larger values reduce the number of HTTP requests but increase the size of each request.

Example:

gosumcheck -h 10 go.sum
-k key

Changes the go.sum database server key. This should be the verifier key for the checksum database you want to verify against.

Example:

gosumcheck -k "sum.golang.org+033de0ae+Ac4zctda..." go.sum
-u url

Overrides the URL of the server. Usually the URL is derived from the key name, but this flag allows explicit specification.

Example:

gosumcheck -u https://sum.golang.org go.sum
-v

Enables verbose output. Reports the URL and elapsed time for each server request, useful for debugging or understanding the verification process.

Example:

gosumcheck -v go.sum

Arguments

go.sum

Path to the go.sum file to verify. This is a required argument.

Examples

Basic Usage

Verify a go.sum file using default settings:

$ gosumcheck go.sum

If successful, gosumcheck will silently exit. If there are errors, they will be printed to stderr.

Verbose Mode

See what gosumcheck is doing:

$ gosumcheck -v go.sum
GET https://sum.golang.org/latest (142ms)
GET https://sum.golang.org/lookup/golang.org/x/text@v0.3.0 (89ms)
GET https://sum.golang.org/tile/8/0/000 (56ms)
GET https://sum.golang.org/tile/8/0/001 (61ms)
...

Custom Tile Height

Use larger tiles to reduce HTTP requests:

$ gosumcheck -h 10 go.sum

This downloads tiles of height 10 (1024 hashes per tile) instead of the default 8 (256 hashes per tile).

Custom Server

Verify against a custom checksum database:

$ gosumcheck -k "myserver.com+abc123+..." -u https://sumdb.myserver.com go.sum

Checking Specific Modules

Create a minimal go.sum with just the modules you want to check:

$ grep "golang.org/x/text" go.sum > text.sum
$ gosumcheck text.sum

go.sum File Format

The go.sum file contains checksums for module downloads. Each line has the format:

<module> <version> <hash>
<module> <version>/go.mod <hash>

Example go.sum:

golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=

Each module version has two lines:

  1. Hash of the module content (source code)
  2. Hash of just the go.mod file

How It Works

  1. Parse go.sum: Reads the go.sum file and extracts module paths and versions

  2. Fetch Latest Tree: Downloads the latest signed tree from the checksum database

  3. Verify Signatures: Verifies the tree signature using the server's public key

  4. Lookup Checksums: For each module in go.sum:

    • Queries the database for the official checksum
    • Downloads necessary transparency log tiles
    • Verifies inclusion proofs
  5. Compare: Compares checksums from go.sum with those from the database

  6. Report: Prints any mismatches or errors

Limitations

No Caching

Every run downloads all data fresh:

$ time gosumcheck go.sum
# Takes several seconds

$ time gosumcheck go.sum
# Takes several seconds again (no caching)

For production use, implement caching using the sumdb.Client with appropriate ClientOps.

No Exit Status

gosumcheck does not set exit status to indicate success or failure:

$ gosumcheck go.sum
$ echo $?
0  # Always 0, even if errors occurred

This makes it unsuitable for CI/CD pipelines. For automated testing, use the sumdb package directly.

No Attack Detection

gosumcheck cannot detect:

  • Server providing inconsistent tree states
  • HTTPS man-in-the-middle attacks over time
  • Timeline forks in the transparency log

A proper client implementation should cache tree states and detect inconsistencies.

Production Alternative

For production use, implement a proper client:

package main

import (
    "context"
    "log"

    "golang.org/x/mod/sumdb"
)

type ProductionClientOps struct {
    // Implement caching, monitoring, etc.
}

func (ops *ProductionClientOps) ReadRemote(path string) ([]byte, error) {
    // Implement with retries, timeouts, metrics
}

func (ops *ProductionClientOps) ReadConfig(file string) ([]byte, error) {
    // Persistent storage
}

func (ops *ProductionClientOps) WriteConfig(file string, old, new []byte) error {
    // Atomic writes
}

func (ops *ProductionClientOps) ReadCache(file string) ([]byte, error) {
    // Persistent cache
}

func (ops *ProductionClientOps) WriteCache(file string, data []byte) {
    // Persistent cache
}

func (ops *ProductionClientOps) Log(msg string) {
    log.Println(msg)
}

func (ops *ProductionClientOps) SecurityError(msg string) {
    log.Fatalf("SECURITY ERROR: %s", msg)
}

func main() {
    client := sumdb.NewClient(&ProductionClientOps{})

    // Verify checksums
    lines, err := client.Lookup("golang.org/x/text", "v0.3.0")
    if err != nil {
        log.Fatal(err)
    }

    // Compare with go.sum
    // ...
}

Debugging

Understanding Requests

Use -v to see all HTTP requests:

$ gosumcheck -v go.sum
GET https://sum.golang.org/latest (142ms)
  → Downloaded latest signed tree
GET https://sum.golang.org/lookup/golang.org/x/text@v0.3.0 (89ms)
  → Looked up module checksum
GET https://sum.golang.org/tile/8/0/000 (56ms)
  → Downloaded transparency log tile

Tile Height Impact

Compare different tile heights:

# Default (height 8 = 256 hashes/tile)
$ time gosumcheck go.sum
# May make more requests

# Larger tiles (height 10 = 1024 hashes/tile)
$ time gosumcheck -h 10 go.sum
# Fewer requests, more data per request

Testing Custom Servers

Test against a local checksum database:

$ gosumcheck -u http://localhost:8080 -k "localhost+..." go.sum

Common Errors

"error looking up ...": Module not in database

The module version isn't in the checksum database. This could mean:

  • Very new version not yet indexed
  • Private module (should be in GONOSUMDB)
  • Invalid module path or version

"hash mismatch": Checksum doesn't match

The checksum in go.sum doesn't match the database. This could indicate:

  • Corrupted go.sum file
  • Module content was modified
  • Database error (unlikely)

Action: Regenerate go.sum:

$ rm go.sum
$ go mod tidy

"invalid tree signature": Server key mismatch

The server's signature doesn't verify. This could mean:

  • Wrong server key specified with -k
  • Wrong server URL specified with -u
  • Server compromise (rare)

See Also

  • sumdb - Production-ready checksum database client
  • Go Checksum Database
  • Transparent Logs
  • go command documentation

Source Code

The gosumcheck source code is available in the golang.org/x/mod repository:

golang.org/x/mod/gosumcheck/main.go

Use it as a reference for understanding the checksum verification process, but implement your own production client using the sumdb package with proper caching and monitoring.