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

     1  package sshego
     2  
     3  import (
     4  	cryptrand "crypto/rand"
     5  	"crypto/rsa"
     6  	"crypto/x509"
     7  	"encoding/pem"
     8  	"fmt"
     9  	"io/ioutil"
    10  
    11  	"github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh"
    12  )
    13  
    14  /*
    15     // WARNING: not implemented/done yet. TODO: finish this.
    16  
    17     // looking at
    18     // /usr/local/go/src/crypto/x509/pem_decrypt_test.go
    19     // here are ideas for implementation
    20  
    21     // encrypt:
    22  
    23  	if !x509.IsEncryptedPEMBlock(block) {
    24  		t.Error("PEM block does not appear to be encrypted")
    25  	}
    26  
    27  		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
    28  
    29  		block, err := EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", plainDER, password, data.kind)
    30  
    31     // decrypt:
    32  
    33  		der, err := DecryptPEMBlock(block, password)
    34  		if err != nil {
    35  			t.Error("decrypt: ", err)
    36  			continue
    37  		}
    38  
    39  or:
    40  
    41  		block, rest := pem.Decode(data.pemData)
    42  		if len(rest) > 0 {
    43  			t.Error("extra data")
    44  		}
    45  		der, err := DecryptPEMBlock(block, data.password)
    46  		if err != nil {
    47  			t.Error("decrypt failed: ", err)
    48  			continue
    49  		}
    50  		if _, err := ParsePKCS1PrivateKey(der); err != nil {
    51  			t.Error("invalid private key: ", err)
    52  		}
    53  		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
    54  		if err != nil {
    55  			t.Fatal("cannot decode test DER data: ", err)
    56  		}
    57  		if !bytes.Equal(der, plainDER) {
    58  			t.Error("data mismatch")
    59  		}
    60  
    61     // /usr/local/go/src/crypto/x509/pem_decrypt_test.go
    62  
    63  
    64  */
    65  
    66  // TODO: Finish this-- specified but password based
    67  // encryption not implemented.
    68  // GenRSAKeyPairCrypt generates an RSA keypair of
    69  // length bits. If rsa_file != "", we write
    70  // the private key to rsa_file and the public
    71  // key to rsa_file + ".pub". If rsa_file == ""
    72  // the keys are not written to disk.
    73  // The private key is encrypted with the password.
    74  func GenRSAKeyPairCrypt(rsaFile string, bits int, password string) (priv *rsa.PrivateKey, sshPriv ssh.Signer, err error) {
    75  
    76  	privKey, err := rsa.GenerateKey(cryptrand.Reader, bits)
    77  	panicOn(err)
    78  
    79  	var pubKey *rsa.PublicKey = privKey.Public().(*rsa.PublicKey)
    80  
    81  	err = privKey.Validate()
    82  	panicOn(err)
    83  
    84  	// write to disk
    85  	// save to pem: serialize private key
    86  	privBytes := pem.EncodeToMemory(
    87  		&pem.Block{
    88  			Type:  "RSA PRIVATE KEY",
    89  			Bytes: x509.MarshalPKCS1PrivateKey(privKey),
    90  		},
    91  	)
    92  
    93  	sshPrivKey, err := ssh.ParsePrivateKey(privBytes)
    94  	panicOn(err)
    95  
    96  	if rsaFile != "" {
    97  
    98  		// serialize public key
    99  		pubBytes := RSAToSSHPublicKey(pubKey)
   100  
   101  		err = ioutil.WriteFile(rsaFile, privBytes, 0600)
   102  		panicOn(err)
   103  
   104  		err = ioutil.WriteFile(rsaFile+".pub", pubBytes, 0600)
   105  		panicOn(err)
   106  	}
   107  
   108  	return privKey, sshPrivKey, nil
   109  }
   110  
   111  // TODO: Finish this-- specified but password based
   112  // encryption not implemented.
   113  // LoadRSAPrivateKey reads a private key from path on disk.
   114  func LoadRSAPrivateKeyCrypt(path string, password string) (privkey ssh.Signer, err error) {
   115  	buf, err := ioutil.ReadFile(path)
   116  	if err != nil {
   117  		return nil, fmt.Errorf("got error '%s' trying to read path '%s'", err, path)
   118  	}
   119  
   120  	privkey, err = ssh.ParsePrivateKey(buf)
   121  	if err != nil {
   122  		return nil, fmt.Errorf("got error '%s' trying to parse private key from path '%s'", err, path)
   123  	}
   124  
   125  	return privkey, err
   126  }