mirror of
https://github.com/YuzuZensai/TrollSSH.git
synced 2026-09-13 15:09:01 +00:00
62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
package sshserver
|
|
|
|
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)
|
|
}
|
|
|
|
func EnsureHostKeys(configDir string) ([]ssh.Signer, error) {
|
|
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
|
|
}
|