1
0
mirror of synced 2026-02-06 19:05:55 +00:00

Improve host key scanner, add Ed25519 generator

This commit is contained in:
Hidde Beydals
2020-06-09 01:11:46 +02:00
parent 3a8151bcc0
commit 6017946144
4 changed files with 111 additions and 60 deletions

View File

@@ -4,27 +4,20 @@ import (
"encoding/base64"
"fmt"
"net"
"time"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/knownhosts"
)
// ScanHostKey collects the given host's preferred public key for the
// algorithm of the given key pair. Any errors (e.g. authentication
// failures) are ignored, except if no key could be collected from the
// host.
func ScanHostKey(host string, user string, pair *KeyPair) ([]byte, error) {
signer, err := ssh.ParsePrivateKey(pair.PrivateKey)
if err != nil {
return nil, err
}
// Any errors (e.g. authentication failures) are ignored, except if
// no key could be collected from the host.
func ScanHostKey(host string, timeout time.Duration) ([]byte, error) {
col := &collector{}
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: col.StoreKey(),
HostKeyCallback: col.StoreKey(),
Timeout: timeout,
}
client, err := ssh.Dial("tcp", host, config)
if err == nil {
@@ -40,6 +33,10 @@ type collector struct {
knownKeys []byte
}
// StoreKey stores the public key in bytes as returned by the host.
// To collect multiple public key types from the host, multiple
// SSH dials need with the ClientConfig HostKeyAlgorithms set to
// the algorithm you want to collect.
func (c *collector) StoreKey() ssh.HostKeyCallback {
return func(hostname string, remote net.Addr, key ssh.PublicKey) error {
c.knownKeys = append(

View File

@@ -2,6 +2,7 @@ package ssh
import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
@@ -79,6 +80,31 @@ func (g *ECDSAGenerator) Generate() (*KeyPair, error) {
}, nil
}
type Ed25519Generator struct{}
func NewEd25519Generator() KeyPairGenerator {
return &Ed25519Generator{}
}
func (g *Ed25519Generator) Generate() (*KeyPair, error) {
pk, pv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
pub, err := generatePublicKey(pk)
if err != nil {
return nil, err
}
priv, err := encodePrivateKeyToPEM(pv)
if err != nil {
return nil, err
}
return &KeyPair{
PublicKey: pub,
PrivateKey: priv,
}, nil
}
func generatePublicKey(pk interface{}) ([]byte, error) {
b, err := ssh.NewPublicKey(pk)
if err != nil {