github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/communicator/ssh/keychain.go (about) 1 package ssh 2 3 import ( 4 "crypto" 5 "crypto/dsa" 6 "crypto/rsa" 7 "crypto/x509" 8 "encoding/pem" 9 "errors" 10 "io" 11 ) 12 13 // SimpleKeychain makes it easy to use private keys in order to connect 14 // via SSH, since the interface exposed by Go isn't the easiest to use 15 // right away. 16 type SimpleKeychain struct { 17 keys []interface{} 18 } 19 20 // AddPEMKey adds a simple PEM encoded private key to the keychain. 21 func (k *SimpleKeychain) AddPEMKey(key string) (err error) { 22 block, _ := pem.Decode([]byte(key)) 23 rsakey, err := x509.ParsePKCS1PrivateKey(block.Bytes) 24 if err != nil { 25 return 26 } 27 28 k.keys = append(k.keys, rsakey) 29 return 30 } 31 32 // AddPEMKeyPassword adds a PEM encoded private key that is protected by 33 // a password to the keychain. 34 func (k *SimpleKeychain) AddPEMKeyPassword(key string, password string) (err error) { 35 block, _ := pem.Decode([]byte(key)) 36 bytes, _ := x509.DecryptPEMBlock(block, []byte(password)) 37 rsakey, err := x509.ParsePKCS1PrivateKey(bytes) 38 if err != nil { 39 return 40 } 41 42 k.keys = append(k.keys, rsakey) 43 return 44 } 45 46 // Key method for ssh.ClientKeyring interface 47 func (k *SimpleKeychain) Key(i int) (interface{}, error) { 48 if i < 0 || i >= len(k.keys) { 49 return nil, nil 50 } 51 switch key := k.keys[i].(type) { 52 case *rsa.PrivateKey: 53 return &key.PublicKey, nil 54 case *dsa.PrivateKey: 55 return &key.PublicKey, nil 56 } 57 panic("unknown key type") 58 } 59 60 // Sign method for ssh.ClientKeyring interface 61 func (k *SimpleKeychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) { 62 hashFunc := crypto.SHA1 63 h := hashFunc.New() 64 h.Write(data) 65 digest := h.Sum(nil) 66 switch key := k.keys[i].(type) { 67 case *rsa.PrivateKey: 68 return rsa.SignPKCS1v15(rand, key, hashFunc, digest) 69 } 70 return nil, errors.New("ssh: unknown key type") 71 }