Skip to content
Snippets Groups Projects
Commit ca0855ab authored by Damyan Mitev's avatar Damyan Mitev :beach:
Browse files

implement separate configuration for encryption of private keys

parent a7aa86cc
No related branches found
No related tags found
1 merge request!63vereign root certificate expires on 1st november
Pipeline #32183 passed
......@@ -49,7 +49,15 @@ certificationKeyFile: privateKey
certificationCaCertFile: caCertificateKey
#certificationVereignCertFile: vereign_ca.cer
certificationVereignCertFile: vereignCaCertificateKey
#certificationVereignKeyFile: vereign_ca.key
certificationVereignKeyFile: vereignCaPrivateKey
#certificationVereignKeyFile: Not used anymore, its functionality is moved to vaultEncryptionKeyFile
#possible levels: trace, info, debug, warn, error, fatal, panic
globalLogLevel: debug
\ No newline at end of file
globalLogLevel: debug
# Until vereign root cert expires, these values will copy the values of certificationVereign(Cert|Key)File.
# When the root cert is changed, the new root will be set in certificationVereign(Cert|Key)File,
# while here will continue to be the old root
vaultEncryptionURL: http://10.6.10.119:8200
vaultEncryptionToken: YOUR_VAULT_TOKEN
vaultEncryptionPath: /developers/data/devteam/cert
vaultEncryptionCertFile: vereignCaCertificateKey
vaultEncryptionKeyFile: vereignCaPrivateKey
package config
import (
"bytes"
"code.vereign.com/code/viam-apis/clientutils"
"code.vereign.com/code/viam-apis/errors"
"crypto"
"crypto/x509"
"os"
"path/filepath"
"strings"
......@@ -24,7 +29,9 @@ var CertificatePEM []byte
var PrivateKeyPEM []byte
var CaCertificatePEM []byte
var VereignCaCertificatePEM []byte
var VereignCaKeyPEM []byte
var EncryptionCert *x509.Certificate
var EncryptionKey crypto.Signer
var ReplaceKey bool
......@@ -40,7 +47,7 @@ var GlobalLogLevel string
var PrometeusListenAddress string
var MetricEnvPrefix string
func SetConfigValues(configFile, etcdURL string) {
func SetConfigValues(configFile, etcdURL string) error {
// Set Default Values For Config Variables
// Vereign API Related
......@@ -66,7 +73,6 @@ func SetConfigValues(configFile, etcdURL string) {
viper.SetDefault("certificationKeyFile", "server.key")
viper.SetDefault("certificationCaCertFile", "ca.crt")
viper.SetDefault("certificationVereignCertFile", "vereign_ca.cer")
viper.SetDefault("certificationVereignKeyFile", "vereign_ca.key")
viper.SetDefault("globalLogLevel", "info")
/*
......@@ -79,9 +85,15 @@ func SetConfigValues(configFile, etcdURL string) {
viper.SetDefault("certificationKeyFile", "privateKey")
viper.SetDefault("certificationCaCertFile", "caCertificateKey")
viper.SetDefault("certificationVereignCertFile", "vereignCaCertificateKey")
viper.SetDefault("certificationVereignKeyFile", "vereignCaPrivateKey")
*/
// Encryption/Decryption Related
viper.SetDefault("vaultEncryptionURL", "")
viper.SetDefault("vaultEncryptionToken", "")
viper.SetDefault("vaultEncryptionPath", "")
viper.SetDefault("vaultEncryptionCertFile", "")
viper.SetDefault("vaultEncryptionKeyFile", "")
// Read Config File
if configFile != "" {
configName := strings.Split(filepath.Base(configFile), ".")[0]
......@@ -110,8 +122,7 @@ func SetConfigValues(configFile, etcdURL string) {
certificationCertFile: viper.GetString("certificationCertFile"),
certificationKeyFile: viper.GetString("certificationKeyFile"),
certificationCaCertFile: viper.GetString("certificationCaCertFile"),
certificationVereignCertFile: viper.GetString("certificationVereignCertFile"),
certificationVereignKeyFile: viper.GetString("certificationVereignKeyFile")}
certificationVereignCertFile: viper.GetString("certificationVereignCertFile")}
} else if CertificationMethod == "2" {
// Read From Vault
P = VaultPEMReader{certificationURL: viper.GetString("certificationURL"),
......@@ -120,8 +131,57 @@ func SetConfigValues(configFile, etcdURL string) {
certificationCertFile: viper.GetString("certificationCertFile"),
certificationKeyFile: viper.GetString("certificationKeyFile"),
certificationCaCertFile: viper.GetString("certificationCaCertFile"),
certificationVereignCertFile: viper.GetString("certificationVereignCertFile"),
certificationVereignKeyFile: viper.GetString("certificationVereignKeyFile")}
certificationVereignCertFile: viper.GetString("certificationVereignCertFile")}
}
// Encryption/Decryption Related
if viper.GetString("vaultEncryptionURL") == "" ||
viper.GetString("vaultEncryptionToken") == "" ||
viper.GetString("vaultEncryptionPath") == "" ||
viper.GetString("vaultEncryptionCertFile") == "" ||
viper.GetString("vaultEncryptionKeyFile") == "" {
log.Error("Some config values for encryption/decryption are missing!")
return errors.NewFormat("Some config values for encryption/decryption are missing!")
}
encryptionCertPEM, err := ReadEncryptionPEMFromVault(
viper.GetString("vaultEncryptionURL"),
viper.GetString("vaultEncryptionToken"),
viper.GetString("vaultEncryptionPath"),
viper.GetString("vaultEncryptionCertFile"))
if err != nil {
errors.LogFormat(err, "Vault Err")
return err
}
encryptionKeyPEM, err := ReadEncryptionPEMFromVault(
viper.GetString("vaultEncryptionURL"),
viper.GetString("vaultEncryptionToken"),
viper.GetString("vaultEncryptionPath"),
viper.GetString("vaultEncryptionKeyFile"))
if err != nil {
errors.LogFormat(err, "Vault Err")
return err
}
var encryptionCerts []*x509.Certificate
encryptionCerts, EncryptionKey, err = clientutils.LoadCertAndKey(encryptionCertPEM, encryptionKeyPEM)
if err != nil {
errors.LogFormat(err, "Load Err")
return err
}
if len(encryptionCerts) != 1 {
log.Errorf("%d certs found in vaultEncryptionCertFile, 1 expected", len(encryptionCerts))
return err
}
EncryptionCert = encryptionCerts[0]
keyPub, err := x509.MarshalPKIXPublicKey(EncryptionKey.Public())
if err != nil {
return err
}
certPub, err := x509.MarshalPKIXPublicKey(EncryptionCert.PublicKey)
if err != nil {
return err
}
if !bytes.Equal(keyPub, certPub) {
return errors.New("Encryption certificate public key does not correspond to encryption private key")
}
// Print all config values to log file
......@@ -154,7 +214,8 @@ func SetConfigValues(configFile, etcdURL string) {
PrivateKeyPEM = GetPrivateKeyPEM()
CaCertificatePEM = GetCaCertificatePEM()
VereignCaCertificatePEM = GetVereignCaCertificatePEM()
VereignCaKeyPEM = GetVereignCaKeyPEM()
return nil
}
func GetCertificatePEM() []byte {
......@@ -172,7 +233,3 @@ func GetCaCertificatePEM() []byte {
func GetVereignCaCertificatePEM() []byte {
return P.readVereignCaCertificatePEM()
}
func GetVereignCaKeyPEM() []byte {
return P.readVereignCaKeyPEM()
}
package config
import (
"code.vereign.com/code/viam-apis/errors"
"io/ioutil"
"code.vereign.com/code/viam-apis/log"
......@@ -13,7 +14,6 @@ type PEMReader interface {
readPrivateKeyPEM() []byte
readCaCertificatePEM() []byte
readVereignCaCertificatePEM() []byte
readVereignCaKeyPEM() []byte
}
type FilePEMReader struct {
......@@ -24,7 +24,6 @@ type FilePEMReader struct {
certificationKeyFile string
certificationCaCertFile string
certificationVereignCertFile string
certificationVereignKeyFile string
}
func (f FilePEMReader) readCertificatePEM() []byte {
......@@ -63,15 +62,6 @@ func (f FilePEMReader) readVereignCaCertificatePEM() []byte {
return pem
}
func (f FilePEMReader) readVereignCaKeyPEM() []byte {
pem, err := ioutil.ReadFile(f.certificationPath + "/" + f.certificationVereignKeyFile)
if err != nil {
log.Printf("Error: %v", err)
return []byte("")
}
return pem
}
type VaultPEMReader struct {
certificationURL string
certificationToken string
......@@ -80,7 +70,6 @@ type VaultPEMReader struct {
certificationKeyFile string
certificationCaCertFile string
certificationVereignCertFile string
certificationVereignKeyFile string
}
func (v VaultPEMReader) readCertificatePEM() []byte {
......@@ -191,29 +180,32 @@ func (v VaultPEMReader) readVereignCaCertificatePEM() []byte {
return []byte("")
}
func (v VaultPEMReader) readVereignCaKeyPEM() []byte {
//copied from object storage agent
func ReadEncryptionPEMFromVault(url, token, path, pemFile string) ([]byte, error) {
client, err := vc.NewClient(&vc.Config{
Address: v.certificationURL,
Address: url,
})
if err != nil {
log.Printf("Error: VAULT Can't create client, %s", err)
errors.LogFormat(err, "VAULT Can't create client")
return nil, err
}
client.SetToken(v.certificationToken)
client.SetToken(token)
keyname := v.certificationPath
keyname := path
secretValues, err := client.Logical().Read(keyname)
if err != nil {
log.Printf("Error: VAULT Can't read value, %s", err)
errors.LogFormat(err, "VAULT Can't read value")
return nil, err
}
pemMap := secretValues.Data["data"].(map[string]interface{})
for propName, propValue := range pemMap {
if propName == v.certificationVereignKeyFile {
return []byte(propValue.(string))
if propName == pemFile {
return []byte(propValue.(string)), nil
}
}
return []byte("")
return []byte(""), nil
}
......@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package handler
import (
"code.vereign.com/code/key-storage-agent/config"
"code.vereign.com/code/viam-apis/errors"
"crypto/aes"
"crypto/cipher"
......@@ -86,7 +87,7 @@ func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context,
return nil, errors.WrapInternalFormat(err, "Could not store key %s", uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE))
}
encryptedAesKeyBytes, err := rsaEncryptWithServerKey(s.VereignCertPEM, aesKeyBytes, []byte("aeskeys"))
encryptedAesKeyBytes, err := rsaEncryptWithServerKey(aesKeyBytes, []byte("aeskeys"))
if err != nil {
return nil, errors.WrapInternal(err, "Could not encrypt")
}
......@@ -98,7 +99,7 @@ func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context,
return nil, errors.WrapInternalFormat(err, "Could not store key %s", uuid+"/"+api.KeyType.String(api.KeyType_AES))
}
encryptedPrivateKeyNonceBytes, err := rsaEncryptWithServerKey(s.VereignCertPEM, privateKeyNonce, []byte("nonce"))
encryptedPrivateKeyNonceBytes, err := rsaEncryptWithServerKey(privateKeyNonce, []byte("nonce"))
if err != nil {
return nil, errors.WrapInternal(err, "Could not encrypt private key")
}
......@@ -158,13 +159,8 @@ func generateKeyPair(keySize int) ([]byte, []byte, error) {
return privateKeyBytes, publicKeyBytes, nil
}
func rsaEncryptWithServerKey(certPEM []byte, message []byte, label []byte) ([]byte, error) {
serverCertificate, err := keyutils.ReadCertificateFromPEM(certPEM)
if err != nil {
log.Printf("Error: %v", err)
return nil, err
}
serverPublicKey := serverCertificate.PublicKey.(*rsa.PublicKey)
func rsaEncryptWithServerKey(message []byte, label []byte) ([]byte, error) {
serverPublicKey := config.EncryptionCert.PublicKey.(*rsa.PublicKey)
encryptedMessageBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, serverPublicKey, message, label)
if err != nil {
......
......@@ -45,7 +45,6 @@ type KeyStorageServerImpl struct {
KeyPEM []byte
CaCertPEM []byte
VereignCertPEM []byte
VereignPrivateKeyPEM []byte
MaxMessageSize int
}
......
......@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"code.vereign.com/code/viam-apis/errors"
"flag"
"code.vereign.com/code/viam-apis/log"
......@@ -39,7 +40,11 @@ func main() {
return
}
config.SetConfigValues(*configFile, *etcdURL)
err := config.SetConfigValues(*configFile, *etcdURL)
if err != nil {
errors.LogFormat(err, "Can not set config values")
return
}
grpcAddress := config.GrpcListenAddress
restAddress := config.RestListenAddress
......@@ -48,7 +53,6 @@ func main() {
keyPem := config.PrivateKeyPEM
caCertPem := config.CaCertificatePEM
vereignCaCertificatePem := config.VereignCaCertificatePEM
vereignCaKeyPem := config.VereignCaKeyPEM
maxMessageSize := config.MaxMessageSize
log.SetConfiguration(config.GlobalLogLevel)
......@@ -56,7 +60,7 @@ func main() {
// fire the gRPC server in a goroutine
go func() {
err := server.StartGRPCServer(grpcAddress, certPem, keyPem, caCertPem, vereignCaCertificatePem,
vereignCaKeyPem, dataStorageAddress, maxMessageSize)
dataStorageAddress, maxMessageSize)
if err != nil {
log.Fatalf("failed to start gRPC server: %s", err)
}
......
......@@ -154,7 +154,7 @@ func createQueryTime(funcName string) prometheus.Summary {
return nil
}
func StartGRPCServer(address string, certPEM, privateKeyPEM, caCertPEM, vereignCertPEM, vereignPrivateKeyPEM []byte, dataStorageAddress string, maxMessageSize int) error {
func StartGRPCServer(address string, certPEM, privateKeyPEM, caCertPEM, vereignCertPEM []byte, dataStorageAddress string, maxMessageSize int) error {
pkgCertPEM = certPEM
pkgKeyPEM = privateKeyPEM
pkgCaCertPEM = caCertPEM
......@@ -173,7 +173,6 @@ func StartGRPCServer(address string, certPEM, privateKeyPEM, caCertPEM, vereignC
KeyPEM: privateKeyPEM,
CaCertPEM: caCertPEM,
VereignCertPEM: vereignCertPEM,
VereignPrivateKeyPEM: vereignPrivateKeyPEM,
MaxMessageSize: maxMessageSize,
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment