diff --git a/config.yaml.sample b/config.yaml.sample index 887c3839d1d972a1c667353be3ec23c6936e2d0b..7e574fe041b35c1cea21576616a270e099e54524 100644 --- a/config.yaml.sample +++ b/config.yaml.sample @@ -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.16.32:8200 +vaultEncryptionToken: YOUR_VAULT_TOKEN +vaultEncryptionPath: /developers/data/devteam/cert +vaultEncryptionCertFile: encryptionCert +vaultEncryptionKeyFile: encryptionKey diff --git a/config/configs.go b/config/configs.go index a0af36eb4bc526a35280dfab2bbe405ae1bc33a8..6c09c440795d5868458c9958bed338289081206a 100644 --- a/config/configs.go +++ b/config/configs.go @@ -1,6 +1,11 @@ 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", "encryptionCert") + viper.SetDefault("vaultEncryptionKeyFile", "encryptionKey") + // Read Config File if configFile != "" { configName := strings.Split(filepath.Base(configFile), ".")[0] @@ -101,6 +113,13 @@ func SetConfigValues(configFile, etcdURL string) { } } + // Print all config values to log file + log.Printf("All Settings From Config:") + as := viper.AllSettings() + for key, _ := range as { + log.Printf("%s => %s", key, viper.GetString(key)) + } + CertificationMethod = viper.GetString("certificationMethod") if CertificationMethod == "1" { // Read From File System @@ -110,8 +129,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,15 +138,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")} } - // Print all config values to log file - log.Printf("All Settings From Config:") - as := viper.AllSettings() - for key, _ := range as { - log.Printf("%s => %s", key, viper.GetString(key)) + // 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") } GrpcListenAddress = viper.GetString("grpcListenAddress") @@ -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() -} diff --git a/config/pem_reader.go b/config/pem_reader.go index a9aafab9d921b40bdb24a3c4dbc17b2e5e18a173..88794e64a2ddf944a8254c3d89e70332160c5c25 100644 --- a/config/pem_reader.go +++ b/config/pem_reader.go @@ -1,6 +1,7 @@ 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 } diff --git a/handler/generate_keypair.go b/handler/generate_keypair.go index 00c6305ec6e66f2de35cb35d8abf6c038ad903d3..a2e538c5ac14c440f13e44c4dc0e37c52f59dd28 100644 --- a/handler/generate_keypair.go +++ b/handler/generate_keypair.go @@ -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 { diff --git a/handler/handler.go b/handler/handler.go index 2122beaa447cb563c32e153b5d56dcb086ea5692..6e502d016d1805156b6b227644604bea146bc156 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -45,7 +45,6 @@ type KeyStorageServerImpl struct { KeyPEM []byte CaCertPEM []byte VereignCertPEM []byte - VereignPrivateKeyPEM []byte MaxMessageSize int } diff --git a/main.go b/main.go index 6efd689f828c505c7df7851c6abe1c503727ef91..ec9523e4fd4b45913f56c2908273e9f8cf4e6864 100644 --- a/main.go +++ b/main.go @@ -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) } diff --git a/server/server.go b/server/server.go index f24dba110d18f0d06ec4f360397d5050f2b94cf6..46868aebf4d01a98e2a141a6cc612c816133f30f 100644 --- a/server/server.go +++ b/server/server.go @@ -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, }