Artifact af934c1d233d4b8579193923f60fc495baafd4a8a121cd8a81427634a11bd7bf:
- File
sshverify/sshverify.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: 1798) [annotate] [blame] [check-ins using] [more...]
// Package sshverify links in-process verification of SSH signatures into a // program that uses go-libfossil. Import it for its side effect: // // import _ "github.com/danmestas/go-libfossil/sshverify" // // Without it, the library links no SSH cryptography, and a signature it // would have to check against an SSH public key, such as a structural // horizon seed under an SSH libfossil.SettingHorizonSeedKey, is refused with // libfossil.ErrSSHVerifierUnavailable. Signing needs no import: it runs // ssh-keygen. PGP signatures are verified by gpg either way. package sshverify import ( "bytes" "errors" "fmt" "golang.org/x/crypto/ssh" "github.com/danmestas/go-libfossil/internal/clearsign" ) func init() { clearsign.RegisterSSHVerifier(verifier{}) } type verifier struct{} // CheckKey returns an error unless authorized is exactly one SSH public key. func (verifier) CheckKey(authorized string) error { _, err := parseKey(authorized) return err } // Verify checks sig against message under the key authorized names. func (verifier) Verify(authorized string, sig clearsign.SSHSignature, message []byte) error { want, err := parseKey(authorized) if err != nil { return err } if !bytes.Equal(sig.PublicKey, want.Marshal()) { return fmt.Errorf("%w: signed by another key", clearsign.ErrBadSignature) } s := &ssh.Signature{Format: sig.Format, Blob: sig.Blob, Rest: sig.Rest} if err := want.Verify(message, s); err != nil { return fmt.Errorf("%w: %v", clearsign.ErrBadSignature, err) } return nil } func parseKey(authorized string) (ssh.PublicKey, error) { key, _, _, rest, err := ssh.ParseAuthorizedKey([]byte(authorized)) if err != nil { return nil, err } if len(bytes.TrimSpace(rest)) != 0 { return nil, errors.New("more than one key") } return key, nil }