diff --git a/plumbing/transport/ssh/auth_method.go b/plumbing/transport/ssh/auth_method.go index b79a74e41..568ec86ee 100644 --- a/plumbing/transport/ssh/auth_method.go +++ b/plumbing/transport/ssh/auth_method.go @@ -1,8 +1,6 @@ package ssh import ( - "crypto/x509" - "encoding/pem" "errors" "fmt" "io/ioutil" @@ -121,27 +119,15 @@ type PublicKeys struct { // NewPublicKeys returns a PublicKeys from a PEM encoded private key. An // encryption password should be given if the pemBytes contains a password // encrypted PEM block otherwise password should be empty. It supports RSA -// (PKCS#1), DSA (OpenSSL), and ECDSA private keys. +// (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys. func NewPublicKeys(user string, pemBytes []byte, password string) (*PublicKeys, error) { - block, _ := pem.Decode(pemBytes) - if block == nil { - return nil, errors.New("invalid PEM data") - } - if x509.IsEncryptedPEMBlock(block) { - key, err := x509.DecryptPEMBlock(block, []byte(password)) - if err != nil { - return nil, err - } - - block = &pem.Block{Type: block.Type, Bytes: key} - pemBytes = pem.EncodeToMemory(block) - } - signer, err := ssh.ParsePrivateKey(pemBytes) + if _, ok := err.(*ssh.PassphraseMissingError); ok { + signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password)) + } if err != nil { return nil, err } - return &PublicKeys{User: user, Signer: signer}, nil } diff --git a/plumbing/transport/ssh/auth_method_test.go b/plumbing/transport/ssh/auth_method_test.go index 2cbcded2d..ade344f76 100644 --- a/plumbing/transport/ssh/auth_method_test.go +++ b/plumbing/transport/ssh/auth_method_test.go @@ -145,6 +145,13 @@ func (*SuiteCommon) TestNewPublicKeysWithEncryptedPEM(c *C) { c.Assert(auth, NotNil) } +func (*SuiteCommon) TestNewPublicKeysWithEncryptedEd25519PEM(c *C) { + f := testdata.PEMEncryptedKeys[2] + auth, err := NewPublicKeys("foo", f.PEMBytes, f.EncryptionKey) + c.Assert(err, IsNil) + c.Assert(auth, NotNil) +} + func (*SuiteCommon) TestNewPublicKeysFromFile(c *C) { f, err := ioutil.TempFile("", "ssh-test") c.Assert(err, IsNil)