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 }