diff --git a/internal/vault/vault.go b/internal/vault/vault.go index 9d11ae48..e49b4acb 100644 --- a/internal/vault/vault.go +++ b/internal/vault/vault.go @@ -223,9 +223,13 @@ func newVault(path, gluonDir string, gcm cipher.AEAD) (*Vault, bool, error) { var corrupt bool - if _, err := decrypt(gcm, enc); err != nil { + if dec, err := decrypt(gcm, enc); err != nil { corrupt = true + } else if err := msgpack.Unmarshal(dec, new(Data)); err != nil { + corrupt = true + } + if corrupt { newEnc, err := initVault(path, gluonDir, gcm) if err != nil { return nil, false, err diff --git a/internal/vault/vault_test.go b/internal/vault/vault_test.go index 5f69d9c4..1c61a047 100644 --- a/internal/vault/vault_test.go +++ b/internal/vault/vault_test.go @@ -18,13 +18,15 @@ package vault_test import ( + "os" + "path/filepath" "testing" "github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/stretchr/testify/require" ) -func TestVaultCorrupt(t *testing.T) { +func TestVault_Corrupt(t *testing.T) { vaultDir, gluonDir := t.TempDir(), t.TempDir() { @@ -46,6 +48,35 @@ func TestVaultCorrupt(t *testing.T) { } } +func TestVault_Corrupt_JunkData(t *testing.T) { + vaultDir, gluonDir := t.TempDir(), t.TempDir() + + { + _, corrupt, err := vault.New(vaultDir, gluonDir, []byte("my secret key")) + require.NoError(t, err) + require.False(t, corrupt) + } + + { + _, corrupt, err := vault.New(vaultDir, gluonDir, []byte("my secret key")) + require.NoError(t, err) + require.False(t, corrupt) + } + + { + f, err := os.OpenFile(filepath.Join(vaultDir, "vault.enc"), os.O_WRONLY, 0o600) + require.NoError(t, err) + defer f.Close() //nolint:errcheck + + _, err = f.Write([]byte("junk data")) + require.NoError(t, err) + + _, corrupt, err := vault.New(vaultDir, gluonDir, []byte("my secret key")) + require.NoError(t, err) + require.True(t, corrupt) + } +} + func newVault(t *testing.T) *vault.Vault { t.Helper()