summaryrefslogtreecommitdiff
path: root/internal/configfile/validate.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-08-21 21:43:26 +0200
committerJakob Unterwurzacher2021-08-23 16:00:41 +0200
commit97d8340bd81ddd60baac598d3e25ebfb4decb50c (patch)
tree2f5444d523ca142e847b0b51422bc51ad8203a75 /internal/configfile/validate.go
parent4764a9bde093f6b61d0370653c6c9d12949ed145 (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.go67
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
+}