Merge pull request #1 from stephen-fox/parse-user-supplied-keypair
Parse user supplied keypair
This commit is contained in:
commit
b7719650ae
|
@ -36,7 +36,19 @@ func (s *StepSshKeyPair) Run(_ context.Context, state multistep.StateBag) multis
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
kp, err := ssh.NewKeyPairBuilder().
|
||||
SetPrivateKey(privateKeyBytes).
|
||||
SetName(fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())).
|
||||
Build()
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
s.Comm.SSHPrivateKey = privateKeyBytes
|
||||
s.Comm.SSHKeyPairName = kp.Name()
|
||||
s.Comm.SSHTemporaryKeyPairName = kp.Name()
|
||||
s.Comm.SSHPublicKey = kp.PublicKeyAuthorizedKeysLine(ssh.UnixNewLine)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package ssh
|
||||
|
||||
type defaultKeyPair struct {
|
||||
}
|
||||
|
||||
func (o defaultKeyPair) Type() KeyPairType {
|
||||
return Default
|
||||
}
|
||||
|
||||
func (o defaultKeyPair) Bits() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (o defaultKeyPair) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (o defaultKeyPair) Description() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (o defaultKeyPair) PrivateKeyPemBlock() []byte {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func (o defaultKeyPair) PublicKeyAuthorizedKeysLine(nl NewLineOption) []byte {
|
||||
return []byte{}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package ssh
|
||||
|
||||
import (
|
||||
"crypto/dsa"
|
||||
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type dsaKeyPair struct {
|
||||
privateKey *dsa.PrivateKey
|
||||
publicKey gossh.PublicKey
|
||||
name string
|
||||
privatePemBlock []byte
|
||||
}
|
||||
|
||||
func (o dsaKeyPair) Type() KeyPairType {
|
||||
return Dsa
|
||||
}
|
||||
|
||||
func (o dsaKeyPair) Bits() int {
|
||||
return 1024
|
||||
}
|
||||
|
||||
func (o dsaKeyPair) Name() string {
|
||||
return o.name
|
||||
}
|
||||
|
||||
func (o dsaKeyPair) Description() string {
|
||||
return description(o)
|
||||
}
|
||||
|
||||
func (o dsaKeyPair) PrivateKeyPemBlock() []byte {
|
||||
return o.privatePemBlock
|
||||
}
|
||||
|
||||
func (o dsaKeyPair) PublicKeyAuthorizedKeysLine(nl NewLineOption) []byte {
|
||||
return publicKeyAuthorizedKeysLine(o.publicKey, o.name, nl)
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package ssh
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/ed25519"
|
||||
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type ed25519KeyPair struct {
|
||||
privateKey *ed25519.PrivateKey
|
||||
publicKey gossh.PublicKey
|
||||
name string
|
||||
privatePemBlock []byte
|
||||
}
|
||||
|
||||
func (o ed25519KeyPair) Type() KeyPairType {
|
||||
return Ed25519
|
||||
}
|
||||
|
||||
func (o ed25519KeyPair) Bits() int {
|
||||
return 256
|
||||
}
|
||||
|
||||
func (o ed25519KeyPair) Name() string {
|
||||
return o.name
|
||||
}
|
||||
|
||||
func (o ed25519KeyPair) Description() string {
|
||||
return description(o)
|
||||
}
|
||||
|
||||
func (o ed25519KeyPair) PrivateKeyPemBlock() []byte {
|
||||
return o.privatePemBlock
|
||||
}
|
||||
|
||||
func (o ed25519KeyPair) PublicKeyAuthorizedKeysLine(nl NewLineOption) []byte {
|
||||
return publicKeyAuthorizedKeysLine(o.publicKey, o.name, nl)
|
||||
}
|
|
@ -2,6 +2,7 @@ package ssh
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
|
@ -9,9 +10,11 @@ import (
|
|||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
|
@ -19,11 +22,12 @@ const (
|
|||
// That's a lot of bits.
|
||||
defaultRsaBits = 4096
|
||||
|
||||
// Rsa is a SSH key pair of RSA type.
|
||||
Rsa KeyPairType = "RSA"
|
||||
|
||||
// Ecdsa is a SSH key pair of ECDSA type.
|
||||
Ecdsa KeyPairType = "ECDSA"
|
||||
// Markers for various SSH key pair types.
|
||||
Default KeyPairType = ""
|
||||
Rsa KeyPairType = "RSA"
|
||||
Ecdsa KeyPairType = "ECDSA"
|
||||
Dsa KeyPairType = "DSA"
|
||||
Ed25519 KeyPairType = "ED25519"
|
||||
)
|
||||
|
||||
// KeyPairType represents different types of SSH key pairs.
|
||||
|
@ -58,6 +62,9 @@ func (o NewLineOption) Bytes() []byte {
|
|||
}
|
||||
|
||||
// KeyPairBuilder builds SSH key pairs.
|
||||
// It can generate new keys of type RSA and ECDSA.
|
||||
// It can parse user supplied keys of type DSA, RSA, ECDSA,
|
||||
// and ED25519.
|
||||
type KeyPairBuilder interface {
|
||||
// SetType sets the key pair type.
|
||||
SetType(KeyPairType) KeyPairBuilder
|
||||
|
@ -65,10 +72,15 @@ type KeyPairBuilder interface {
|
|||
// SetBits sets the key pair's bits of entropy.
|
||||
SetBits(int) KeyPairBuilder
|
||||
|
||||
// SetName sets the name of the key pair. This is primarily used
|
||||
// to identify the public key in the authorized_keys file.
|
||||
// SetName sets the name of the key pair. This is primarily
|
||||
// used to identify the public key in the authorized_keys file.
|
||||
SetName(string) KeyPairBuilder
|
||||
|
||||
// SetPrivateKey takes an existing private key in PEM format.
|
||||
// It overrides key generation details specified by SetType()
|
||||
// and SetBits().
|
||||
SetPrivateKey([]byte) KeyPairBuilder
|
||||
|
||||
// Build returns a SSH key pair.
|
||||
//
|
||||
// The following defaults are used if not specified:
|
||||
|
@ -89,6 +101,10 @@ type defaultKeyPairBuilder struct {
|
|||
|
||||
// name is the resulting key pair's name.
|
||||
name string
|
||||
|
||||
// privatePemBytes is the supplied key data when the builder
|
||||
// is working from a preallocated key.
|
||||
privatePemBytes []byte
|
||||
}
|
||||
|
||||
func (o *defaultKeyPairBuilder) SetType(kind KeyPairType) KeyPairBuilder {
|
||||
|
@ -106,15 +122,82 @@ func (o *defaultKeyPairBuilder) SetName(name string) KeyPairBuilder {
|
|||
return o
|
||||
}
|
||||
|
||||
func (o *defaultKeyPairBuilder) SetPrivateKey(privateBytes []byte) KeyPairBuilder {
|
||||
o.privatePemBytes = privateBytes
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *defaultKeyPairBuilder) Build() (KeyPair, error) {
|
||||
if o.privatePemBytes != nil {
|
||||
return o.preallocatedKeyPair()
|
||||
}
|
||||
|
||||
switch o.kind {
|
||||
case Rsa:
|
||||
return o.newRsaKeyPair()
|
||||
case Ecdsa:
|
||||
// Default case.
|
||||
case Ecdsa, Default:
|
||||
return o.newEcdsaKeyPair()
|
||||
}
|
||||
|
||||
return o.newEcdsaKeyPair()
|
||||
return defaultKeyPair{}, fmt.Errorf("Unsupported keypair type: %s", o.kind.String())
|
||||
}
|
||||
|
||||
// preallocatedKeyPair returns an SSH key pair based on user
|
||||
// supplied PEM data.
|
||||
func (o *defaultKeyPairBuilder) preallocatedKeyPair() (KeyPair, error) {
|
||||
privateKey, err := gossh.ParseRawPrivateKey(o.privatePemBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch pk := privateKey.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
publicKey, err := gossh.NewPublicKey(&pk.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rsaKeyPair{
|
||||
privateKey: pk,
|
||||
publicKey: publicKey,
|
||||
name: o.name,
|
||||
privatePemBlock: o.privatePemBytes,
|
||||
}, nil
|
||||
case *ecdsa.PrivateKey:
|
||||
publicKey, err := gossh.NewPublicKey(&pk.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ecdsaKeyPair{
|
||||
privateKey: pk,
|
||||
publicKey: publicKey,
|
||||
name: o.name,
|
||||
privatePemBlock: o.privatePemBytes,
|
||||
}, nil
|
||||
case *dsa.PrivateKey:
|
||||
publicKey, err := gossh.NewPublicKey(&pk.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dsaKeyPair{
|
||||
privateKey: pk,
|
||||
publicKey: publicKey,
|
||||
name: o.name,
|
||||
privatePemBlock: o.privatePemBytes,
|
||||
}, nil
|
||||
case *ed25519.PrivateKey:
|
||||
publicKey, err := gossh.NewPublicKey(pk.Public())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ed25519KeyPair{
|
||||
privateKey: pk,
|
||||
publicKey: publicKey,
|
||||
name: o.name,
|
||||
privatePemBlock: o.privatePemBytes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &defaultKeyPair{}, fmt.Errorf("Unknown ssh key pair type")
|
||||
}
|
||||
|
||||
// newEcdsaKeyPair returns a new ECDSA SSH key pair.
|
||||
|
|
|
@ -20,6 +20,137 @@ type expected struct {
|
|||
data []byte
|
||||
}
|
||||
|
||||
const (
|
||||
pemRsa1024 = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQDJEMFPpTBiWNDb3qEIPTSeEnIP8FZdBpG8njOrclcMoQQNhzZ+
|
||||
4uz37tqtHMp36Z7LB4/+85NN6epNXO+ekyZIHswiyBcJC2sT3KuH7nG1BESOooPY
|
||||
DfeCSM+CJT9GDIhy9nUXSsJjrceEyh/B5DjEtIbS0XfcRelrNTJodCmPJwIDAQAB
|
||||
AoGAK66GMOV0c4lUJtBhL8cMTWM4gJn4SVGKC+5az16R5t58YOwFPN/UF7E+tOlS
|
||||
W2bX5sgH0p3cXMr66j/Mlyjk4deLg7trDavulIP93MyVO2SUJ0cstQ0ZmRz2oGwx
|
||||
Gow+hD75Cet7uvepdmG4DKHJe8D/I72rtP1WKuZyd0vP6WECQQDua6wWlyEdIimx
|
||||
XoGWUvmywACWPnQmBnyHG7x5hxMjijQoQZu60zRxSU9I5q08BerTsvbTc+xLnDVv
|
||||
mFzlcjT/AkEA1+P7lcvViZeNKoDB1Qt+VV+pkcqL5aoRwdnLA51SyFJ9tXkxeZwA
|
||||
LOof3xtoRGhCld7ixi3kF5aZsafAJOZd2QJAH8rFyMFgTgU3MAqdFxF7cGV/7ojn
|
||||
bgahZlbBfCcR20Rbjh6piHEPZifTZbI02XMkjBQqK6oikTaEPZxAjuv6uwJANczu
|
||||
yWm+kUdfOpRTuY/fr87jJx3etyEmw7ROz1vJYXqNMUg+eBvUP10pDCR8W2/QCCE/
|
||||
Sjvtd6NkMc2oKInwIQJAFZ1xJte0EaQsXaCIoZwHrQJbK1dd5l1xTAzz51voAcKH
|
||||
2K23xgx4I+/eam2enjFa7wXLZFoW0xg/51xsaIjnrA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
||||
pemRsa2048 = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA/ZPazeRmBapF01gzHXtJGpu0S936xHY+pOrIyIk6lEE06paf
|
||||
q5gh6BCuiN/60Keed5Nz+Es4dPGc73mql9pd7N0HOoEc1IQjZzJVqWOy3E55oWbz
|
||||
rXr1qbmMjw8bGHalZsVBov1UhyB6f2bKi88fGkThJi9HZ+Dc3Jr87eW+whS4D0bI
|
||||
JJe5dkY0VhDqB0YVEk299TxlAiDkeXD1EcMZrD/yHsusapwlXL2WHWmCgbPpbeYW
|
||||
YJhD1bScChYmf41iiInBwFymG7kz4bPsup7wCBXpcLJplY1iuXdtVVujNLDbJwlb
|
||||
Xi2oBm3WizPjYcUthvMlqOieuy6Z4KzyJd7EnQIDAQABAoIBAByZ8LQIbvl0myub
|
||||
ZyiMH1LA/TURdJd0PtybHsp/r/vI3w8WrivMnQZv2z/VA5VFUrpqB0qaMWP/XJQm
|
||||
RPebybxNseMHbRkLTnL1WnQgqqvurglmc1W96LecFh6MtaGswDs3RI/9wur63tY/
|
||||
4dijI/7yhfKoooU097RqRt0ObNW3BxGwNKUraMLKEZjtohv1cZBeRqzGZuui351E
|
||||
YsG1jt23/3OP3Acfd1xpzoi+daadxl9JTr02kE7lMjfq32quhTdzuNZP84sQsaV+
|
||||
RXLNEoiSufjzy3nHTEpG6QaEWQc4gszCIBVRabxr7LtIOqJn2KmXxtOyFE52AJJj
|
||||
ls3ifAECgYEA/9K+5oHdZBizWWUvNzQWXrdHUtVavCwjj+0v+yRFZSoAhKtVmLYl
|
||||
8R4NeG6NCIOoJsqmGVpgtCyPndR4PQ6yr4Jt1FJorjsNw21eYrjOVG+y9Z0DkCwJ
|
||||
uCRVUeqB42jLu7v9r1V3OBQdKLN6VxO4np05KEZyv1LOGGt0XC8NCykCgYEA/cC2
|
||||
NR7Y4Z5OjCc2GHMQNrVZ2HTDDir71RjcIIEmsIQ5/AMAELFLCSqzD73tJ87T5jPi
|
||||
aWeOpIcnK78jMvIIsbV0BXaDsjtlvCdQui2AoX63FuK4q4E+vwe5Q/TqY2nDh2io
|
||||
mGHfeXECyUx4gxIede2XEO9zYQ0lP8gxnjmLkFUCgYBO8LolqQcm/xRAzp9eOn14
|
||||
prekkN+Z10j1/avjpFKhn+9fAPu9zt8wYySm9/4fFXlK1xegFSpoDqQWgNzFgoaS
|
||||
7/1yGifhM6nQlywb7IkGtx0S+2uBDoXFQ7jsOR/xi4HqoVzrwMS0EkjZKWDkA9rh
|
||||
XwSnL+3yqduc33OdiotM2QKBgCgNCrVHsSOrQOqOJdOmFaEM7qljhIXv8t+nlNbs
|
||||
i5bAyAYm0xPPZ/CCdNC/QXdPBdMHzWylk7YUPvKAsKWR3h1ubmmOUysGhQA1lGBO
|
||||
XkcfIPbTwiIPvD+akHtRZM1cHCh7NGEY0ZTxaWcsUrkdWwFyBq39nVBsKrzudCZt
|
||||
HsIhAoGBAMv3erZQawzIgX9nOUHB2UJl8pS+LZSNMlYvFoMHKI2hLq0g/VxUlnsh
|
||||
Jzw9+fTLMVFdY+F3ydO6qQFd8wlfov7deyscdoSj8R5gjGKJsarBs+YVdFde2oLG
|
||||
gkFsXmbmc2boyqGg51CbAX34VJOhGQKhWgKCWqDGmoYXafmyiZc+
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
||||
pemOpenSshRsa1024 = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAIEAzzknaHV741775aJOPacDpd2SiDpIDYmm7/w2sgY8lrinSakfLIVk
|
||||
1qn0IBRLNOzMxoF/pvIgGQXS51xvE1vB3QK8L+8vJwH06DuOXPP1WgVoDTU03gGvBJ7MNF
|
||||
5HcQYvBiIaU5XxG8l0OZO88B9RFhPP9r0XrYxAlSjuk9KKlEcAAAIYLQ46zy0OOs8AAAAH
|
||||
c3NoLXJzYQAAAIEAzzknaHV741775aJOPacDpd2SiDpIDYmm7/w2sgY8lrinSakfLIVk1q
|
||||
n0IBRLNOzMxoF/pvIgGQXS51xvE1vB3QK8L+8vJwH06DuOXPP1WgVoDTU03gGvBJ7MNF5H
|
||||
cQYvBiIaU5XxG8l0OZO88B9RFhPP9r0XrYxAlSjuk9KKlEcAAAADAQABAAAAgQDJ9Jq6jF
|
||||
08P/LhXug/38iHW0UW7S4Ru4jttHGd2MQt5DJtcJzIKA0ZxLL+nKibIPmFsOm2y5yKpolg
|
||||
IE7EoBVzTeg0LedbRayc0Kc5tY7PEz0Shi9ABIMYbNo2L2pNmsq9ns0xA8ur3OugfKHsH8
|
||||
XjJ1rdHsyLjoMx2ADfLY0xkQAAAEAvyrgW4jswENdErbF0rOdP+Y73B/8rxBaY/QBE2qtG
|
||||
oUp7bpOtUAH2Ip7RjXOX4xTAt4n2QeHBSfX7gfXRjmY6AAAAQQDmYlgSWtTYLV9VZSScLU
|
||||
OG+GkhQxYqkKN/N9LSpTP4Pwh81KpMp40yvIlufmKLgGihWVxUDzRap3aoR7PqIvHPAAAA
|
||||
QQDmQ47VwclxiVn5tVAht/Lk2ZVa7rSjeFlXAkAWZkUAiHboaH8IfW9W4gYV7o2BqJO11L
|
||||
0vi+vCq+le45F416wJAAAAImNocmlzQHBvZXRhc3Rlci5jb3JwLm11dHVhbGluay5uZXQ=
|
||||
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
`
|
||||
pemOpenSshRsa2048 = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAQEAxWfWNu0i8sbmwPqTUfKSeXOSt/fLMuqucn9KYU7rJ+83trznRhAn
|
||||
AHQzKgcSU8PBgkax+PDEUexYUB9gZApNI6K/2twVDYh3Hgwx7EjXf05rji7bQk6TFyKEp4
|
||||
n348CWAdK8iFmNUutSpJLy7GciyMPLu3BK+EsXpsnuPpIm184hEFOiADZyHTGeUgvsKOAc
|
||||
G7u5hBS3kty8LRZmL+pihbktFwGC4D5bapCcTaF2++zkUy4JKcVE5/2JfK1Ya6D0ATczjz
|
||||
1b6+r7j2RUg1mXfK6AwMHEcamzhgeuM9RdrPtMdhZI09LCJzjmXc9pzlGu1HCZzh3rJ3hd
|
||||
8PVmlAd3VQAAA+A9hesQPYXrEAAAAAdzc2gtcnNhAAABAQDFZ9Y27SLyxubA+pNR8pJ5c5
|
||||
K398sy6q5yf0phTusn7ze2vOdGECcAdDMqBxJTw8GCRrH48MRR7FhQH2BkCk0jor/a3BUN
|
||||
iHceDDHsSNd/TmuOLttCTpMXIoSniffjwJYB0ryIWY1S61KkkvLsZyLIw8u7cEr4Sxemye
|
||||
4+kibXziEQU6IANnIdMZ5SC+wo4Bwbu7mEFLeS3LwtFmYv6mKFuS0XAYLgPltqkJxNoXb7
|
||||
7ORTLgkpxUTn/Yl8rVhroPQBNzOPPVvr6vuPZFSDWZd8roDAwcRxqbOGB64z1F2s+0x2Fk
|
||||
jT0sInOOZdz2nOUa7UcJnOHesneF3w9WaUB3dVAAAAAwEAAQAAAQEAvA8Z8iWjX6nA9yM/
|
||||
6ZevluhVY9E60XzlR8qgL2ehet/YMcxwfzywCyyn+WfXO9mHpfZ3YfLs9Ca2U04w4900c7
|
||||
h+EaAMpmHVKNjxTmpucadhq4hT9S0pz6ZgvcMgVuaHgaEjXroBencYuhQMPM5cQurUUfK+
|
||||
WSAgnhJNV2qgeoEGgfDZoL1HkItckEZwIzmx4lfMVAuaeqVq5tJNcdv5ukNHpnIYl6fgDp
|
||||
WGUn/9F8sSHO7P7kGl67IZIsAz+1wW+6pFaVgxbZJ3baPiURtRp+nRSaKLYZSMph6MAiTu
|
||||
YC8EEVqi3X4m/ZHy+BkphfzR24ouwpt1Vv9QOAPzXXsPwQAAAIEAvmA+yiBdzsJplCifTA
|
||||
KljE+KpSuvLPRPTb7MGsBO0LIvxrkXOMCXZF4I2VP1zSUH+SDPPc6JeR1Q8liMqPC3Md6c
|
||||
CIkHfVFBAZL709d0ZtTiir1BipG/l5vIpBnepNX/bWIszIOMzPF2at0WF1lFe6THWujuE8
|
||||
Xjp2AJSFZlUjAAAACBAOMxr6FN38VwRC1nrDcZyo4TjWVhAdk4p3AkdNJhFSiKS/x5/yo2
|
||||
K1majzcKbrR8+fEPTVWGszAg+AXQdsOq17q+DMenfrBckQ9ZHr3upSZAaGN+keNwge/Kaj
|
||||
yOvYiKdYFXmAulQZCPQsDNp7e7Z1dTqxi5IlhUgDPzzO0vRGjNAAAAgQDeb0Ulv7fkYAav
|
||||
tZ+D0LohGjlGFwTeLdwErcVnq9wGyupdeNhlTXZXxRvF+yEt4FCV9UEUnRX75CAnpk2hT2
|
||||
D5uYMyixAEfSeIo59Ln27MmAy0alR3UnT7JnLEZRh4dnvFbSSMJ1rHxf8Eg6YFJmpH65fX
|
||||
exrJE+p69wgRVndoqQAAACJjaHJpc0Bwb2V0YXN0ZXIuY29ycC5tdXR1YWxpbmsubmV0AQ
|
||||
IDBAUGBw==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
`
|
||||
pemDsa = `-----BEGIN DSA PRIVATE KEY-----
|
||||
MIIBuwIBAAKBgQDH/T+IkpbdA9nUM7O4MMRoeS0bn7iXWs63Amo2fsIyJPxDvjjF
|
||||
5HZBH5Rq045TFCCWHjymwiYof+wvwUMZIUH++ABTrKzes/r5qG5jXp42pFWf6nTI
|
||||
zHwttdjvNiXr+AgreXOrJKhjv6Ga3hq8MNcXMa9xFsIB83EZNMBPxbj0nwIVAJQW
|
||||
1eR4Uf8/8haQb4HkTsoH+R5/AoGBAK9FV5LIZxY1TeNsD5eXoqpTqCy1WROMggSG
|
||||
VZ4yN0rrKCtLd8am61m/L8VCMUWiO3IJQdq3yWBTEBbsShL/toau9beUdTl6rdB8
|
||||
wcEcNgtZnhypQR58HlmgUFWC45rW37hW4AUJuMDgLxgqSVuoF1pDcHrHSi/fZwgp
|
||||
7t0MKH2SAoGAJfUcLrXg5ZR8jbpZs4L/ubibUn+y35y+33aos07auMW1MesuNTcZ
|
||||
Ch42nbH2wKnbjk8eDxHdHLHzzOLGgYVMpUuBeuc7G5Q94rM/Z0I8HGQ6mvIkuFyp
|
||||
58Unu5yu33GsNUgGEHmriiMGezXNXGNH/72PmTXuyxEMSrad23c6NZoCFAtIqbal
|
||||
4tGCfnnmWU514A7ZzEKj
|
||||
-----END DSA PRIVATE KEY-----
|
||||
`
|
||||
pemEcdsa384 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAjuEIlmFyhGjFtJoAwD420FuPAjIknN3YwDZL4cfMFpB4YAK+7QVLs
|
||||
coAJ/ADuT7OgBwYFK4EEACKhZANiAASeXKyBr2prr4f4aOsM4dtVikYOUIL3yYnb
|
||||
GFOy7yHmauCnkIB48paXpvRE5m53Q8zgu7vkz/z9tcMBcC0GzpY3Sef37fmgTUuZ
|
||||
AJuJp36DMBdQel+j51TcQ79sizxCayg=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
pemEcdsa521 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIHcAgEBBEIBVCiwcf/did2vCIu3aMe7OeTD35PULm0hqmfkAK9OKIosi/DjOFfA
|
||||
8h99rVNPaf+Cx/JNmEzR4bZNnYDyilSRCr+gBwYFK4EEACOhgYkDgYYABABHBMLP
|
||||
XbQoRF31ZGIeUj9jt9GqKES1dLBtGDEQSiiZFouL4tEIW7NfIZDpOIkA0khNcO8N
|
||||
xH6eylg0XOgcr01GRwCjY5VOapOahtn63SpajPGeKk+46F2dULIwrov9tWQuYNa3
|
||||
P50N8j3rx6fAdgyDENOcCJlfNdNcySvkH4bgL1xcsw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
pemOpenSshEd25519 = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACAUftPhZQN17kAlThiiWJEgJvddm/pUhHvgrHUtpuYFOQAAAKjN+UhDzflI
|
||||
QwAAAAtzc2gtZWQyNTUxOQAAACAUftPhZQN17kAlThiiWJEgJvddm/pUhHvgrHUtpuYFOQ
|
||||
AAAEANXlEZdNU03RMmj77O2ojWh06Hbj8/qQ++H5wkt688NBR+0+FlA3XuQCVOGKJYkSAm
|
||||
912b+lSEe+CsdS2m5gU5AAAAImNocmlzQHBvZXRhc3Rlci5jb3JwLm11dHVhbGluay5uZX
|
||||
QBAgM=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
`
|
||||
)
|
||||
|
||||
func (o expected) matches(kp KeyPair) error {
|
||||
if o.kind.String() == "" {
|
||||
return errors.New("expected kind's value cannot be empty")
|
||||
|
@ -86,18 +217,18 @@ func (o expected) verifyPublicKeyAuthorizedKeysFormat(kp KeyPair) error {
|
|||
|
||||
switch nl {
|
||||
case NoNewLine:
|
||||
if publicKeyAk[len(publicKeyAk) - 1] == '\n' {
|
||||
if publicKeyAk[len(publicKeyAk)-1] == '\n' {
|
||||
return errors.New("public key in authorized keys format has trailing new line when none was specified")
|
||||
}
|
||||
case UnixNewLine:
|
||||
if publicKeyAk[len(publicKeyAk) - 1] != '\n' {
|
||||
if publicKeyAk[len(publicKeyAk)-1] != '\n' {
|
||||
return errors.New("public key in authorized keys format does not have unix new line when unix was specified")
|
||||
}
|
||||
if string(publicKeyAk[len(publicKeyAk) - 2:]) == WindowsNewLine.String() {
|
||||
if string(publicKeyAk[len(publicKeyAk)-2:]) == WindowsNewLine.String() {
|
||||
return errors.New("public key in authorized keys format has windows new line when unix was specified")
|
||||
}
|
||||
case WindowsNewLine:
|
||||
if string(publicKeyAk[len(publicKeyAk) - 2:]) != WindowsNewLine.String() {
|
||||
if string(publicKeyAk[len(publicKeyAk)-2:]) != WindowsNewLine.String() {
|
||||
return errors.New("public key in authorized keys format does not have windows new line when windows was specified")
|
||||
}
|
||||
}
|
||||
|
@ -267,3 +398,154 @@ func TestDefaultKeyPairBuilder_Build_NamedRsa(t *testing.T) {
|
|||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultKeyPairBuilder_SetPrivateKey(t *testing.T) {
|
||||
name := uuid.TimeOrderedUUID()
|
||||
pemData := make(map[string]expected)
|
||||
pemData[pemRsa1024] = expected{
|
||||
bits: 1024,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "1024 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemRsa2048] = expected{
|
||||
bits: 2048,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "2048 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemOpenSshRsa1024] = expected{
|
||||
bits: 1024,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "1024 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemOpenSshRsa2048] = expected{
|
||||
bits: 2048,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "2048 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemDsa] = expected{
|
||||
bits: 1024,
|
||||
kind: Dsa,
|
||||
name: name,
|
||||
desc: "1024 bit DSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemEcdsa384] = expected{
|
||||
bits: 384,
|
||||
kind: Ecdsa,
|
||||
name: name,
|
||||
desc: "384 bit ECDSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemEcdsa521] = expected{
|
||||
bits: 521,
|
||||
kind: Ecdsa,
|
||||
name: name,
|
||||
desc: "521 bit ECDSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemOpenSshEd25519] = expected{
|
||||
bits: 256,
|
||||
kind: Ed25519,
|
||||
name: name,
|
||||
desc: "256 bit ED25519 named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
|
||||
for s, l := range pemData {
|
||||
kp, err := NewKeyPairBuilder().SetPrivateKey([]byte(s)).SetName(name).Build()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = l.matches(kp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultKeyPairBuilder_SetPrivateKey_Override(t *testing.T) {
|
||||
name := uuid.TimeOrderedUUID()
|
||||
pemData := make(map[string]expected)
|
||||
pemData[pemRsa1024] = expected{
|
||||
bits: 1024,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "1024 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemRsa2048] = expected{
|
||||
bits: 2048,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "2048 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemOpenSshRsa1024] = expected{
|
||||
bits: 1024,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "1024 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemOpenSshRsa2048] = expected{
|
||||
bits: 2048,
|
||||
kind: Rsa,
|
||||
name: name,
|
||||
desc: "2048 bit RSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemDsa] = expected{
|
||||
bits: 1024,
|
||||
kind: Dsa,
|
||||
name: name,
|
||||
desc: "1024 bit DSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemEcdsa384] = expected{
|
||||
bits: 384,
|
||||
kind: Ecdsa,
|
||||
name: name,
|
||||
desc: "384 bit ECDSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemEcdsa521] = expected{
|
||||
bits: 521,
|
||||
kind: Ecdsa,
|
||||
name: name,
|
||||
desc: "521 bit ECDSA named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
pemData[pemOpenSshEd25519] = expected{
|
||||
bits: 256,
|
||||
kind: Ed25519,
|
||||
name: name,
|
||||
desc: "256 bit ED25519 named " + name,
|
||||
data: []byte(uuid.TimeOrderedUUID()),
|
||||
}
|
||||
|
||||
supportedKeyTypes := []KeyPairType{Rsa, Dsa}
|
||||
for _, keyType := range supportedKeyTypes {
|
||||
for pemString, expectedResult := range pemData {
|
||||
kp, err := NewKeyPairBuilder().
|
||||
SetPrivateKey([]byte(pemString)).
|
||||
SetName(name).
|
||||
SetType(keyType).
|
||||
Build()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = expectedResult.matches(kp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue