diff options
author | Jakob Unterwurzacher | 2021-08-21 21:43:26 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2021-08-23 16:00:41 +0200 |
commit | 97d8340bd81ddd60baac598d3e25ebfb4decb50c (patch) | |
tree | 2f5444d523ca142e847b0b51422bc51ad8203a75 /internal/configfile/validate.go | |
parent | 4764a9bde093f6b61d0370653c6c9d12949ed145 (diff) |
configfile: add Validate() function, support FlagXChaCha20Poly1305
We used to do validation using lists of mandatory feature flags.
With the introduction of XChaCha20Poly1305, this became too
simplistic, as it uses a different IV length, hence disabling
GCMIV128.
Add a dedicated function, Validate(), with open-coded validation
logic.
The validation and creation logic also gets XChaCha20Poly1305
support, and gocryptfs -init -xchacha now writes the flag into
gocryptfs.conf.
Diffstat (limited to 'internal/configfile/validate.go')
-rw-r--r-- | internal/configfile/validate.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/internal/configfile/validate.go b/internal/configfile/validate.go new file mode 100644 index 0000000..511f704 --- /dev/null +++ b/internal/configfile/validate.go @@ -0,0 +1,67 @@ +package configfile + +import ( + "fmt" + + "github.com/rfjakob/gocryptfs/v2/internal/contentenc" +) + +// Validate that the combination of settings makes sense and is supported +func (cf *ConfFile) Validate() error { + if cf.Version != contentenc.CurrentVersion { + return fmt.Errorf("Unsupported on-disk format %d", cf.Version) + } + // scrypt params ok? + if err := cf.ScryptObject.validateParams(); err != nil { + return err + } + // All feature flags that are in the config file are known? + for _, flag := range cf.FeatureFlags { + if !isFeatureFlagKnown(flag) { + return fmt.Errorf("Unknown feature flag %q", flag) + } + } + // File content encryption + { + switch { + case cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && cf.IsFeatureFlagSet(FlagAESSIV): + return fmt.Errorf("Can't have both XChaCha20Poly1305 and AESSIV feature flags") + case cf.IsFeatureFlagSet(FlagAESSIV): + if !cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("AESSIV requires GCMIV128 feature flag") + } + case cf.IsFeatureFlagSet(FlagXChaCha20Poly1305): + if cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("XChaCha20Poly1305 conflicts with GCMIV128 feature flag") + } + if !cf.IsFeatureFlagSet(FlagHKDF) { + return fmt.Errorf("XChaCha20Poly1305 requires HKDF feature flag") + } + // The absence of other flags means AES-GCM (oldest algorithm) + case !cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && !cf.IsFeatureFlagSet(FlagAESSIV): + if !cf.IsFeatureFlagSet(FlagGCMIV128) { + return fmt.Errorf("AES-GCM requires GCMIV128 feature flag") + } + } + } + // Filename encryption + { + switch { + case cf.IsFeatureFlagSet(FlagPlaintextNames) && cf.IsFeatureFlagSet(FlagEMENames): + return fmt.Errorf("Can't have both PlaintextNames and EMENames feature flags") + case cf.IsFeatureFlagSet(FlagPlaintextNames): + if cf.IsFeatureFlagSet(FlagDirIV) { + return fmt.Errorf("PlaintextNames conflicts with DirIV feature flag") + } + if cf.IsFeatureFlagSet(FlagLongNames) { + return fmt.Errorf("PlaintextNames conflicts with LongNames feature flag") + } + if cf.IsFeatureFlagSet(FlagRaw64) { + return fmt.Errorf("PlaintextNames conflicts with Raw64 feature flag") + } + case cf.IsFeatureFlagSet(FlagEMENames): + // All combinations of DirIV, LongNames, Raw64 allowed + } + } + return nil +} |