Files
keyfunc/internal/cli/ssh/ssh.go
clawbot 279cba6bcf
All checks were successful
check / check (push) Successful in 5s
Skeleton, mnemonic input, derivation, and the ssh pub and priv commands (closes #1)
The module, the script entrypoints and Makefile, Docker-only linting, the mnemonic sources in the specified order with their refusals, the BIP-85 derivation, and keyfunc ssh pub and priv with the README test vectors as tests. Two review rounds; the second passed with no findings.

Model: opus-5 (implementation and review); fable-5-1 (landing)
2026-09-07 17:34:54 +02:00

128 lines
2.6 KiB
Go

// Package ssh groups the commands that derive ed25519 SSH keys.
package ssh
import (
"fmt"
"git.eeqj.de/sneak/keyfunc/internal/cli/options"
"git.eeqj.de/sneak/keyfunc/internal/derive"
"git.eeqj.de/sneak/keyfunc/internal/sshkey"
"github.com/spf13/cobra"
)
// Command returns the ssh command and everything under it.
func Command() *cobra.Command {
group := &cobra.Command{
Use: "ssh",
Short: "derive ed25519 SSH keys",
}
group.AddCommand(public(), private())
return group
}
// public returns the command that prints the authorized_keys line.
func public() *cobra.Command {
cmd := &cobra.Command{
Use: "pub",
Short: "print the public key as an authorized_keys line",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
key, comment, err := derived(cmd)
if err != nil {
return err
}
line, err := key.Line(comment)
if err != nil {
return err
}
return write(cmd, line+"\n")
},
}
addComment(cmd)
return cmd
}
// private returns the command that prints the private key.
func private() *cobra.Command {
cmd := &cobra.Command{
Use: "priv",
Short: "print the unencrypted private key in OpenSSH format",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
key, comment, err := derived(cmd)
if err != nil {
return err
}
block, err := key.Block(comment)
if err != nil {
return err
}
return write(cmd, block)
},
}
addComment(cmd)
return cmd
}
// write sends the text to wherever the command's output goes.
func write(cmd *cobra.Command, text string) error {
_, err := fmt.Fprint(cmd.OutOrStdout(), text)
if err != nil {
return fmt.Errorf("writing the key: %w", err)
}
return nil
}
// addComment gives a command its comment flag.
func addComment(cmd *cobra.Command) {
cmd.Flags().String(
"comment", "",
"comment on the key; keyfunc/ssh/<index> when not given",
)
}
// derived returns the key for this run and the comment to put on it.
func derived(cmd *cobra.Command) (*sshkey.Key, string, error) {
index, err := options.Index(cmd)
if err != nil {
return nil, "", err
}
words, err := options.Mnemonic(cmd)
if err != nil {
return nil, "", err
}
material, err := derive.Bytes(words, sshkey.Application, index)
if err != nil {
return nil, "", err
}
key, err := sshkey.New(material)
if err != nil {
return nil, "", err
}
comment, err := cmd.Flags().GetString("comment")
if err != nil {
return nil, "", fmt.Errorf("reading the comment: %w", err)
}
if comment == "" {
comment = fmt.Sprintf("keyfunc/ssh/%d", index)
}
return key, comment, nil
}