Files
TrollSSH/internal/sshserver/hostkeys.go
T

62 lines
1.3 KiB
Go
Raw Normal View History

2026-07-16 23:29:14 +07:00
package sshserver
2026-07-13 17:47:00 +07:00
import (
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"encoding/pem"
"fmt"
"os"
"path/filepath"
"golang.org/x/crypto/ssh"
)
func generateAndSave(keyPath, keyType string) error {
fmt.Printf("Generating %s host key...\n", keyType)
var key any
var err error
if keyType == "rsa" {
key, err = rsa.GenerateKey(rand.Reader, 4096)
} else {
_, key, err = ed25519.GenerateKey(rand.Reader)
}
if err != nil {
return err
}
block, err := ssh.MarshalPrivateKey(key, "")
if err != nil {
return err
}
return os.WriteFile(keyPath, pem.EncodeToMemory(block), 0o600)
}
2026-07-16 23:29:14 +07:00
func EnsureHostKeys(configDir string) ([]ssh.Signer, error) {
2026-07-13 17:47:00 +07:00
keys := []struct{ file, keyType string }{
{"id_rsa", "rsa"},
{"id_ed25519", "ed25519"},
}
signers := make([]ssh.Signer, 0, len(keys))
for _, k := range keys {
keyPath := filepath.Join(configDir, k.file)
if _, err := os.Stat(keyPath); os.IsNotExist(err) {
if err := generateAndSave(keyPath, k.keyType); err != nil {
return nil, fmt.Errorf("failed to generate %s host key: %w", k.keyType, err)
}
}
raw, err := os.ReadFile(keyPath)
if err != nil {
return nil, err
}
signer, err := ssh.ParsePrivateKey(raw)
if err != nil {
return nil, fmt.Errorf("failed to parse host key %q: %w", keyPath, err)
}
signers = append(signers, signer)
}
return signers, nil
}