77 lines
1.5 KiB
Go
77 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
"golang.org/x/crypto/ssh/agent"
|
|
)
|
|
|
|
var (
|
|
fname = flag.String("fname", "var/thoth.md", "file to sign and validate")
|
|
|
|
trustedPubkeys = []string{
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPg9gYKVglnO2HQodSJt4z4mNrUSUiyJQ7b+J798bwD9",
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPYr9hiLtDHgd6lZDgQMkJzvYeAXmePOrgFaWHAjJvNU",
|
|
}
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
// ssh-agent(1) provides a UNIX socket at $SSH_AUTH_SOCK.
|
|
socket := os.Getenv("SSH_AUTH_SOCK")
|
|
conn, err := net.Dial("unix", socket)
|
|
if err != nil {
|
|
log.Fatalf("Failed to open SSH_AUTH_SOCK: %v", err)
|
|
}
|
|
|
|
agentClient := agent.NewClient(conn)
|
|
|
|
data, err := os.ReadFile(*fname)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
var sigs []*ssh.Signature
|
|
var pubkeys []ssh.PublicKey
|
|
for _, pkString := range trustedPubkeys {
|
|
pubkey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pkString))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
pubkeys = append(pubkeys, pubkey)
|
|
|
|
sig, err := agentClient.Sign(pubkey, data)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
sig.Rest = []byte(ssh.FingerprintSHA256(pubkey))
|
|
|
|
sigs = append(sigs, sig)
|
|
}
|
|
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.SetIndent("", " ")
|
|
enc.Encode(sigs)
|
|
os.Stdout.Sync()
|
|
|
|
for _, sig := range sigs {
|
|
for _, pubkey := range pubkeys {
|
|
if ssh.FingerprintSHA256(pubkey) != string(sig.Rest) {
|
|
continue
|
|
}
|
|
|
|
err := pubkey.Verify(data, sig)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|