launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/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 "launchpad.net/errgo/errors" 13 "strings" 14 15 "code.google.com/p/go.crypto/ssh" 16 ) 17 18 // KeyBits is used to determine the number of bits to use for the RSA keys 19 // created using the GenerateKey function. 20 var KeyBits = 2048 21 22 // GenerateKey makes a 2048 bit RSA no-passphrase SSH capable key. The bit 23 // size is actually controlled by the KeyBits var. The private key returned is 24 // encoded to ASCII using the PKCS1 encoding. The public key is suitable to 25 // be added into an authorized_keys file, and has the comment passed in as the 26 // comment part of the key. 27 func GenerateKey(comment string) (private, public string, err error) { 28 key, err := rsa.GenerateKey(rand.Reader, KeyBits) 29 if err != nil { 30 return "", "", mask(err) 31 } 32 33 identity := pem.EncodeToMemory( 34 &pem.Block{ 35 Type: "RSA PRIVATE KEY", 36 Bytes: x509.MarshalPKCS1PrivateKey(key), 37 }) 38 39 signer, err := ssh.ParsePrivateKey(identity) 40 if err != nil { 41 return "", "", errors.Notef(err, "failed to load key") 42 } 43 44 auth_key := string(ssh.MarshalAuthorizedKey(signer.PublicKey())) 45 // Strip off the trailing new line so we can add a comment. 46 auth_key = strings.TrimSpace(auth_key) 47 public = fmt.Sprintf("%s %s\n", auth_key, comment) 48 49 return string(identity), public, nil 50 }