github.com/jerryclinesmith/packer@v0.3.7/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 if block == nil { 24 return errors.New("no block in key") 25 } 26 27 var rsakey interface{} 28 rsakey, err = x509.ParsePKCS1PrivateKey(block.Bytes) 29 if err != nil { 30 rsakey, err = x509.ParsePKCS8PrivateKey(block.Bytes) 31 } 32 33 if err != nil { 34 return 35 } 36 37 k.keys = append(k.keys, rsakey) 38 return 39 } 40 41 // AddPEMKeyPassword adds a PEM encoded private key that is protected by 42 // a password to the keychain. 43 func (k *SimpleKeychain) AddPEMKeyPassword(key string, password string) (err error) { 44 block, _ := pem.Decode([]byte(key)) 45 bytes, _ := x509.DecryptPEMBlock(block, []byte(password)) 46 rsakey, err := x509.ParsePKCS1PrivateKey(bytes) 47 if err != nil { 48 return 49 } 50 51 k.keys = append(k.keys, rsakey) 52 return 53 } 54 55 // Key method for ssh.ClientKeyring interface 56 func (k *SimpleKeychain) Key(i int) (interface{}, error) { 57 if i < 0 || i >= len(k.keys) { 58 return nil, nil 59 } 60 switch key := k.keys[i].(type) { 61 case *rsa.PrivateKey: 62 return &key.PublicKey, nil 63 case *dsa.PrivateKey: 64 return &key.PublicKey, nil 65 } 66 panic("unknown key type") 67 } 68 69 // Sign method for ssh.ClientKeyring interface 70 func (k *SimpleKeychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) { 71 hashFunc := crypto.SHA1 72 h := hashFunc.New() 73 h.Write(data) 74 digest := h.Sum(nil) 75 switch key := k.keys[i].(type) { 76 case *rsa.PrivateKey: 77 return rsa.SignPKCS1v15(rand, key, hashFunc, digest) 78 } 79 return nil, errors.New("ssh: unknown key type") 80 }