1
0
mirror of https://github.com/getsops/sops.git synced 2026-02-05 12:45:21 +01:00

Introduce EncryptContext and DecryptContext for AWS, Azure, GCP, PGP

and HashiCorp Vault

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
This commit is contained in:
Matheus Pimenta
2025-05-03 13:07:20 +01:00
parent 60ea3acece
commit 036ef9faec
8 changed files with 135 additions and 45 deletions

View File

@@ -120,7 +120,15 @@ func (t TokenCredential) ApplyToMasterKey(key *MasterKey) {
// Encrypt takes a SOPS data key, encrypts it with Azure Key Vault, and stores
// the result in the EncryptedKey field.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
return key.EncryptContext(context.Background(), dataKey)
}
// EncryptContext takes a SOPS data key, encrypts it with Azure Key Vault, and stores
// the result in the EncryptedKey field.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
token, err := key.getTokenCredential()
if err != nil {
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
@@ -133,7 +141,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
return fmt.Errorf("failed to construct Azure Key Vault client to encrypt data: %w", err)
}
resp, err := c.Encrypt(context.Background(), key.Name, key.Version, azkeys.KeyOperationParameters{
resp, err := c.Encrypt(ctx, key.Name, key.Version, azkeys.KeyOperationParameters{
Algorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),
Value: dataKey,
}, nil)
@@ -169,7 +177,15 @@ func (key *MasterKey) EncryptIfNeeded(dataKey []byte) error {
// Decrypt decrypts the EncryptedKey field with Azure Key Vault and returns
// the result.
//
// Consider using DecryptContext instead.
func (key *MasterKey) Decrypt() ([]byte, error) {
return key.DecryptContext(context.Background())
}
// DecryptContext decrypts the EncryptedKey field with Azure Key Vault and returns
// the result.
func (key *MasterKey) DecryptContext(ctx context.Context) ([]byte, error) {
token, err := key.getTokenCredential()
if err != nil {
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Decryption failed")
@@ -188,7 +204,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
return nil, fmt.Errorf("failed to construct Azure Key Vault client to decrypt data: %w", err)
}
resp, err := c.Decrypt(context.Background(), key.Name, key.Version, azkeys.KeyOperationParameters{
resp, err := c.Decrypt(ctx, key.Name, key.Version, azkeys.KeyOperationParameters{
Algorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),
Value: rawEncryptedKey,
}, nil)

View File

@@ -118,8 +118,16 @@ func (c CredentialJSON) ApplyToMasterKey(key *MasterKey) {
// Encrypt takes a SOPS data key, encrypts it with GCP KMS, and stores the
// result in the EncryptedKey field.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
service, err := key.newKMSClient()
return key.EncryptContext(context.Background(), dataKey)
}
// EncryptContext takes a SOPS data key, encrypts it with GCP KMS, and stores the
// result in the EncryptedKey field.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
service, err := key.newKMSClient(ctx)
if err != nil {
log.WithField("resourceID", key.ResourceID).Info("Encryption failed")
return fmt.Errorf("cannot create GCP KMS service: %w", err)
@@ -134,7 +142,6 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
Name: key.ResourceID,
Plaintext: dataKey,
}
ctx := context.Background()
resp, err := service.Encrypt(ctx, req)
if err != nil {
log.WithField("resourceID", key.ResourceID).Info("Encryption failed")
@@ -169,8 +176,16 @@ func (key *MasterKey) EncryptIfNeeded(dataKey []byte) error {
// Decrypt decrypts the EncryptedKey field with GCP KMS and returns
// the result.
//
// Consider using DecryptContext instead.
func (key *MasterKey) Decrypt() ([]byte, error) {
service, err := key.newKMSClient()
return key.DecryptContext(context.Background())
}
// DecryptContext decrypts the EncryptedKey field with GCP KMS and returns
// the result.
func (key *MasterKey) DecryptContext(ctx context.Context) ([]byte, error) {
service, err := key.newKMSClient(ctx)
if err != nil {
log.WithField("resourceID", key.ResourceID).Info("Decryption failed")
return nil, fmt.Errorf("cannot create GCP KMS service: %w", err)
@@ -193,7 +208,6 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
Name: key.ResourceID,
Ciphertext: decodedCipher,
}
ctx := context.Background()
resp, err := service.Decrypt(ctx, req)
if err != nil {
log.WithField("resourceID", key.ResourceID).Info("Decryption failed")
@@ -232,7 +246,7 @@ func (key *MasterKey) TypeToIdentifier() string {
// or credentialJSON, and/or grpcConn, falling back to environmental defaults.
// It returns an error if the ResourceID is invalid, or if the setup of the
// client fails.
func (key *MasterKey) newKMSClient() (*kms.KeyManagementClient, error) {
func (key *MasterKey) newKMSClient(ctx context.Context) (*kms.KeyManagementClient, error) {
re := regexp.MustCompile(`^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$`)
matches := re.FindStringSubmatch(key.ResourceID)
if matches == nil {
@@ -265,7 +279,6 @@ func (key *MasterKey) newKMSClient() (*kms.KeyManagementClient, error) {
opts = append(opts, option.WithGRPCConn(key.grpcConn))
}
ctx := context.Background()
client, err := kms.NewKeyManagementClient(ctx, opts...)
if err != nil {
return nil, err

View File

@@ -1,6 +1,7 @@
package gcpkms
import (
"context"
"encoding/base64"
"fmt"
"net"
@@ -155,7 +156,7 @@ func TestMasterKey_createCloudKMSService_withCredentialsFile(t *testing.T) {
}
for _, tt := range tests {
_, err := tt.key.newKMSClient()
_, err := tt.key.newKMSClient(context.Background())
if tt.errString != "" {
assert.Error(t, err)
assert.ErrorContains(t, err, tt.errString)
@@ -172,7 +173,7 @@ func TestMasterKey_createCloudKMSService_withOauthToken(t *testing.T) {
ResourceID: testResourceID,
}
_, err := masterKey.newKMSClient()
_, err := masterKey.newKMSClient(context.Background())
assert.NoError(t, err)
}
@@ -182,7 +183,7 @@ func TestMasterKey_createCloudKMSService_withoutCredentials(t *testing.T) {
ResourceID: testResourceID,
}
_, err := masterKey.newKMSClient()
_, err := masterKey.newKMSClient(context.Background())
assert.Error(t, err)
assert.ErrorContains(t, err, "credentials: could not find default credentials")

View File

@@ -2,6 +2,7 @@ package hcvault
import (
"bytes"
"context"
"encoding/base64"
"errors"
"fmt"
@@ -130,7 +131,15 @@ func NewMasterKey(address, enginePath, keyName string) *MasterKey {
// Encrypt takes a SOPS data key, encrypts it with Vault Transit, and stores
// the result in the EncryptedKey field.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
return key.EncryptContext(context.Background(), dataKey)
}
// EncryptContext takes a SOPS data key, encrypts it with Vault Transit, and stores
// the result in the EncryptedKey field.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
fullPath := key.encryptPath()
client, err := vaultClient(key.VaultAddress, key.token)
@@ -139,7 +148,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
return err
}
secret, err := client.Logical().Write(fullPath, encryptPayload(dataKey))
secret, err := client.Logical().WriteWithContext(ctx, fullPath, encryptPayload(dataKey))
if err != nil {
log.WithField("Path", fullPath).Info("Encryption failed")
return fmt.Errorf("failed to encrypt sops data key to Vault transit backend '%s': %w", fullPath, err)
@@ -175,7 +184,14 @@ func (key *MasterKey) SetEncryptedDataKey(enc []byte) {
}
// Decrypt decrypts the EncryptedKey field with Vault Transit and returns the result.
//
// Consider using DecryptContext instead.
func (key *MasterKey) Decrypt() ([]byte, error) {
return key.DecryptContext(context.Background())
}
// DecryptContext decrypts the EncryptedKey field with Vault Transit and returns the result.
func (key *MasterKey) DecryptContext(ctx context.Context) ([]byte, error) {
fullPath := key.decryptPath()
client, err := vaultClient(key.VaultAddress, key.token)
@@ -184,7 +200,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
return nil, err
}
secret, err := client.Logical().Write(fullPath, decryptPayload(key.EncryptedKey))
secret, err := client.Logical().WriteWithContext(ctx, fullPath, decryptPayload(key.EncryptedKey))
if err != nil {
log.WithField("Path", fullPath).Info("Decryption failed")
return nil, fmt.Errorf("failed to decrypt sops data key from Vault transit backend '%s': %w", fullPath, err)

View File

@@ -235,8 +235,16 @@ func (c CredentialsProvider) ApplyToMasterKey(key *MasterKey) {
// Encrypt takes a SOPS data key, encrypts it with KMS and stores the result
// in the EncryptedKey field.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
cfg, err := key.createKMSConfig()
return key.EncryptContext(context.Background(), dataKey)
}
// EncryptContext takes a SOPS data key, encrypts it with KMS and stores the result
// in the EncryptedKey field.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
cfg, err := key.createKMSConfig(ctx)
if err != nil {
log.WithField("arn", key.Arn).Info("Encryption failed")
return err
@@ -247,7 +255,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
Plaintext: dataKey,
EncryptionContext: stringPointerToStringMap(key.EncryptionContext),
}
out, err := client.Encrypt(context.TODO(), input)
out, err := client.Encrypt(ctx, input)
if err != nil {
log.WithField("arn", key.Arn).Info("Encryption failed")
return fmt.Errorf("failed to encrypt sops data key with AWS KMS: %w", err)
@@ -278,13 +286,21 @@ func (key *MasterKey) SetEncryptedDataKey(enc []byte) {
// Decrypt decrypts the EncryptedKey with a newly created AWS KMS config, and
// returns the result.
//
// Consider using DecryptContext instead.
func (key *MasterKey) Decrypt() ([]byte, error) {
return key.DecryptContext(context.Background())
}
// DecryptContext decrypts the EncryptedKey with a newly created AWS KMS config, and
// returns the result.
func (key *MasterKey) DecryptContext(ctx context.Context) ([]byte, error) {
k, err := base64.StdEncoding.DecodeString(key.EncryptedKey)
if err != nil {
log.WithField("arn", key.Arn).Info("Decryption failed")
return nil, fmt.Errorf("error base64-decoding encrypted data key: %s", err)
}
cfg, err := key.createKMSConfig()
cfg, err := key.createKMSConfig(ctx)
if err != nil {
log.WithField("arn", key.Arn).Info("Decryption failed")
return nil, err
@@ -295,7 +311,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
CiphertextBlob: k,
EncryptionContext: stringPointerToStringMap(key.EncryptionContext),
}
decrypted, err := client.Decrypt(context.TODO(), input)
decrypted, err := client.Decrypt(ctx, input)
if err != nil {
log.WithField("arn", key.Arn).Info("Decryption failed")
return nil, fmt.Errorf("failed to decrypt sops data key with AWS KMS: %w", err)
@@ -351,7 +367,7 @@ func (key *MasterKey) TypeToIdentifier() string {
// createKMSConfig returns an AWS config with the credentialsProvider of the
// MasterKey, or the default configuration sources.
func (key MasterKey) createKMSConfig() (*aws.Config, error) {
func (key MasterKey) createKMSConfig(ctx context.Context) (*aws.Config, error) {
re := regexp.MustCompile(arnRegex)
matches := re.FindStringSubmatch(key.Arn)
if matches == nil {
@@ -359,7 +375,7 @@ func (key MasterKey) createKMSConfig() (*aws.Config, error) {
}
region := matches[1]
cfg, err := config.LoadDefaultConfig(context.TODO(), func(lo *config.LoadOptions) error {
cfg, err := config.LoadDefaultConfig(ctx, func(lo *config.LoadOptions) error {
// Use the credentialsProvider if present, otherwise default to reading credentials
// from the environment.
if key.credentialsProvider != nil {
@@ -376,7 +392,7 @@ func (key MasterKey) createKMSConfig() (*aws.Config, error) {
}
if key.Role != "" {
return key.createSTSConfig(&cfg)
return key.createSTSConfig(ctx, &cfg)
}
return &cfg, nil
}
@@ -393,7 +409,7 @@ func (key MasterKey) createClient(config *aws.Config) *kms.Client {
// createSTSConfig uses AWS STS to assume a role and returns a config
// configured with that role's credentials. It returns an error if
// it fails to construct a session name, or assume the role.
func (key MasterKey) createSTSConfig(config *aws.Config) (*aws.Config, error) {
func (key MasterKey) createSTSConfig(ctx context.Context, config *aws.Config) (*aws.Config, error) {
name, err := stsSessionName()
if err != nil {
return nil, err
@@ -404,7 +420,7 @@ func (key MasterKey) createSTSConfig(config *aws.Config) (*aws.Config, error) {
}
client := sts.NewFromConfig(*config)
out, err := client.AssumeRole(context.TODO(), input)
out, err := client.AssumeRole(ctx, input)
if err != nil {
return nil, fmt.Errorf("failed to assume role '%s': %w", key.Role, err)
}

View File

@@ -535,7 +535,7 @@ aws_secret_access_key = test-secret`), 0600))
if tt.envFunc != nil {
tt.envFunc(t)
}
cfg, err := tt.key.createKMSConfig()
cfg, err := tt.key.createKMSConfig(context.Background())
tt.assertFunc(t, cfg, err)
})
}
@@ -549,7 +549,7 @@ func TestMasterKey_createSTSConfig(t *testing.T) {
return
}
key := NewMasterKeyFromArn(dummyARN, nil, "")
cfg, err := key.createSTSConfig(nil)
cfg, err := key.createSTSConfig(context.Background(), nil)
assert.Error(t, err)
assert.ErrorContains(t, err, "failed to construct STS session name")
assert.Nil(t, cfg)
@@ -558,7 +558,7 @@ func TestMasterKey_createSTSConfig(t *testing.T) {
t.Run("role assumption error", func(t *testing.T) {
key := NewMasterKeyFromArn(dummyARN, nil, "")
key.Role = "role"
got, err := key.createSTSConfig(&aws.Config{})
got, err := key.createSTSConfig(context.Background(), &aws.Config{})
assert.Error(t, err)
assert.ErrorContains(t, err, "failed to assume role 'role'")
assert.Nil(t, got)
@@ -629,7 +629,7 @@ func createTestMasterKey(arn string) MasterKey {
// createTestKMSClient creates a new client with the
// aws.EndpointResolverWithOptions set to epResolver.
func createTestKMSClient(key MasterKey) (*kms.Client, error) {
cfg, err := key.createKMSConfig()
cfg, err := key.createKMSConfig(context.Background())
if err != nil {
return nil, err
}

View File

@@ -8,6 +8,7 @@ package pgp // import "github.com/getsops/sops/v3/pgp"
import (
"bytes"
"context"
"encoding/hex"
"errors"
"fmt"
@@ -129,13 +130,22 @@ func NewGnuPGHome() (GnuPGHome, error) {
// Import attempts to import the armored key bytes into the GnuPGHome keyring.
// It returns an error if the GnuPGHome does not pass Validate, or if the
// import failed.
//
// Consider using ImportContext instead.
func (d GnuPGHome) Import(armoredKey []byte) error {
return d.ImportContext(context.Background(), armoredKey)
}
// ImportContext attempts to import the armored key bytes into the GnuPGHome keyring.
// It returns an error if the GnuPGHome does not pass Validate, or if the
// import failed.
func (d GnuPGHome) ImportContext(ctx context.Context, armoredKey []byte) error {
if err := d.Validate(); err != nil {
return fmt.Errorf("cannot import armored key data into GnuPG keyring: %w", err)
}
args := []string{"--batch", "--import"}
_, stderr, err := gpgExec(d.String(), args, bytes.NewReader(armoredKey))
_, stderr, err := gpgExec(ctx, d.String(), args, bytes.NewReader(armoredKey))
if err != nil {
stderrStr := strings.TrimSpace(stderr.String())
errStr := err.Error()
@@ -254,7 +264,15 @@ func (e errSet) Error() string {
// Encrypt encrypts the data key with the PGP key with the same
// fingerprint as the MasterKey.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
return key.EncryptContext(context.Background(), dataKey)
}
// EncryptContext encrypts the data key with the PGP key with the same
// fingerprint as the MasterKey.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
var errs errSet
if !key.disableOpenPGP {
@@ -266,7 +284,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
errs = append(errs, fmt.Errorf("github.com/ProtonMail/go-crypto/openpgp error: %w", openpgpErr))
}
binaryErr := key.encryptWithGnuPG(dataKey)
binaryErr := key.encryptWithGnuPG(ctx, dataKey)
if binaryErr == nil {
log.WithField("fingerprint", key.Fingerprint).Info("Encryption succeeded")
return nil
@@ -320,7 +338,7 @@ func (key *MasterKey) encryptWithOpenPGP(dataKey []byte) error {
// encryptWithOpenPGP attempts to encrypt the data key using GnuPG with the
// PGP key that belongs to Fingerprint. It sets EncryptedDataKey, or returns
// an error.
func (key *MasterKey) encryptWithGnuPG(dataKey []byte) error {
func (key *MasterKey) encryptWithGnuPG(ctx context.Context, dataKey []byte) error {
fingerprint := shortenFingerprint(key.Fingerprint)
args := []string{
@@ -334,7 +352,7 @@ func (key *MasterKey) encryptWithGnuPG(dataKey []byte) error {
fingerprint,
"--no-encrypt-to",
}
stdout, stderr, err := gpgExec(key.gnuPGHomeDir, args, bytes.NewReader(dataKey))
stdout, stderr, err := gpgExec(ctx, key.gnuPGHomeDir, args, bytes.NewReader(dataKey))
if err != nil {
return fmt.Errorf("failed to encrypt sops data key with pgp: %s", strings.TrimSpace(stderr.String()))
}
@@ -365,7 +383,16 @@ func (key *MasterKey) SetEncryptedDataKey(enc []byte) {
// Decrypt first attempts to obtain the data key from the EncryptedKey
// stored in the MasterKey using OpenPGP, before falling back to GnuPG.
// When both attempts fail, an error is returned.
//
// Consider using DecryptContext instead.
func (key *MasterKey) Decrypt() ([]byte, error) {
return key.DecryptContext(context.Background())
}
// DecryptContext first attempts to obtain the data key from the EncryptedKey
// stored in the MasterKey using OpenPGP, before falling back to GnuPG.
// When both attempts fail, an error is returned.
func (key *MasterKey) DecryptContext(ctx context.Context) ([]byte, error) {
var errs errSet
if !key.disableOpenPGP {
@@ -377,7 +404,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
errs = append(errs, fmt.Errorf("github.com/ProtonMail/go-crypto/openpgp error: %w", openpgpErr))
}
dataKey, binaryErr := key.decryptWithGnuPG()
dataKey, binaryErr := key.decryptWithGnuPG(ctx)
if binaryErr == nil {
log.WithField("fingerprint", key.Fingerprint).Info("Decryption succeeded")
return dataKey, nil
@@ -419,11 +446,11 @@ func (key *MasterKey) decryptWithOpenPGP() ([]byte, error) {
// GnuPG and returns the result. If DisableAgent is configured on the MasterKey,
// the GnuPG agent is not enabled. When the decryption command fails, it returns
// the error from stdout.
func (key *MasterKey) decryptWithGnuPG() ([]byte, error) {
func (key *MasterKey) decryptWithGnuPG(ctx context.Context) ([]byte, error) {
args := []string{
"-d",
}
stdout, stderr, err := gpgExec(key.gnuPGHomeDir, args, strings.NewReader(key.EncryptedKey))
stdout, stderr, err := gpgExec(ctx, key.gnuPGHomeDir, args, strings.NewReader(key.EncryptedKey))
if err != nil {
return nil, fmt.Errorf("failed to decrypt sops data key with pgp: %s",
strings.TrimSpace(stderr.String()))
@@ -595,12 +622,12 @@ func fingerprintIndex(ring openpgp.EntityList) map[string]openpgp.Entity {
// gpgExec runs the provided args with the gpgBinary, while restricting it to
// homeDir when provided. Stdout and stderr can be read from the returned
// buffers. When the command fails, an error is returned.
func gpgExec(homeDir string, args []string, stdin io.Reader) (stdout bytes.Buffer, stderr bytes.Buffer, err error) {
func gpgExec(ctx context.Context, homeDir string, args []string, stdin io.Reader) (stdout bytes.Buffer, stderr bytes.Buffer, err error) {
if homeDir != "" {
args = append([]string{"--homedir", homeDir}, args...)
}
cmd := exec.Command(gpgBinary(), args...)
cmd := exec.CommandContext(ctx, gpgBinary(), args...)
cmd.Stdin = stdin
cmd.Stdout = &stdout
cmd.Stderr = &stderr

View File

@@ -2,6 +2,7 @@ package pgp
import (
"bytes"
"context"
"io"
"os"
"os/user"
@@ -56,14 +57,14 @@ func TestGnuPGHome_Import(t *testing.T) {
assert.NoError(t, err)
assert.NoError(t, gnuPGHome.Import(b))
_, stderr, err := gpgExec(gnuPGHome.String(), []string{"--list-keys", mockFingerprint}, nil)
_, stderr, err := gpgExec(context.Background(), gnuPGHome.String(), []string{"--list-keys", mockFingerprint}, nil)
assert.NoErrorf(t, err, stderr.String())
b, err = os.ReadFile(mockPrivateKey)
assert.NoError(t, err)
assert.NoError(t, gnuPGHome.Import(b))
_, stderr, err = gpgExec(gnuPGHome.String(), []string{"--list-secret-keys", mockFingerprint}, nil)
_, stderr, err = gpgExec(context.Background(), gnuPGHome.String(), []string{"--list-secret-keys", mockFingerprint}, nil)
assert.NoErrorf(t, err, stderr.String())
err = gnuPGHome.Import([]byte("invalid armored data"))
@@ -281,7 +282,7 @@ func TestMasterKey_encryptWithGnuPG(t *testing.T) {
key := NewMasterKeyFromFingerprint(mockFingerprint)
gnuPGHome.ApplyToMasterKey(key)
data := []byte("oh no, my darkest secret")
assert.NoError(t, key.encryptWithGnuPG(data))
assert.NoError(t, key.encryptWithGnuPG(context.Background(), data))
assert.NotEmpty(t, key.EncryptedKey)
assert.NotEqual(t, data, key.EncryptedKey)
@@ -291,14 +292,14 @@ func TestMasterKey_encryptWithGnuPG(t *testing.T) {
args := []string{
"-d",
}
stdout, stderr, err := gpgExec(key.gnuPGHomeDir, args, strings.NewReader(key.EncryptedKey))
stdout, stderr, err := gpgExec(context.Background(), key.gnuPGHomeDir, args, strings.NewReader(key.EncryptedKey))
assert.NoError(t, err, stderr.String())
assert.Equal(t, data, stdout.Bytes())
})
t.Run("invalid fingerprint error", func(t *testing.T) {
key := NewMasterKeyFromFingerprint("invalid")
err := key.encryptWithGnuPG([]byte("invalid"))
err := key.encryptWithGnuPG(context.Background(), []byte("invalid"))
assert.Error(t, err)
assert.ErrorContains(t, err, "failed to encrypt sops data key with pgp: gpg: 'invalid' is not a valid long keyID")
})
@@ -341,7 +342,7 @@ func TestMasterKey_Decrypt(t *testing.T) {
fingerprint := shortenFingerprint(mockFingerprint)
data := []byte("this data is absolutely top secret")
stdout, stderr, err := gpgExec(gnuPGHome.String(), []string{
stdout, stderr, err := gpgExec(context.Background(), gnuPGHome.String(), []string{
"--no-default-recipient",
"--yes",
"--encrypt",
@@ -424,7 +425,7 @@ func TestMasterKey_decryptWithOpenPGP(t *testing.T) {
fingerprint := shortenFingerprint(mockFingerprint)
data := []byte("this data is absolutely top secret")
stdout, stderr, err := gpgExec(gnuPGHome.String(), []string{
stdout, stderr, err := gpgExec(context.Background(), gnuPGHome.String(), []string{
"--no-default-recipient",
"--yes",
"--encrypt",
@@ -473,7 +474,7 @@ func TestMasterKey_decryptWithGnuPG(t *testing.T) {
fingerprint := shortenFingerprint(mockFingerprint)
data := []byte("this data is absolutely top secret")
stdout, stderr, err := gpgExec(gnuPGHome.String(), []string{
stdout, stderr, err := gpgExec(context.Background(), gnuPGHome.String(), []string{
"--no-default-recipient",
"--yes",
"--encrypt",
@@ -494,7 +495,7 @@ func TestMasterKey_decryptWithGnuPG(t *testing.T) {
gnuPGHome.ApplyToMasterKey(key)
key.EncryptedKey = encryptedData
got, err := key.decryptWithGnuPG()
got, err := key.decryptWithGnuPG(context.Background())
assert.NoError(t, err)
assert.Equal(t, data, got)
})
@@ -502,7 +503,7 @@ func TestMasterKey_decryptWithGnuPG(t *testing.T) {
t.Run("invalid data error", func(t *testing.T) {
key := NewMasterKeyFromFingerprint(mockFingerprint)
key.EncryptedKey = "absolute invalid"
got, err := key.decryptWithGnuPG()
got, err := key.decryptWithGnuPG(context.Background())
assert.Error(t, err)
assert.ErrorContains(t, err, "gpg: no valid OpenPGP data found")
assert.Nil(t, got)