github.com/devops-filetransfer/sshego@v7.0.4+incompatible/rsa.go (about)

     1  package sshego
     2  
     3  import (
     4  	"bytes"
     5  	cryptrand "crypto/rand"
     6  	"crypto/rsa"
     7  	"crypto/x509"
     8  	"encoding/pem"
     9  	"fmt"
    10  	"io/ioutil"
    11  
    12  	"github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh"
    13  )
    14  
    15  // GenRSAKeyPair generates an RSA keypair of length bits. If rsa_file != "", we write
    16  // the private key to rsa_file and the public key to rsa_file + ".pub". If rsa_file == ""
    17  // the keys are not written to disk.
    18  //
    19  func GenRSAKeyPair(rsaFile string, bits int, email string) (priv *rsa.PrivateKey, sshPriv ssh.Signer, err error) {
    20  	p("GenRSAKeyPair called.")
    21  	privKey, err := rsa.GenerateKey(cryptrand.Reader, bits)
    22  	panicOn(err)
    23  
    24  	var pubKey *rsa.PublicKey = privKey.Public().(*rsa.PublicKey)
    25  
    26  	err = privKey.Validate()
    27  	panicOn(err)
    28  
    29  	// write to disk
    30  	// save to pem: serialize private key
    31  	privBytes := pem.EncodeToMemory(
    32  		&pem.Block{
    33  			Type:  "RSA PRIVATE KEY",
    34  			Bytes: x509.MarshalPKCS1PrivateKey(privKey),
    35  		},
    36  	)
    37  
    38  	// sshPrivKey is the ssh.Signer, 2nd returned value.
    39  	sshPrivKey, err := ssh.ParsePrivateKey(privBytes)
    40  	panicOn(err)
    41  
    42  	if rsaFile != "" {
    43  		p("GenRSAKeyPair is serializing to rsaFile -> '%s' and .pub", rsaFile)
    44  
    45  		// serialize public key
    46  		pubBytes := RSAToSSHPublicKey(pubKey)
    47  
    48  		if email != "" {
    49  			p("adding in email")
    50  			var by bytes.Buffer
    51  			fmt.Fprintf(&by, " %s\n", email)
    52  			n := len(pubBytes)
    53  			// overwrite the newline
    54  			pubBytes = append(pubBytes[:n-1], by.Bytes()...)
    55  		}
    56  
    57  		err = ioutil.WriteFile(rsaFile, privBytes, 0600)
    58  		panicOn(err)
    59  
    60  		err = ioutil.WriteFile(rsaFile+".pub", pubBytes, 0600)
    61  		panicOn(err)
    62  	}
    63  
    64  	return privKey, sshPrivKey, nil
    65  }
    66  
    67  // RSAToSSHPublicKey convert an RSA Public Key to the SSH authorized_keys format.
    68  func RSAToSSHPublicKey(pubkey *rsa.PublicKey) []byte {
    69  	pub, err := ssh.NewPublicKey(pubkey)
    70  	panicOn(err)
    71  	return ssh.MarshalAuthorizedKey(pub)
    72  }
    73  
    74  // LoadRSAPrivateKey reads a private key from path on disk.
    75  func LoadRSAPrivateKey(path string) (privkey ssh.Signer, err error) {
    76  	buf, err := ioutil.ReadFile(path)
    77  	if err != nil {
    78  		return nil, fmt.Errorf("got error '%s' trying to read path '%s'", err, path)
    79  	}
    80  
    81  	privkey, err = ssh.ParsePrivateKey(buf)
    82  	if err != nil {
    83  		return nil, fmt.Errorf("got error '%s' trying to parse private key from path '%s'", err, path)
    84  	}
    85  
    86  	return privkey, err
    87  }
    88  
    89  // LoadRSAPublicKey reads a public key from path on disk. By convention
    90  // these keys end in '.pub', but that is not verified here.
    91  func LoadRSAPublicKey(path string) (pubkey ssh.PublicKey, err error) {
    92  	var buf []byte
    93  	buf, err = ioutil.ReadFile(path)
    94  	if err != nil {
    95  		return
    96  	}
    97  
    98  	pubkey, _, _, _, err = ssh.ParseAuthorizedKey(buf)
    99  	return
   100  }