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  }