encryption: re-use same IVs so that the ciphertext doesn't change when decrypting and reencrypting
Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
90abadf0de
commit
f374f4c5ea
@ -4,18 +4,21 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.mozilla.org/sops/v3"
|
||||
"go.mozilla.org/sops/v3/aes"
|
||||
sopsaes "go.mozilla.org/sops/v3/aes"
|
||||
sopsage "go.mozilla.org/sops/v3/age"
|
||||
"go.mozilla.org/sops/v3/cmd/sops/common"
|
||||
"go.mozilla.org/sops/v3/cmd/sops/formats"
|
||||
sopsdecrypt "go.mozilla.org/sops/v3/decrypt"
|
||||
sopskeys "go.mozilla.org/sops/v3/keys"
|
||||
sopsyaml "go.mozilla.org/sops/v3/stores/yaml"
|
||||
"go.mozilla.org/sops/v3/version"
|
||||
)
|
||||
|
||||
var (
|
||||
cipher = sopsaes.NewCipher()
|
||||
)
|
||||
|
||||
// setupEnv: hack to inject a SOPS env var for age
|
||||
func setupEnv() error {
|
||||
p, err := Path()
|
||||
@ -65,7 +68,7 @@ func Encrypt(ctx context.Context, path string, plaintext []byte, key string) ([]
|
||||
}
|
||||
|
||||
err = common.EncryptTree(common.EncryptTreeOpts{
|
||||
DataKey: dataKey, Tree: &tree, Cipher: aes.NewCipher(),
|
||||
DataKey: dataKey, Tree: &tree, Cipher: cipher,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -104,7 +107,7 @@ func Reencrypt(_ context.Context, path string, plaintext []byte) ([]byte, error)
|
||||
return nil, err
|
||||
}
|
||||
err = common.EncryptTree(common.EncryptTreeOpts{
|
||||
DataKey: key, Tree: &tree, Cipher: aes.NewCipher(),
|
||||
DataKey: key, Tree: &tree, Cipher: cipher,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -119,5 +122,38 @@ func Decrypt(_ context.Context, encrypted []byte) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sopsdecrypt.DataWithFormat(encrypted, formats.Yaml)
|
||||
store := &sopsyaml.Store{}
|
||||
|
||||
// Load SOPS file and access the data key
|
||||
tree, err := store.LoadEncryptedFile(encrypted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := tree.Metadata.GetDataKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Decrypt the tree
|
||||
mac, err := tree.Decrypt(key, cipher)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compute the hash of the cleartext tree and compare it with
|
||||
// the one that was stored in the document. If they match,
|
||||
// integrity was preserved
|
||||
originalMac, err := cipher.Decrypt(
|
||||
tree.Metadata.MessageAuthenticationCode,
|
||||
key,
|
||||
tree.Metadata.LastModified.Format(time.RFC3339),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if originalMac != mac {
|
||||
return nil, fmt.Errorf("failed to verify data integrity. expected mac %q, got %q", originalMac, mac)
|
||||
}
|
||||
|
||||
return store.EmitPlainFile(tree.Branches)
|
||||
}
|
||||
|
Reference in New Issue
Block a user