mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
parent
641751f163
commit
979bf5ce3f
@ -87,7 +87,7 @@ func IsEncryptionPayload(data []byte) (bool, error) {
|
|||||||
return es.Version != "", nil
|
return es.Version != "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *baseEncryption) encrypt(data []byte) ([]byte, error) {
|
func (s *baseEncryption) encrypt(data []byte, enhance func(basedata) interface{}) ([]byte, error) {
|
||||||
// No configuration provided, don't do anything
|
// No configuration provided, don't do anything
|
||||||
if s.target == nil {
|
if s.target == nil {
|
||||||
return data, nil
|
return data, nil
|
||||||
@ -117,7 +117,7 @@ func (s *baseEncryption) encrypt(data []byte) ([]byte, error) {
|
|||||||
Meta: s.encMeta,
|
Meta: s.encMeta,
|
||||||
Data: encd,
|
Data: encd,
|
||||||
}
|
}
|
||||||
jsond, err := json.Marshal(es)
|
jsond, err := json.Marshal(enhance(es))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to encode encrypted data as json: %w", err)
|
return nil, fmt.Errorf("unable to encode encrypted data as json: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -63,15 +63,15 @@ func Example() {
|
|||||||
|
|
||||||
sfe := enc.State()
|
sfe := enc.State()
|
||||||
|
|
||||||
// Encrypt the data, for this example we will be using the string "test",
|
// Encrypt the data, for this example we will be using the string `{"serial": 42, "lineage": "magic"}`,
|
||||||
// but in a real world scenario this would be the plan file.
|
// but in a real world scenario this would be the plan file.
|
||||||
sourceData := []byte("test")
|
sourceData := []byte(`{"serial": 42, "lineage": "magic"}`)
|
||||||
encrypted, err := sfe.EncryptState(sourceData)
|
encrypted, err := sfe.EncryptState(sourceData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(encrypted) == "test" {
|
if string(encrypted) == `{"serial": 42, "lineage": "magic"}` {
|
||||||
panic("The data has not been encrypted!")
|
panic("The data has not been encrypted!")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ func Example() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s\n", decryptedState)
|
fmt.Printf("%s\n", decryptedState)
|
||||||
// Output: test
|
// Output: {"serial": 42, "lineage": "magic"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDiags(diags hcl.Diagnostics) {
|
func handleDiags(diags hcl.Diagnostics) {
|
||||||
|
@ -55,7 +55,7 @@ func newPlanEncryption(enc *encryption, target *config.TargetConfig, enforced bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p planEncryption) EncryptPlan(data []byte) ([]byte, error) {
|
func (p planEncryption) EncryptPlan(data []byte) ([]byte, error) {
|
||||||
return p.base.encrypt(data)
|
return p.base.encrypt(data, func(base basedata) interface{} { return base })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p planEncryption) DecryptPlan(data []byte) ([]byte, error) {
|
func (p planEncryption) DecryptPlan(data []byte) ([]byte, error) {
|
||||||
|
@ -62,12 +62,32 @@ func newStateEncryption(enc *encryption, target *config.TargetConfig, enforced b
|
|||||||
return &stateEncryption{base}, diags
|
return &stateEncryption{base}, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type statedata struct {
|
||||||
|
Serial *int `json:"serial"`
|
||||||
|
Lineage string `json:"lineage"`
|
||||||
|
}
|
||||||
|
|
||||||
func (s *stateEncryption) EncryptState(plainState []byte) ([]byte, error) {
|
func (s *stateEncryption) EncryptState(plainState []byte) ([]byte, error) {
|
||||||
return s.base.encrypt(plainState)
|
var passthrough statedata
|
||||||
|
err := json.Unmarshal(plainState, &passthrough)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.base.encrypt(plainState, func(base basedata) interface{} {
|
||||||
|
// Merge together the base encryption data and the passthrough fields
|
||||||
|
return struct {
|
||||||
|
statedata
|
||||||
|
basedata
|
||||||
|
}{
|
||||||
|
statedata: passthrough,
|
||||||
|
basedata: base,
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stateEncryption) DecryptState(encryptedState []byte) ([]byte, error) {
|
func (s *stateEncryption) DecryptState(encryptedState []byte) ([]byte, error) {
|
||||||
return s.base.decrypt(encryptedState, func(data []byte) error {
|
decryptedState, err := s.base.decrypt(encryptedState, func(data []byte) error {
|
||||||
tmp := struct {
|
tmp := struct {
|
||||||
FormatVersion string `json:"terraform_version"`
|
FormatVersion string `json:"terraform_version"`
|
||||||
}{}
|
}{}
|
||||||
@ -82,6 +102,34 @@ func (s *stateEncryption) DecryptState(encryptedState []byte) ([]byte, error) {
|
|||||||
// Probably a state file
|
// Probably a state file
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that the state passthrough fields match
|
||||||
|
var encrypted statedata
|
||||||
|
err = json.Unmarshal(encryptedState, &encrypted)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var state statedata
|
||||||
|
err = json.Unmarshal(decryptedState, &state)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO make encrypted.Serial non-optional. This is only for supporting alpha1 states!
|
||||||
|
if encrypted.Serial != nil && state.Serial != nil && *state.Serial != *encrypted.Serial {
|
||||||
|
return nil, fmt.Errorf("invalid state metadata, serial field mismatch %v vs %v", *encrypted.Serial, *state.Serial)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO make encrypted.Lineage non-optional. This is only for supporting alpha1 states!
|
||||||
|
if encrypted.Lineage != "" && state.Lineage != encrypted.Lineage {
|
||||||
|
return nil, fmt.Errorf("invalid state metadata, linage field mismatch %v vs %v", encrypted.Lineage, state.Lineage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return decryptedState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StateEncryptionDisabled() StateEncryption {
|
func StateEncryptionDisabled() StateEncryption {
|
||||||
|
Loading…
Reference in New Issue
Block a user