Artifact 6469014c6f82559f377eea9b7756a2dd6a78a82c068a928649488b03563bfee9:
- File
ssh_dependency_test.go
— part of check-in
[a87790f468]
at
2026-10-26 12:45:46
on branch main
— feat(sshverify): make in-process SSH signature verification opt-in
internal/clearsign keeps the SSH envelope, SSHSIG parsing, namespace, hash and SHA-1 checks, none of which need cryptography, and hands the key parse and signature check to an SSHVerifier that the new public package sshverify registers from init. The library therefore no longer links golang.org/x/crypto/ssh and the ECDSA, P-256, Ed25519 and RSA code it pulls in; html-artifact-publisher's TinyGo engine drops from 1,347,569 to 1,093,647 bytes gzipped (3,777,936 to 3,208,411 raw).
Without the verifier nothing is accepted unchecked: a well-formed SSH signature is ErrSSHVerifierUnavailable, which wraps ErrCannotVerify, so a seed under an SSH horizon-seed-key is refused, the held one is kept, and the sync or rebuild fails naming the package to import. Malformed signatures are still bad. The cli package (and so cmd/libfossil) and examples/tinygo import sshverify; a go list guard keeps x/crypto/ssh out of the root and db closures. (user: [email protected], size: 1849) [annotate] [blame] [check-ins using]
package libfossil import ( "os" "os/exec" "slices" "strings" "testing" // The signing tests verify SSH signatures in process, which the // library links only for a program that imports sshverify. _ "github.com/danmestas/go-libfossil/sshverify" ) // sshImportPath is the in-process SSH signature code: x/crypto/ssh and the // ECDSA, Ed25519 and RSA implementations it links. const sshImportPath = "golang.org/x/crypto/ssh" // goListDeps returns the import paths of pkg's dependency closure, built for // goos/goarch, or for the host when goos is empty. func goListDeps(t *testing.T, goos, goarch, pkg string) []string { t.Helper() cmd := exec.Command("go", "list", "-deps", "-f={{.ImportPath}}", pkg) cmd.Env = os.Environ() if goos != "" { cmd.Env = append(cmd.Env, "GOOS="+goos, "GOARCH="+goarch) } out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("go list -deps %s: %v\n%s", pkg, err, out) } return strings.Fields(string(out)) } // TestSSHVerifyIsOptIn: the library and its db package link no SSH // cryptography, for the host or for js/wasm, so an embedder that never // verifies an SSH signature does not carry it; the sshverify package // links it, and the libfossil command, which verifies, imports it. func TestSSHVerifyIsOptIn(t *testing.T) { if testing.Short() { t.Skip("runs the go tool") } for _, target := range [][2]string{{"", ""}, {"js", "wasm"}} { for _, pkg := range []string{".", "./db"} { if slices.Contains(goListDeps(t, target[0], target[1], pkg), sshImportPath) { t.Errorf("%s (GOOS=%q) links %s; import sshverify to opt in instead", pkg, target[0], sshImportPath) } } } for _, pkg := range []string{"./sshverify", "./cmd/libfossil"} { if !slices.Contains(goListDeps(t, "", "", pkg), sshImportPath) { t.Errorf("%s does not link %s", pkg, sshImportPath) } } }