Verify checksums and signatures¶
A self-updating tool downloads a binary and runs it. Verifying what it fetched is the difference between an update mechanism and a remote code execution mechanism.
This module supplies the retrieval half — getting the manifest and signature bytes from the forge. Verifying them is the consumer's job.
Two routes to the same bytes¶
Most releases ship a checksums.txt as an ordinary asset, so the default route
is to find it by name in the asset list. Nothing special is required.
Some sources cannot do that — the direct provider
composes a checksum URL from a template that may point outside any asset listing.
For those, a provider opts into ChecksumProvider:
if cp, ok := provider.(forge.ChecksumProvider); ok {
manifest, err := cp.DownloadChecksumManifest(ctx, rel, forge.DefaultMaxChecksumsSize)
switch {
case err == nil:
return manifest, nil
case errors.Is(err, forge.ErrNotSupported):
// opted out for this configuration — fall through
default:
return nil, err
}
}
// default route: locate checksums.txt among the release assets
SignatureProvider mirrors it exactly for a detached signature.
ErrNotSupported is not a failure
Treat "does not implement the interface" and "returned ErrNotSupported"
identically: fall back. Only a different error is fatal. Getting this wrong
turns a working provider into a broken one for every release where the
capability happens to be unconfigured.
Bound the read, always¶
Both methods take a maxBytes cap. Pass one:
These are defaults, not mandates — raise them if your tool genuinely ships larger artefacts. The provider enforces whatever you pass, because it is the only code that sees the response before it is buffered; a cap applied afterwards has already let the bytes into memory.
A manifest for a typical multi-OS release is around 1 KiB, so the default is roughly a thousandfold headroom while still stopping a hostile server streaming indefinitely.
Related¶
- Optional capabilities — why these are opt-in interfaces rather than required methods
- Use the direct provider