224 lines
6.4 KiB
Go
224 lines
6.4 KiB
Go
package queries
|
|
|
|
import (
|
|
"github.com/fiskerinc/cloud-services/pkg/common"
|
|
"github.com/fiskerinc/cloud-services/pkg/logger"
|
|
s "github.com/fiskerinc/cloud-services/pkg/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
|
|
}
|