github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/utils/ssh/generate.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ssh 5 6 import ( 7 "crypto/rand" 8 "crypto/rsa" 9 "crypto/x509" 10 "encoding/pem" 11 "fmt" 12 "strings" 13 14 "code.google.com/p/go.crypto/ssh" 15 "github.com/juju/errors" 16 ) 17 18 // rsaGenerateKey allows for tests to patch out rsa key generation 19 var rsaGenerateKey = rsa.GenerateKey 20 21 // KeyBits is used to determine the number of bits to use for the RSA keys 22 // created using the GenerateKey function. 23 var KeyBits = 2048 24 25 // GenerateKey makes a 2048 bit RSA no-passphrase SSH capable key. The bit 26 // size is actually controlled by the KeyBits var. The private key returned is 27 // encoded to ASCII using the PKCS1 encoding. The public key is suitable to 28 // be added into an authorized_keys file, and has the comment passed in as the 29 // comment part of the key. 30 func GenerateKey(comment string) (private, public string, err error) { 31 key, err := rsaGenerateKey(rand.Reader, KeyBits) 32 if err != nil { 33 return "", "", errors.Trace(err) 34 } 35 36 identity := pem.EncodeToMemory( 37 &pem.Block{ 38 Type: "RSA PRIVATE KEY", 39 Bytes: x509.MarshalPKCS1PrivateKey(key), 40 }) 41 42 public, err = PublicKey(identity, comment) 43 if err != nil { 44 return "", "", errors.Trace(err) 45 } 46 47 return string(identity), public, nil 48 } 49 50 // PublicKey returns the public key for any private key. The public key is 51 // suitable to be added into an authorized_keys file, and has the comment 52 // passed in as the comment part of the key. 53 func PublicKey(privateKey []byte, comment string) (string, error) { 54 signer, err := ssh.ParsePrivateKey(privateKey) 55 if err != nil { 56 return "", errors.Annotate(err, "failed to load key") 57 } 58 59 auth_key := string(ssh.MarshalAuthorizedKey(signer.PublicKey())) 60 // Strip off the trailing new line so we can add a comment. 61 auth_key = strings.TrimSpace(auth_key) 62 public := fmt.Sprintf("%s %s\n", auth_key, comment) 63 64 return public, nil 65 }