Missing-key errors for restore and deep verify name both key sources (closes #401) #406
No files matched your search
@@ -31,10 +31,9 @@ var (
|
||||
errPathsNotInSnapshot = errors.New("requested path(s) not in the snapshot")
|
||||
errFilesFailedVerify = errors.New("files failed verification")
|
||||
errDecryptionKeyRequired = errors.New(
|
||||
"decryption key required for restore\n\n" +
|
||||
"Set the VAULTIK_AGE_SECRET_KEY environment variable to your " +
|
||||
"age private key file:\n" +
|
||||
" export VAULTIK_AGE_SECRET_KEY=\"$(cat vaultik_backup_private_key.txt)\"")
|
||||
"age secret key is missing; set it in the " +
|
||||
"VAULTIK_AGE_SECRET_KEY environment variable or the " +
|
||||
"age_secret_key config file field")
|
||||
// errInvalidAgeSecretKey is returned when the configured key does not
|
||||
// parse as any age identity. It names the source but never the value,
|
||||
// which is secret, so the message is safe to print and log.
|
||||
|
||||
@@ -106,3 +106,23 @@ func TestRestoreIdentitiesMissingKey(t *testing.T) {
|
||||
_, err := v.restoreIdentities()
|
||||
require.ErrorIs(t, err, errDecryptionKeyRequired)
|
||||
}
|
||||
|
||||
// TestMissingKeyErrorsNameBothSources asserts restore and deep verify
|
||||
// return the same missing-key error, whose text names both places the key
|
||||
// can be set: the VAULTIK_AGE_SECRET_KEY environment variable first since
|
||||
// it is preferred, then the age_secret_key config file field.
|
||||
func TestMissingKeyErrorsNameBothSources(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const want = "age secret key is missing; set it in " +
|
||||
"the VAULTIK_AGE_SECRET_KEY environment variable or the " +
|
||||
"age_secret_key config file field"
|
||||
|
||||
v := &Vaultik{Config: &config.Config{}}
|
||||
|
||||
_, err := v.restoreIdentities()
|
||||
require.EqualError(t, err, want)
|
||||
|
||||
err = v.RunDeepVerify("any-snapshot", &VerifyOptions{})
|
||||
require.EqualError(t, err, want)
|
||||
}
|
||||
@@ -162,11 +162,6 @@ func (v *Vaultik) StartOperation(fn func()) func(context.Context) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// CanDecrypt returns true if this Vaultik instance has decryption capabilities
|
||||
func (v *Vaultik) CanDecrypt() bool {
|
||||
return v.Config.AgeSecretKey != ""
|
||||
}
|
||||
|
||||
// GetFilesystem returns the filesystem instance used by Vaultik
|
||||
//
|
||||
//nolint:ireturn // afero.Fs is the filesystem abstraction by design
|
||||
|
||||
@@ -23,8 +23,6 @@ import (
|
||||
// Sentinel errors for snapshot verification failures.
|
||||
var (
|
||||
errVerificationFailed = errors.New("verification failed")
|
||||
errSecretKeyRequired = errors.New(
|
||||
"VAULTIK_AGE_SECRET_KEY not set; required for deep verification")
|
||||
errChunksOutOfOrder = errors.New("chunks out of order")
|
||||
errChunkHashMismatch = errors.New("chunk hash mismatch")
|
||||
errNegativeChunkLength = errors.New("chunk length is negative")
|
||||
@@ -106,13 +104,9 @@ func (v *Vaultik) RunDeepVerify(snapshotID string, opts *VerifyOptions) error {
|
||||
Mode: "deep",
|
||||
}
|
||||
|
||||
if !v.CanDecrypt() {
|
||||
return v.deepVerifyFailure(result, opts,
|
||||
errSecretKeyRequired.Error(), errSecretKeyRequired)
|
||||
}
|
||||
|
||||
// Parse the age secret key once, the same way restore does, and reuse
|
||||
// the identities for the database and every blob.
|
||||
// the identities for the database and every blob. A missing key fails
|
||||
// here, before anything is downloaded.
|
||||
identities, err := v.restoreIdentities()
|
||||
if err != nil {
|
||||
return v.deepVerifyFailure(result, opts, err.Error(), err)
|
||||
|
||||
Reference in new issue
Block a user