169 lines
4.1 KiB
Go
169 lines
4.1 KiB
Go
package api
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"path/filepath"
|
|
)
|
|
|
|
const (
|
|
RSA_KEY_LENGTH = 4096
|
|
|
|
QliksensePublicKey = "qliksensePub"
|
|
QliksensePrivateKey = "qliksensePriv"
|
|
)
|
|
|
|
// GenerateAndStoreSecretKeypair generates and stores key pairs
|
|
func GenerateAndStoreSecretKeypair(secretsPath string) error {
|
|
LogDebugMessage("%s exists", secretsPath)
|
|
// creating contexts/qlik-default/secrets/qliksensePub and contexts/qlik-default/secrets/qliksensePriv files
|
|
publicKeyFilePath := filepath.Join(secretsPath, QliksensePublicKey)
|
|
privateKeyFilePath := filepath.Join(secretsPath, QliksensePrivateKey)
|
|
LogDebugMessage("Generating public-private key pair.....")
|
|
GenerateRSAEncryptionKeys(publicKeyFilePath, privateKeyFilePath)
|
|
LogDebugMessage("Generated public-private key pairs")
|
|
|
|
return nil
|
|
}
|
|
|
|
// GenerateRSAEncryptionKeys is used to generate a new public-private key pair
|
|
func GenerateRSAEncryptionKeys(publicKeyFilePath, privateKeyFilePath string) error {
|
|
LogDebugMessage("Generating new RSA key pair")
|
|
privateKey, err := rsa.GenerateKey(rand.Reader, RSA_KEY_LENGTH)
|
|
if err != nil {
|
|
log.Printf("error generating RSA private key: %v\n", err)
|
|
return err
|
|
}
|
|
|
|
privateKeyPEM := EncodePrivateKey(privateKey)
|
|
if err := writeContentToFile(privateKeyPEM, privateKeyFilePath); err != nil {
|
|
return err
|
|
}
|
|
pubKeyPEM, err2 := EncodePublicKey(&privateKey.PublicKey)
|
|
if err2 != nil {
|
|
log.Printf("error occurred when encoding public key: %v\n", err2)
|
|
return err2
|
|
}
|
|
if err := writeContentToFile(pubKeyPEM, publicKeyFilePath); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// writeContentToFile writes keys to a file
|
|
func writeContentToFile(keyData []byte, fileName string) error {
|
|
err := ioutil.WriteFile(fileName, keyData, 0600)
|
|
if err != nil {
|
|
log.Printf("error writing to file (%s): %v", fileName, err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Encrypt encrypts data with public key
|
|
func Encrypt(pt []byte, pub *rsa.PublicKey) ([]byte, error) {
|
|
//hash := sha512.New()
|
|
//ct, err := rsa.EncryptOAEP(hash, rand.Reader, pub, pt, nil)
|
|
ct, err := rsa.EncryptPKCS1v15(rand.Reader, pub, pt)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
return ct, nil
|
|
}
|
|
|
|
// Decrypt decrypts data with private key
|
|
func Decrypt(ct []byte, priv *rsa.PrivateKey) ([]byte, error) {
|
|
// hash := sha512.New()
|
|
// plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil)
|
|
pt, err := rsa.DecryptPKCS1v15(rand.Reader, priv, ct)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
return pt, nil
|
|
}
|
|
|
|
// EncodePrivateKey private key to bytes
|
|
func EncodePrivateKey(priv *rsa.PrivateKey) []byte {
|
|
privBytes := pem.EncodeToMemory(
|
|
&pem.Block{
|
|
Type: "RSA PRIVATE KEY",
|
|
Bytes: x509.MarshalPKCS1PrivateKey(priv),
|
|
},
|
|
)
|
|
|
|
return privBytes
|
|
}
|
|
|
|
// EncodePublicKey public key to bytes
|
|
func EncodePublicKey(pub *rsa.PublicKey) ([]byte, error) {
|
|
pubASN1, err := x509.MarshalPKIXPublicKey(pub)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
|
|
pubBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PUBLIC KEY",
|
|
Bytes: pubASN1,
|
|
})
|
|
|
|
return pubBytes, nil
|
|
}
|
|
|
|
// DecodeToPrivateKey bytes to private key
|
|
func DecodeToPrivateKey(priv []byte) (*rsa.PrivateKey, error) {
|
|
block, _ := pem.Decode(priv)
|
|
enc := x509.IsEncryptedPEMBlock(block)
|
|
b := block.Bytes
|
|
var err error
|
|
if enc {
|
|
log.Println("is encrypted pem block")
|
|
b, err = x509.DecryptPEMBlock(block, nil)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
}
|
|
key, err := x509.ParsePKCS1PrivateKey(b)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// DecodeToPublicKey bytes to public key
|
|
func DecodeToPublicKey(pub []byte) (*rsa.PublicKey, error) {
|
|
block, _ := pem.Decode(pub)
|
|
enc := x509.IsEncryptedPEMBlock(block)
|
|
b := block.Bytes
|
|
var err error
|
|
if enc {
|
|
log.Println("is encrypted pem block")
|
|
b, err = x509.DecryptPEMBlock(block, nil)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
}
|
|
iface, err := x509.ParsePKIXPublicKey(b)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
key, ok := iface.(*rsa.PublicKey)
|
|
if !ok {
|
|
err := fmt.Errorf("Unable to decode public key")
|
|
log.Println(err)
|
|
return nil, err
|
|
}
|
|
return key, nil
|
|
}
|