Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
223
pkg/db/queries/ecckeys.go
Normal file
223
pkg/db/queries/ecckeys.go
Normal file
@@ -0,0 +1,223 @@
|
||||
package queries
|
||||
|
||||
import (
|
||||
"fiskerinc.com/modules/common"
|
||||
"fiskerinc.com/modules/logger"
|
||||
s "fiskerinc.com/modules/security"
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/go-pg/pg/v10/orm"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const sqlLastManifestEnv = "WITH sub AS (SELECT COALESCE((SELECT env FROM update_manifests WHERE id IN (SELECT update_manifest_id FROM car_updates WHERE id IN (SELECT MAX(id) FROM car_updates WHERE vin = ?))), 'current') as env)"
|
||||
const sqlCarUpdateIDEnv = "WITH sub AS (SELECT COALESCE((SELECT env FROM update_manifests WHERE update_manifests.id IN (SELECT update_manifest_id FROM car_updates WHERE id = ?)), 'current') as env)"
|
||||
const sqlECCPrivKeysEnv = " SELECT priv_key_level_1, priv_key_level_2, priv_key_level_3, ecu, ecc_keys.env FROM ecc_keys INNER JOIN sub ON ecc_keys.env = sub.env ORDER BY ecu;"
|
||||
|
||||
type EccKeysInterface interface {
|
||||
Insert(keys common.ECCKeys) (orm.Result, error)
|
||||
SelectAllPrivateKeys() ([]common.ECCKeys, error)
|
||||
SelectAllPrivateKeysByEnv(env string) ([]common.ECCKeys, error)
|
||||
SelectPublicKeysByECUByEnv(ecu string, env string) (common.ECCKeys, error)
|
||||
SelectAllPublicKeysByEnv(env string) ([]common.ECCKeys, error)
|
||||
SelectPrivateKeysByECUsEnv(ecus []string, env string) ([]common.ECCKeys, error)
|
||||
SelectAllPrivateKeysByVIN(vin string) ([]common.ECCKeys, error)
|
||||
SelectAllPrivateKeysByCarUpdateID(id int64) ([]common.ECCKeys, error)
|
||||
}
|
||||
|
||||
type EccKeys struct {
|
||||
QueryBase
|
||||
}
|
||||
|
||||
func (ek *EccKeys) Insert(keys common.ECCKeys) (orm.Result, error) {
|
||||
enc := s.Encrypt{}
|
||||
encryptor, err := enc.GetEncryptor()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keys.PubKey1.SetBytes(encryptor.EncryptChunk(keys.PubKey1.Bytes()))
|
||||
keys.PrivKey1.SetBytes(encryptor.EncryptChunk(keys.PrivKey1.Bytes()))
|
||||
keys.PubKey2.SetBytes(encryptor.EncryptChunk(keys.PubKey2.Bytes()))
|
||||
keys.PrivKey2.SetBytes(encryptor.EncryptChunk(keys.PrivKey2.Bytes()))
|
||||
keys.PubKey3.SetBytes(encryptor.EncryptChunk(keys.PubKey3.Bytes()))
|
||||
keys.PrivKey3.SetBytes(encryptor.EncryptChunk(keys.PrivKey3.Bytes()))
|
||||
|
||||
return ek.resultWithStack(ek.GetDBConn().Model(&keys).Insert())
|
||||
}
|
||||
|
||||
// Selects all private keys and ECU's
|
||||
func (ek *EccKeys) SelectAllPrivateKeys() ([]common.ECCKeys, error) {
|
||||
return ek.selectKeys("current", "priv_key_level_1", "priv_key_level_2", "priv_key_level_3", "ecu")
|
||||
}
|
||||
|
||||
// Selects all private keys and ECU's by env
|
||||
func (ek *EccKeys) SelectAllPrivateKeysByEnv(env string) ([]common.ECCKeys, error) {
|
||||
return ek.selectKeys(env, "priv_key_level_1", "priv_key_level_2", "priv_key_level_3", "ecu")
|
||||
}
|
||||
|
||||
// Selects public keys associated with ECU by env
|
||||
func (ek *EccKeys) SelectAllPublicKeysByEnv(env string) ([]common.ECCKeys, error) {
|
||||
return ek.selectKeys(env, "pub_key_level_1", "pub_key_level_2", "pub_key_level_3", "ecu")
|
||||
}
|
||||
|
||||
// Selects keys associated with ECU
|
||||
func (ek *EccKeys) SelectAllKeys() ([]common.ECCKeys, error) {
|
||||
return ek.selectKeys("current", "pub_key_level_1", "pub_key_level_2", "pub_key_level_3", "priv_key_level_1", "priv_key_level_2", "priv_key_level_3", "ecu")
|
||||
}
|
||||
|
||||
// Selects public keys associated with ECU by env
|
||||
func (ek *EccKeys) SelectPublicKeysByECUByEnv(ecu string, env string) (common.ECCKeys, error) {
|
||||
ecckey := common.ECCKeys{}
|
||||
|
||||
err := ek.GetDBConn().Model(&ecckey).Column("pub_key_level_1", "pub_key_level_2", "pub_key_level_3", "ecu").Where("ecu = ? AND env = ?", ecu, env).Select()
|
||||
if err != nil {
|
||||
return ecckey, errors.WithStack(err)
|
||||
}
|
||||
|
||||
err = ek.decrypt(&ecckey)
|
||||
|
||||
return ecckey, err
|
||||
}
|
||||
|
||||
func (ek *EccKeys) SelectPrivateKeysByECUsEnv(ecus []string, env string) ([]common.ECCKeys, error) {
|
||||
var keys []common.ECCKeys
|
||||
|
||||
if env == "" {
|
||||
env = common.EnvCurrent
|
||||
}
|
||||
|
||||
err := ek.GetDBConn().Model(&keys).
|
||||
Column("priv_key_level_1", "priv_key_level_2", "priv_key_level_3", "ecu").
|
||||
Where("ecu IN (?) AND env = ?", pg.In(ecus), env).
|
||||
Order("ecu").
|
||||
Select()
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
for i := range keys {
|
||||
err = ek.decrypt(&keys[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// SelectAllPrivateKeysByVIN returns the ECC keys for an environment based on the last update sent to the VIN
|
||||
// If no update was sent, it will send the keys for the current environment
|
||||
func (ek *EccKeys) SelectAllPrivateKeysByVIN(vin string) ([]common.ECCKeys, error) {
|
||||
var keys []common.ECCKeys
|
||||
|
||||
_, err := ek.GetDBConn().Query(&keys, sqlLastManifestEnv+sqlECCPrivKeysEnv, vin)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if len(keys) == 0 {
|
||||
return nil, errors.Errorf("No ECC keys for %s", vin)
|
||||
}
|
||||
|
||||
logger.Info().Msgf("SelectAllPrivateKeysByVIN %s %s", vin, keys[0].Env)
|
||||
|
||||
for i := range keys {
|
||||
keys[i].Env = ""
|
||||
err = ek.decrypt(&keys[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (ek *EccKeys) SelectAllPrivateKeysByCarUpdateID(id int64) ([]common.ECCKeys, error) {
|
||||
var keys []common.ECCKeys
|
||||
|
||||
_, err := ek.GetDBConn().Query(&keys, sqlCarUpdateIDEnv+sqlECCPrivKeysEnv, id)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if len(keys) == 0 {
|
||||
return nil, errors.Errorf("No ECC keys for car update id %d", id)
|
||||
}
|
||||
|
||||
logger.Info().Msgf("SelectAllPrivateKeysByCarUpdateID %d %s", id, keys[0].Env)
|
||||
|
||||
for i := range keys {
|
||||
keys[i].Env = ""
|
||||
err = ek.decrypt(&keys[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (ek *EccKeys) selectKeys(env string, columns ...string) ([]common.ECCKeys, error) {
|
||||
ecckeys := []common.ECCKeys{}
|
||||
|
||||
err := ek.GetDBConn().Model(&ecckeys).Column(columns...).Where("env = ?", env).Order("ecu").Select()
|
||||
if err != nil {
|
||||
return ecckeys, errors.WithStack(err)
|
||||
}
|
||||
|
||||
for i := range ecckeys {
|
||||
err = ek.decrypt(&ecckeys[i])
|
||||
}
|
||||
|
||||
return ecckeys, err
|
||||
}
|
||||
|
||||
func (ek *EccKeys) decrypt(eccKeys *common.ECCKeys) error {
|
||||
enc := s.Encrypt{}
|
||||
encryptor, err := enc.GetEncryptor()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ek.decryptKey(encryptor, eccKeys.PrivKey1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ek.decryptKey(encryptor, eccKeys.PrivKey2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ek.decryptKey(encryptor, eccKeys.PrivKey3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ek.decryptKey(encryptor, eccKeys.PubKey1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ek.decryptKey(encryptor, eccKeys.PubKey2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ek.decryptKey(encryptor, eccKeys.PubKey3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ek *EccKeys) decryptKey(encryptor s.IEncryptor, key *common.BinaryHex) error {
|
||||
if key != nil {
|
||||
keys, err := encryptor.DecryptChunk(key.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.SetBytes(keys)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user