1
1
package ssh
2
2
3
3
import (
4
+ "crypto/x509"
5
+ "encoding/pem"
4
6
"errors"
5
7
"fmt"
6
8
"io/ioutil"
@@ -9,9 +11,11 @@ import (
9
11
"os/user"
10
12
"path/filepath"
11
13
12
- "github.com/src-d/crypto/ssh/knownhosts"
14
+ "gopkg.in/src-d/go-git.v4/plumbing/transport"
15
+
13
16
"golang.org/x/crypto/ssh"
14
17
"golang.org/x/crypto/ssh/agent"
18
+ "golang.org/x/crypto/ssh/knownhosts"
15
19
)
16
20
17
21
const DefaultUsername = "git"
@@ -22,6 +26,7 @@ var ErrEmptySSHAgentAddr = errors.New("SSH_AUTH_SOCK env variable is required")
22
26
// must implement. The clientConfig method returns the ssh client
23
27
// configuration needed to establish an ssh connection.
24
28
type AuthMethod interface {
29
+ transport.AuthMethod
25
30
clientConfig () * ssh.ClientConfig
26
31
hostKeyCallback () (ssh.HostKeyCallback , error )
27
32
}
@@ -112,9 +117,22 @@ type PublicKeys struct {
112
117
baseAuthMethod
113
118
}
114
119
115
- // NewPublicKeys returns a PublicKeys from a PEM encoded private key. It
116
- // supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
117
- func NewPublicKeys (user string , pemBytes []byte ) (AuthMethod , error ) {
120
+ // NewPublicKeys returns a PublicKeys from a PEM encoded private key. An
121
+ // encryption password should be given if the pemBytes contains a password
122
+ // encrypted PEM block otherwise password should be empty. It supports RSA
123
+ // (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
124
+ func NewPublicKeys (user string , pemBytes []byte , password string ) (AuthMethod , error ) {
125
+ block , _ := pem .Decode (pemBytes )
126
+ if x509 .IsEncryptedPEMBlock (block ) {
127
+ key , err := x509 .DecryptPEMBlock (block , []byte (password ))
128
+ if err != nil {
129
+ return nil , err
130
+ }
131
+
132
+ block = & pem.Block {Type : block .Type , Bytes : key }
133
+ pemBytes = pem .EncodeToMemory (block )
134
+ }
135
+
118
136
signer , err := ssh .ParsePrivateKey (pemBytes )
119
137
if err != nil {
120
138
return nil , err
@@ -124,14 +142,15 @@ func NewPublicKeys(user string, pemBytes []byte) (AuthMethod, error) {
124
142
}
125
143
126
144
// NewPublicKeysFromFile returns a PublicKeys from a file containing a PEM
127
- // encoded private key.
128
- func NewPublicKeysFromFile (user string , pemFile string ) (AuthMethod , error ) {
145
+ // encoded private key. An encryption password should be given if the pemBytes
146
+ // contains a password encrypted PEM block otherwise password should be empty.
147
+ func NewPublicKeysFromFile (user , pemFile , password string ) (AuthMethod , error ) {
129
148
bytes , err := ioutil .ReadFile (pemFile )
130
149
if err != nil {
131
150
return nil , err
132
151
}
133
152
134
- return NewPublicKeys (user , bytes )
153
+ return NewPublicKeys (user , bytes , password )
135
154
}
136
155
137
156
func (a * PublicKeys ) Name () string {
0 commit comments