Fix missing-key errors for restore and deep verify to name both key sources (closes #401)
check / check (push) Successful in 10m21s
check / check (push) Successful in 10m21s
The missing-key error for restore and deep verify is one value, errDecryptionKeyRequired, whose text names both places the key can be set: the VAULTIK_AGE_SECRET_KEY environment variable first, then the age_secret_key config file field. Model: deepseek-v4-pro
This commit is contained in:
1 parent
5abacbc5c1
commit
301e408bd3
3 files changed
+26
-13
No files matched your search
@@ -31,10 +31,9 @@ var (
|
|||||||
errPathsNotInSnapshot = errors.New("requested path(s) not in the snapshot")
|
errPathsNotInSnapshot = errors.New("requested path(s) not in the snapshot")
|
||||||
errFilesFailedVerify = errors.New("files failed verification")
|
errFilesFailedVerify = errors.New("files failed verification")
|
||||||
errDecryptionKeyRequired = errors.New(
|
errDecryptionKeyRequired = errors.New(
|
||||||
"decryption key required for restore\n\n" +
|
"age secret key is missing; set it in the " +
|
||||||
"Set the VAULTIK_AGE_SECRET_KEY environment variable to your " +
|
"VAULTIK_AGE_SECRET_KEY environment variable or the " +
|
||||||
"age private key file:\n" +
|
"age_secret_key config file field")
|
||||||
" export VAULTIK_AGE_SECRET_KEY=\"$(cat vaultik_backup_private_key.txt)\"")
|
|
||||||
// errInvalidAgeSecretKey is returned when the configured key does not
|
// errInvalidAgeSecretKey is returned when the configured key does not
|
||||||
// parse as any age identity. It names the source but never the value,
|
// 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.
|
// which is secret, so the message is safe to print and log.
|
||||||
|
|||||||
@@ -106,3 +106,23 @@ func TestRestoreIdentitiesMissingKey(t *testing.T) {
|
|||||||
_, err := v.restoreIdentities()
|
_, err := v.restoreIdentities()
|
||||||
require.ErrorIs(t, err, errDecryptionKeyRequired)
|
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.Equal(t, want, err.Error())
|
||||||
|
|
||||||
|
err = v.RunDeepVerify("any-snapshot", &VerifyOptions{})
|
||||||
|
require.Equal(t, want, err.Error())
|
||||||
|
}
|
||||||
@@ -22,9 +22,7 @@ import (
|
|||||||
|
|
||||||
// Sentinel errors for snapshot verification failures.
|
// Sentinel errors for snapshot verification failures.
|
||||||
var (
|
var (
|
||||||
errVerificationFailed = errors.New("verification failed")
|
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")
|
errChunksOutOfOrder = errors.New("chunks out of order")
|
||||||
errChunkHashMismatch = errors.New("chunk hash mismatch")
|
errChunkHashMismatch = errors.New("chunk hash mismatch")
|
||||||
errNegativeChunkLength = errors.New("chunk length is negative")
|
errNegativeChunkLength = errors.New("chunk length is negative")
|
||||||
@@ -106,13 +104,9 @@ func (v *Vaultik) RunDeepVerify(snapshotID string, opts *VerifyOptions) error {
|
|||||||
Mode: "deep",
|
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
|
// 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()
|
identities, err := v.restoreIdentities()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v.deepVerifyFailure(result, opts, err.Error(), err)
|
return v.deepVerifyFailure(result, opts, err.Error(), err)
|
||||||
|
|||||||
Reference in new issue
Block a user