summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-11-01 18:43:22 +0100
committerJakob Unterwurzacher2016-11-01 18:43:22 +0100
commit2b991c9743caa5edf38fbcdadb129ca61ffa702f (patch)
tree307059774772110a6aa63fbd35e00ac2747ab4f9 /internal
parent964e0e6b3634973fb9512858b4ae8707c825aaaf (diff)
Add support for unpadded base64 filenames, "-raw64"
Through base64.RawURLEncoding. New command-line parameter "-raw64".
Diffstat (limited to 'internal')
-rw-r--r--internal/configfile/config_file.go5
-rw-r--r--internal/configfile/config_test.go19
-rw-r--r--internal/configfile/feature_flags.go3
-rw-r--r--internal/fusefrontend/args.go3
-rw-r--r--internal/fusefrontend/fs.go2
-rw-r--r--internal/fusefrontend_reverse/rfs.go2
-rw-r--r--internal/nametransform/names.go13
7 files changed, 38 insertions, 9 deletions
diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go
index 603f276..0bee16f 100644
--- a/internal/configfile/config_file.go
+++ b/internal/configfile/config_file.go
@@ -49,7 +49,7 @@ type ConfFile struct {
// CreateConfFile - create a new config with a random key encrypted with
// "password" and write it to "filename".
// Uses scrypt with cost parameter logN.
-func CreateConfFile(filename string, password string, plaintextNames bool, logN int, creator string, aessiv bool) error {
+func CreateConfFile(filename string, password string, plaintextNames bool, logN int, creator string, aessiv bool, raw64 bool) error {
var cf ConfFile
cf.filename = filename
cf.Creator = creator
@@ -70,6 +70,9 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagDirIV])
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagEMENames])
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagLongNames])
+ if raw64 {
+ cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagRaw64])
+ }
}
if aessiv {
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV])
diff --git a/internal/configfile/config_test.go b/internal/configfile/config_test.go
index 81984fe..f993803 100644
--- a/internal/configfile/config_test.go
+++ b/internal/configfile/config_test.go
@@ -60,7 +60,7 @@ func TestLoadV2StrangeFeature(t *testing.T) {
}
func TestCreateConfFile(t *testing.T) {
- err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", false)
+ err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", false, false)
if err != nil {
t.Fatal(err)
}
@@ -68,11 +68,10 @@ func TestCreateConfFile(t *testing.T) {
if err != nil {
t.Fatal(err)
}
-
}
func TestCreateConfFileAESSIV(t *testing.T) {
- err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", true)
+ err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", true, false)
if err != nil {
t.Fatal(err)
}
@@ -85,6 +84,20 @@ func TestCreateConfFileAESSIV(t *testing.T) {
}
}
+func TestCreateConfFileRaw64(t *testing.T) {
+ err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", false, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, c, err := LoadConfFile("config_test/tmp.conf", "test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !c.IsFeatureFlagSet(FlagRaw64) {
+ t.Error("FlagRaw64 flag should be set but is not")
+ }
+}
+
func TestIsFeatureFlagKnown(t *testing.T) {
// Test a few hardcoded values
testKnownFlags := []string{"DirIV", "PlaintextNames", "EMENames", "GCMIV128", "LongNames", "AESSIV"}
diff --git a/internal/configfile/feature_flags.go b/internal/configfile/feature_flags.go
index d3601b1..8d4aa6e 100644
--- a/internal/configfile/feature_flags.go
+++ b/internal/configfile/feature_flags.go
@@ -17,6 +17,8 @@ const (
FlagLongNames
// FlagAESSIV selects an AES-SIV based crypto backend.
FlagAESSIV
+ // FlagRaw64 enables raw (unpadded) base64 encoding for file names
+ FlagRaw64
)
// knownFlags stores the known feature flags and their string representation
@@ -27,6 +29,7 @@ var knownFlags = map[flagIota]string{
FlagGCMIV128: "GCMIV128",
FlagLongNames: "LongNames",
FlagAESSIV: "AESSIV",
+ FlagRaw64: "Raw64",
}
// Filesystems that do not have these feature flags set are deprecated.
diff --git a/internal/fusefrontend/args.go b/internal/fusefrontend/args.go
index 204647d..d8b0304 100644
--- a/internal/fusefrontend/args.go
+++ b/internal/fusefrontend/args.go
@@ -18,4 +18,7 @@ type Args struct {
// location. If it is false, reverse mode maps ".gocryptfs.reverse.conf"
// to "gocryptfs.conf" in the plaintext dir.
ConfigCustom bool
+ // Raw64 is true when RawURLEncoding (without padding) should be used for
+ // file names
+ Raw64 bool
}
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go
index 33053de..e9e6113 100644
--- a/internal/fusefrontend/fs.go
+++ b/internal/fusefrontend/fs.go
@@ -42,7 +42,7 @@ var _ pathfs.FileSystem = &FS{} // Verify that interface is implemented.
func NewFS(args Args) *FS {
cryptoCore := cryptocore.New(args.Masterkey, args.CryptoBackend, contentenc.DefaultIVBits)
contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS)
- nameTransform := nametransform.New(cryptoCore, args.LongNames)
+ nameTransform := nametransform.New(cryptoCore, args.LongNames, args.Raw64)
return &FS{
FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),
diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go
index 35e9e50..87a2602 100644
--- a/internal/fusefrontend_reverse/rfs.go
+++ b/internal/fusefrontend_reverse/rfs.go
@@ -56,7 +56,7 @@ func NewFS(args fusefrontend.Args) pathfs.FileSystem {
initLongnameCache()
cryptoCore := cryptocore.New(args.Masterkey, args.CryptoBackend, contentenc.DefaultIVBits)
contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS)
- nameTransform := nametransform.New(cryptoCore, args.LongNames)
+ nameTransform := nametransform.New(cryptoCore, args.LongNames, args.Raw64)
return &reverseFS{
// pathfs.defaultFileSystem returns ENOSYS for all operations
diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go
index 05ae75e..9b1639f 100644
--- a/internal/nametransform/names.go
+++ b/internal/nametransform/names.go
@@ -17,13 +17,20 @@ type NameTransform struct {
cryptoCore *cryptocore.CryptoCore
longNames bool
DirIVCache dirIVCache
+ // b64 = either base64.URLEncoding or base64.RawURLEncoding
+ b64 *base64.Encoding
}
// New returns a new NameTransform instance.
-func New(c *cryptocore.CryptoCore, longNames bool) *NameTransform {
+func New(c *cryptocore.CryptoCore, longNames bool, raw64 bool) *NameTransform {
+ b64 := base64.URLEncoding
+ if raw64 {
+ b64 = base64.RawURLEncoding
+ }
return &NameTransform{
cryptoCore: c,
longNames: longNames,
+ b64: b64,
}
}
@@ -32,7 +39,7 @@ func New(c *cryptocore.CryptoCore, longNames bool) *NameTransform {
// This function is exported because it allows for a very efficient readdir
// implementation (read IV once, decrypt all names using this function).
func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error) {
- bin, err := base64.URLEncoding.DecodeString(cipherName)
+ bin, err := n.b64.DecodeString(cipherName)
if err != nil {
return "", err
}
@@ -63,6 +70,6 @@ func (n *NameTransform) EncryptName(plainName string, iv []byte) (cipherName64 s
bin := []byte(plainName)
bin = pad16(bin)
bin = eme.Transform(n.cryptoCore.BlockCipher, iv, bin, eme.DirectionEncrypt)
- cipherName64 = base64.URLEncoding.EncodeToString(bin)
+ cipherName64 = n.b64.EncodeToString(bin)
return cipherName64
}