github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/keygen_test.go (about)

     1  // Copyright 2018-2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License.
     2  
     3  package runner
     4  
     5  import (
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/x509"
     9  	"encoding/asn1"
    10  	"encoding/pem"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/go-stack/stack"
    15  	"github.com/jjeffery/kv"
    16  )
    17  
    18  // GenerateTestKeys will generate a prtivate.pem and public.prm file in the nominated directory
    19  // containing PEM formatted RSA keys with a passphrase if supplied.
    20  //
    21  // Never use keys generated this way in production.
    22  //
    23  func GenerateTestKeys(dir string, bitSize int, passphrase string) (err kv.Error) {
    24  	reader := rand.Reader
    25  
    26  	key, errGo := rsa.GenerateKey(reader, bitSize)
    27  	if errGo != nil {
    28  		return kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())
    29  	}
    30  
    31  	if err = exportPrivatePEM(filepath.Join(dir, "private.pem"), passphrase, key); err != nil {
    32  		return err
    33  	}
    34  
    35  	if err = exportPublicPEM(filepath.Join(dir, "public.pem"), key.PublicKey); err != nil {
    36  		return err
    37  	}
    38  
    39  	return nil
    40  }
    41  
    42  func exportPrivatePEM(fn string, passphrase string, key *rsa.PrivateKey) (err kv.Error) {
    43  	out, errGo := os.Create(fn)
    44  	if errGo != nil {
    45  		return kv.Wrap(errGo).With("filename", fn, "stack", stack.Trace().TrimRuntime())
    46  	}
    47  	defer out.Close()
    48  
    49  	block := &pem.Block{
    50  		Type:  "RSA PRIVATE KEY",
    51  		Bytes: x509.MarshalPKCS1PrivateKey(key),
    52  	}
    53  
    54  	if passphrase != "" {
    55  		block, errGo = x509.EncryptPEMBlock(rand.Reader, block.Type, block.Bytes, []byte(passphrase), x509.PEMCipherAES256)
    56  		if errGo != nil {
    57  			return kv.Wrap(errGo).With("filename", fn, "stack", stack.Trace().TrimRuntime())
    58  		}
    59  	}
    60  
    61  	if errGo = pem.Encode(out, block); errGo != nil {
    62  		return kv.Wrap(errGo).With("filename", fn, "stack", stack.Trace().TrimRuntime())
    63  	}
    64  	return nil
    65  }
    66  
    67  func exportPublicPEM(fn string, pubkey rsa.PublicKey) (err kv.Error) {
    68  	asn1Bytes, errGo := asn1.Marshal(pubkey)
    69  	if errGo != nil {
    70  		return kv.Wrap(errGo).With("filename", fn, "stack", stack.Trace().TrimRuntime())
    71  	}
    72  
    73  	output, errGo := os.Create(fn)
    74  	if errGo != nil {
    75  		return kv.Wrap(errGo).With("filename", fn, "stack", stack.Trace().TrimRuntime())
    76  	}
    77  	defer output.Close()
    78  
    79  	block := &pem.Block{
    80  		Type:  "PUBLIC KEY",
    81  		Bytes: asn1Bytes,
    82  	}
    83  
    84  	if errGo = pem.Encode(output, block); errGo != nil {
    85  		return kv.Wrap(errGo).With("filename", fn, "stack", stack.Trace().TrimRuntime())
    86  	}
    87  	return nil
    88  }