libgocryptfs: update to gocryptfs v2.3
This commit is contained in:
commit
27232cbdb7
11
go.mod
11
go.mod
@ -1,14 +1,17 @@
|
|||||||
module libgocryptfs/v2
|
module libgocryptfs/v2
|
||||||
|
|
||||||
go 1.16
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115
|
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115
|
||||||
|
github.com/rfjakob/eme v1.1.2
|
||||||
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||||
|
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect
|
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect
|
||||||
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect
|
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect
|
||||||
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 // indirect
|
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 // indirect
|
||||||
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect
|
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect
|
||||||
github.com/rfjakob/eme v1.1.2
|
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
|
|
||||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9
|
|
||||||
)
|
)
|
||||||
|
15
go.sum
15
go.sum
@ -10,15 +10,8 @@ github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb h1:uSWBjJdMf47kQl
|
|||||||
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4=
|
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4=
|
||||||
github.com/rfjakob/eme v1.1.2 h1:SxziR8msSOElPayZNFfQw4Tjx/Sbaeeh3eRvrHVMUs4=
|
github.com/rfjakob/eme v1.1.2 h1:SxziR8msSOElPayZNFfQw4Tjx/Sbaeeh3eRvrHVMUs4=
|
||||||
github.com/rfjakob/eme v1.1.2/go.mod h1:cVvpasglm/G3ngEfcfT/Wt0GwhkuO32pf/poW6Nyk1k=
|
github.com/rfjakob/eme v1.1.2/go.mod h1:cVvpasglm/G3ngEfcfT/Wt0GwhkuO32pf/poW6Nyk1k=
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
|
|
||||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
|
@ -54,6 +54,8 @@ type ConfFile struct {
|
|||||||
FeatureFlags []string
|
FeatureFlags []string
|
||||||
// FIDO2 parameters
|
// FIDO2 parameters
|
||||||
FIDO2 *FIDO2Params `json:",omitempty"`
|
FIDO2 *FIDO2Params `json:",omitempty"`
|
||||||
|
// LongNameMax corresponds to the -longnamemax flag
|
||||||
|
LongNameMax uint8 `json:",omitempty"`
|
||||||
// Filename is the name of the config file. Not exported to JSON.
|
// Filename is the name of the config file. Not exported to JSON.
|
||||||
filename string
|
filename string
|
||||||
}
|
}
|
||||||
@ -68,6 +70,7 @@ type CreateArgs struct {
|
|||||||
AESSIV bool
|
AESSIV bool
|
||||||
DeterministicNames bool
|
DeterministicNames bool
|
||||||
XChaCha20Poly1305 bool
|
XChaCha20Poly1305 bool
|
||||||
|
LongNameMax uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create - create a new config with a random key encrypted with
|
// Create - create a new config with a random key encrypted with
|
||||||
@ -94,6 +97,12 @@ func Create(args *CreateArgs, returnedScryptHashBuff []byte) error {
|
|||||||
if !args.DeterministicNames {
|
if !args.DeterministicNames {
|
||||||
cf.setFeatureFlag(FlagDirIV)
|
cf.setFeatureFlag(FlagDirIV)
|
||||||
}
|
}
|
||||||
|
// 0 means to *use* the default (which means we don't have to save it), and
|
||||||
|
// 255 *is* the default, which means we don't have to save it either.
|
||||||
|
if args.LongNameMax != 0 && args.LongNameMax != 255 {
|
||||||
|
cf.LongNameMax = args.LongNameMax
|
||||||
|
cf.setFeatureFlag(FlagLongNameMax)
|
||||||
|
}
|
||||||
cf.setFeatureFlag(FlagEMENames)
|
cf.setFeatureFlag(FlagEMENames)
|
||||||
cf.setFeatureFlag(FlagLongNames)
|
cf.setFeatureFlag(FlagLongNames)
|
||||||
cf.setFeatureFlag(FlagRaw64)
|
cf.setFeatureFlag(FlagRaw64)
|
||||||
|
@ -14,8 +14,11 @@ const (
|
|||||||
// This flag is mandatory since gocryptfs v1.0,
|
// This flag is mandatory since gocryptfs v1.0,
|
||||||
// except when XChaCha20Poly1305 is used.
|
// except when XChaCha20Poly1305 is used.
|
||||||
FlagGCMIV128
|
FlagGCMIV128
|
||||||
// FlagLongNames allows file names longer than 176 bytes.
|
// FlagLongNames allows file names longer than 175 bytes.
|
||||||
FlagLongNames
|
FlagLongNames
|
||||||
|
// FlagLongNameMax sets a custom name length limit, names longer than that
|
||||||
|
// will be hashed.
|
||||||
|
FlagLongNameMax
|
||||||
// FlagAESSIV selects an AES-SIV based crypto backend.
|
// FlagAESSIV selects an AES-SIV based crypto backend.
|
||||||
FlagAESSIV
|
FlagAESSIV
|
||||||
// FlagRaw64 enables raw (unpadded) base64 encoding for file names
|
// FlagRaw64 enables raw (unpadded) base64 encoding for file names
|
||||||
@ -40,6 +43,7 @@ var knownFlags = map[flagIota]string{
|
|||||||
FlagEMENames: "EMENames",
|
FlagEMENames: "EMENames",
|
||||||
FlagGCMIV128: "GCMIV128",
|
FlagGCMIV128: "GCMIV128",
|
||||||
FlagLongNames: "LongNames",
|
FlagLongNames: "LongNames",
|
||||||
|
FlagLongNameMax: "LongNameMax",
|
||||||
FlagAESSIV: "AESSIV",
|
FlagAESSIV: "AESSIV",
|
||||||
FlagRaw64: "Raw64",
|
FlagRaw64: "Raw64",
|
||||||
FlagHKDF: "HKDF",
|
FlagHKDF: "HKDF",
|
||||||
|
@ -23,22 +23,23 @@ func (cf *ConfFile) Validate() error {
|
|||||||
}
|
}
|
||||||
// File content encryption
|
// File content encryption
|
||||||
{
|
{
|
||||||
switch {
|
if cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && cf.IsFeatureFlagSet(FlagAESSIV) {
|
||||||
case cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && cf.IsFeatureFlagSet(FlagAESSIV):
|
|
||||||
return fmt.Errorf("Can't have both XChaCha20Poly1305 and AESSIV feature flags")
|
return fmt.Errorf("Can't have both XChaCha20Poly1305 and AESSIV feature flags")
|
||||||
case cf.IsFeatureFlagSet(FlagAESSIV):
|
}
|
||||||
if !cf.IsFeatureFlagSet(FlagGCMIV128) {
|
if cf.IsFeatureFlagSet(FlagAESSIV) && !cf.IsFeatureFlagSet(FlagGCMIV128) {
|
||||||
|
|
||||||
return fmt.Errorf("AESSIV requires GCMIV128 feature flag")
|
return fmt.Errorf("AESSIV requires GCMIV128 feature flag")
|
||||||
}
|
}
|
||||||
case cf.IsFeatureFlagSet(FlagXChaCha20Poly1305):
|
if cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) {
|
||||||
if cf.IsFeatureFlagSet(FlagGCMIV128) {
|
if cf.IsFeatureFlagSet(FlagGCMIV128) {
|
||||||
return fmt.Errorf("XChaCha20Poly1305 conflicts with GCMIV128 feature flag")
|
return fmt.Errorf("XChaCha20Poly1305 conflicts with GCMIV128 feature flag")
|
||||||
}
|
}
|
||||||
if !cf.IsFeatureFlagSet(FlagHKDF) {
|
if !cf.IsFeatureFlagSet(FlagHKDF) {
|
||||||
return fmt.Errorf("XChaCha20Poly1305 requires HKDF feature flag")
|
return fmt.Errorf("XChaCha20Poly1305 requires HKDF feature flag")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// The absence of other flags means AES-GCM (oldest algorithm)
|
// The absence of other flags means AES-GCM (oldest algorithm)
|
||||||
case !cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && !cf.IsFeatureFlagSet(FlagAESSIV):
|
if !cf.IsFeatureFlagSet(FlagXChaCha20Poly1305) && !cf.IsFeatureFlagSet(FlagAESSIV) {
|
||||||
if !cf.IsFeatureFlagSet(FlagGCMIV128) {
|
if !cf.IsFeatureFlagSet(FlagGCMIV128) {
|
||||||
return fmt.Errorf("AES-GCM requires GCMIV128 feature flag")
|
return fmt.Errorf("AES-GCM requires GCMIV128 feature flag")
|
||||||
}
|
}
|
||||||
@ -46,10 +47,10 @@ func (cf *ConfFile) Validate() error {
|
|||||||
}
|
}
|
||||||
// Filename encryption
|
// Filename encryption
|
||||||
{
|
{
|
||||||
switch {
|
if cf.IsFeatureFlagSet(FlagPlaintextNames) {
|
||||||
case cf.IsFeatureFlagSet(FlagPlaintextNames) && cf.IsFeatureFlagSet(FlagEMENames):
|
if cf.IsFeatureFlagSet(FlagEMENames) {
|
||||||
return fmt.Errorf("Can't have both PlaintextNames and EMENames feature flags")
|
return fmt.Errorf("PlaintextNames conflicts with EMENames feature flag")
|
||||||
case cf.IsFeatureFlagSet(FlagPlaintextNames):
|
}
|
||||||
if cf.IsFeatureFlagSet(FlagDirIV) {
|
if cf.IsFeatureFlagSet(FlagDirIV) {
|
||||||
return fmt.Errorf("PlaintextNames conflicts with DirIV feature flag")
|
return fmt.Errorf("PlaintextNames conflicts with DirIV feature flag")
|
||||||
}
|
}
|
||||||
@ -59,9 +60,19 @@ func (cf *ConfFile) Validate() error {
|
|||||||
if cf.IsFeatureFlagSet(FlagRaw64) {
|
if cf.IsFeatureFlagSet(FlagRaw64) {
|
||||||
return fmt.Errorf("PlaintextNames conflicts with Raw64 feature flag")
|
return fmt.Errorf("PlaintextNames conflicts with Raw64 feature flag")
|
||||||
}
|
}
|
||||||
case cf.IsFeatureFlagSet(FlagEMENames):
|
if cf.IsFeatureFlagSet(FlagLongNameMax) {
|
||||||
|
return fmt.Errorf("PlaintextNames conflicts with LongNameMax feature flag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cf.IsFeatureFlagSet(FlagEMENames) {
|
||||||
// All combinations of DirIV, LongNames, Raw64 allowed
|
// All combinations of DirIV, LongNames, Raw64 allowed
|
||||||
}
|
}
|
||||||
|
if cf.LongNameMax != 0 && !cf.IsFeatureFlagSet(FlagLongNameMax) {
|
||||||
|
return fmt.Errorf("LongNameMax=%d but the LongNameMax feature flag is NOT set", cf.LongNameMax)
|
||||||
|
}
|
||||||
|
if cf.LongNameMax == 0 && cf.IsFeatureFlagSet(FlagLongNameMax) {
|
||||||
|
return fmt.Errorf("LongNameMax=0 but the LongNameMax feature flag IS set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ func (be *NameTransform) EncryptAndHashBadName(name string, iv []byte, dirfd int
|
|||||||
//file found, return result
|
//file found, return result
|
||||||
return lastFoundName, nil
|
return lastFoundName, nil
|
||||||
}
|
}
|
||||||
//BadName Mode: check if the name was tranformed without change (badname suffix and undecryptable cipher name)
|
//BadName Mode: check if the name was transformed without change (badname suffix and undecryptable cipher name)
|
||||||
err = syscallcompat.Fstatat(dirfd, name[:len(name)-len(BadnameSuffix)], &st, unix.AT_SYMLINK_NOFOLLOW)
|
err = syscallcompat.Fstatat(dirfd, name[:len(name)-len(BadnameSuffix)], &st, unix.AT_SYMLINK_NOFOLLOW)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
filesFound++
|
filesFound++
|
||||||
@ -48,7 +48,7 @@ func (be *NameTransform) EncryptAndHashBadName(name string, iv []byte, dirfd int
|
|||||||
//expand suffix on error
|
//expand suffix on error
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if be.longNames && len(cName) > NameMax {
|
if len(cName) > be.longNameMax {
|
||||||
cNamePart = be.HashLongName(cName)
|
cNamePart = be.HashLongName(cName)
|
||||||
}
|
}
|
||||||
cNameBadReverse := cNamePart + name[charpos:len(name)-len(BadnameSuffix)]
|
cNameBadReverse := cNamePart + name[charpos:len(name)-len(BadnameSuffix)]
|
||||||
|
@ -4,6 +4,7 @@ package nametransform
|
|||||||
import (
|
import (
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"math"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
@ -18,7 +19,9 @@ const (
|
|||||||
// NameTransform is used to transform filenames.
|
// NameTransform is used to transform filenames.
|
||||||
type NameTransform struct {
|
type NameTransform struct {
|
||||||
emeCipher *eme.EMECipher
|
emeCipher *eme.EMECipher
|
||||||
longNames bool
|
// Names longer than `longNameMax` are hashed. Set to MaxInt when
|
||||||
|
// longnames are disabled.
|
||||||
|
longNameMax int
|
||||||
// B64 = either base64.URLEncoding or base64.RawURLEncoding, depending
|
// B64 = either base64.URLEncoding or base64.RawURLEncoding, depending
|
||||||
// on the Raw64 feature flag
|
// on the Raw64 feature flag
|
||||||
B64 *base64.Encoding
|
B64 *base64.Encoding
|
||||||
@ -28,14 +31,26 @@ type NameTransform struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new NameTransform instance.
|
// New returns a new NameTransform instance.
|
||||||
func New(e *eme.EMECipher, longNames bool, raw64 bool, badname []string, deterministicNames bool) *NameTransform {
|
//
|
||||||
|
// If `longNames` is set, names longer than `longNameMax` are hashed to
|
||||||
|
// `gocryptfs.longname.[sha256]`.
|
||||||
|
// Pass `longNameMax = 0` to use the default value (255).
|
||||||
|
func New(e *eme.EMECipher, longNames bool, longNameMax uint8, raw64 bool, badname []string, deterministicNames bool) *NameTransform {
|
||||||
b64 := base64.URLEncoding
|
b64 := base64.URLEncoding
|
||||||
if raw64 {
|
if raw64 {
|
||||||
b64 = base64.RawURLEncoding
|
b64 = base64.RawURLEncoding
|
||||||
}
|
}
|
||||||
|
var effectiveLongNameMax int = math.MaxInt32
|
||||||
|
if longNames {
|
||||||
|
if longNameMax == 0 {
|
||||||
|
effectiveLongNameMax = NameMax
|
||||||
|
} else {
|
||||||
|
effectiveLongNameMax = int(longNameMax)
|
||||||
|
}
|
||||||
|
}
|
||||||
return &NameTransform{
|
return &NameTransform{
|
||||||
emeCipher: e,
|
emeCipher: e,
|
||||||
longNames: longNames,
|
longNameMax: effectiveLongNameMax,
|
||||||
B64: b64,
|
B64: b64,
|
||||||
badnamePatterns: badname,
|
badnamePatterns: badname,
|
||||||
deterministicNames: deterministicNames,
|
deterministicNames: deterministicNames,
|
||||||
@ -47,7 +62,13 @@ func New(e *eme.EMECipher, longNames bool, raw64 bool, badname []string, determi
|
|||||||
func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error) {
|
func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error) {
|
||||||
res, err := n.decryptName(cipherName, iv)
|
res, err := n.decryptName(cipherName, iv)
|
||||||
if err != nil && n.HaveBadnamePatterns() {
|
if err != nil && n.HaveBadnamePatterns() {
|
||||||
return n.decryptBadname(cipherName, iv)
|
res, err = n.decryptBadname(cipherName, iv)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err := IsValidName(res); err != nil {
|
||||||
|
return "", syscall.EBADMSG
|
||||||
}
|
}
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -71,26 +92,34 @@ func (n *NameTransform) decryptName(cipherName string, iv []byte) (string, error
|
|||||||
return "", syscall.EBADMSG
|
return "", syscall.EBADMSG
|
||||||
}
|
}
|
||||||
plain := string(bin)
|
plain := string(bin)
|
||||||
if err := IsValidName(plain); err != nil {
|
|
||||||
return "", syscall.EBADMSG
|
|
||||||
}
|
|
||||||
return plain, err
|
return plain, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptName encrypts "plainName", returns a base64-encoded "cipherName64",
|
// EncryptName encrypts a file name "plainName" and returns a base64-encoded "cipherName64",
|
||||||
// encrypted using EME (https://github.com/rfjakob/eme).
|
// encrypted using EME (https://github.com/rfjakob/eme).
|
||||||
//
|
//
|
||||||
|
// plainName is checked for null bytes, slashes etc. and such names are rejected
|
||||||
|
// with an error.
|
||||||
|
//
|
||||||
// This function is exported because in some cases, fusefrontend needs access
|
// This function is exported because in some cases, fusefrontend needs access
|
||||||
// to the full (not hashed) name if longname is used.
|
// to the full (not hashed) name if longname is used.
|
||||||
func (n *NameTransform) EncryptName(plainName string, iv []byte) (cipherName64 string, err error) {
|
func (n *NameTransform) EncryptName(plainName string, iv []byte) (cipherName64 string, err error) {
|
||||||
if err := IsValidName(plainName); err != nil {
|
if err := IsValidName(plainName); err != nil {
|
||||||
return "", syscall.EBADMSG
|
return "", syscall.EBADMSG
|
||||||
}
|
}
|
||||||
|
return n.encryptName(plainName, iv), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryptName encrypts "plainName" and returns a base64-encoded "cipherName64",
|
||||||
|
// encrypted using EME (https://github.com/rfjakob/eme).
|
||||||
|
//
|
||||||
|
// No checks for null bytes etc are performed against plainName.
|
||||||
|
func (n *NameTransform) encryptName(plainName string, iv []byte) (cipherName64 string) {
|
||||||
bin := []byte(plainName)
|
bin := []byte(plainName)
|
||||||
bin = pad16(bin)
|
bin = pad16(bin)
|
||||||
bin = n.emeCipher.Encrypt(iv, bin)
|
bin = n.emeCipher.Encrypt(iv, bin)
|
||||||
cipherName64 = n.B64.EncodeToString(bin)
|
cipherName64 = n.B64.EncodeToString(bin)
|
||||||
return cipherName64, nil
|
return cipherName64
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptAndHashName encrypts "name" and hashes it to a longname if it is
|
// EncryptAndHashName encrypts "name" and hashes it to a longname if it is
|
||||||
@ -105,7 +134,7 @@ func (be *NameTransform) EncryptAndHashName(name string, iv []byte) (string, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if be.longNames && len(cName) > NameMax {
|
if len(cName) > be.longNameMax {
|
||||||
return be.HashLongName(cName), nil
|
return be.HashLongName(cName), nil
|
||||||
}
|
}
|
||||||
return cName, nil
|
return cName, nil
|
||||||
@ -129,3 +158,9 @@ func Dir(path string) string {
|
|||||||
}
|
}
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLongNameMax will return curent `longNameMax`. File name longer than
|
||||||
|
// this should be hashed.
|
||||||
|
func (n *NameTransform) GetLongNameMax() int {
|
||||||
|
return n.longNameMax
|
||||||
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !without_openssl
|
||||||
// +build !without_openssl
|
// +build !without_openssl
|
||||||
|
|
||||||
package stupidgcm
|
package stupidgcm
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !without_openssl
|
||||||
// +build !without_openssl
|
// +build !without_openssl
|
||||||
|
|
||||||
package stupidgcm
|
package stupidgcm
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !without_openssl
|
||||||
// +build !without_openssl
|
// +build !without_openssl
|
||||||
|
|
||||||
package stupidgcm
|
package stupidgcm
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !without_openssl
|
||||||
// +build !without_openssl
|
// +build !without_openssl
|
||||||
|
|
||||||
package stupidgcm
|
package stupidgcm
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !without_openssl
|
||||||
// +build !without_openssl
|
// +build !without_openssl
|
||||||
|
|
||||||
package stupidgcm
|
package stupidgcm
|
||||||
@ -117,7 +118,7 @@ func slicePointerOrNull(s []byte) (ptr *C.uchar) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This functions exists to benchmark the C call overhead from Go.
|
// This functions exists to benchmark the C call overhead from Go.
|
||||||
// See BenchmarkCCall for resuts.
|
// See BenchmarkCCall for results.
|
||||||
func noopCFunction() {
|
func noopCFunction() {
|
||||||
C.noop_c_function()
|
C.noop_c_function()
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func PreferOpenSSLXchacha20poly1305() bool {
|
|||||||
if runtime.GOARCH == "amd64" {
|
if runtime.GOARCH == "amd64" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// On arm64 and arm, OpenSSL is faster. Probably everwhere else too.
|
// On arm64 and arm, OpenSSL is faster. Probably everywhere else too.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !without_openssl
|
||||||
// +build !without_openssl
|
// +build !without_openssl
|
||||||
|
|
||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package syscallcompat
|
package syscallcompat
|
||||||
|
@ -17,8 +17,10 @@ const (
|
|||||||
// O_PATH is only defined on Linux
|
// O_PATH is only defined on Linux
|
||||||
O_PATH = unix.O_PATH
|
O_PATH = unix.O_PATH
|
||||||
|
|
||||||
// RENAME_NOREPLACE is only defined on Linux
|
// Only defined on Linux
|
||||||
RENAME_NOREPLACE = unix.RENAME_NOREPLACE
|
RENAME_NOREPLACE = unix.RENAME_NOREPLACE
|
||||||
|
RENAME_WHITEOUT = unix.RENAME_WHITEOUT
|
||||||
|
RENAME_EXCHANGE = unix.RENAME_EXCHANGE
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnospcPrealloc preallocates ciphertext space without changing the file
|
// EnospcPrealloc preallocates ciphertext space without changing the file
|
||||||
|
13
volume.go
13
volume.go
@ -9,6 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"libgocryptfs/v2/internal/configfile"
|
"libgocryptfs/v2/internal/configfile"
|
||||||
"libgocryptfs/v2/internal/contentenc"
|
"libgocryptfs/v2/internal/contentenc"
|
||||||
@ -81,6 +82,7 @@ func registerNewVolume(rootCipherDir string, masterkey []byte, cf *configfile.Co
|
|||||||
newVolume.nameTransform = nametransform.New(
|
newVolume.nameTransform = nametransform.New(
|
||||||
newVolume.cryptoCore.EMECipher,
|
newVolume.cryptoCore.EMECipher,
|
||||||
true,
|
true,
|
||||||
|
cf.LongNameMax,
|
||||||
cf.IsFeatureFlagSet(configfile.FlagRaw64),
|
cf.IsFeatureFlagSet(configfile.FlagRaw64),
|
||||||
badname,
|
badname,
|
||||||
!cf.IsFeatureFlagSet(configfile.FlagDirIV),
|
!cf.IsFeatureFlagSet(configfile.FlagDirIV),
|
||||||
@ -116,6 +118,8 @@ func gcf_init(rootCipherDir string, password, givenScryptHash, returnedScryptHas
|
|||||||
cf, err := configfile.Load(filepath.Join(rootCipherDir, configfile.ConfDefaultName))
|
cf, err := configfile.Load(filepath.Join(rootCipherDir, configfile.ConfDefaultName))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
masterkey := cf.GetMasterkey(password, givenScryptHash, returnedScryptHashBuff)
|
masterkey := cf.GetMasterkey(password, givenScryptHash, returnedScryptHashBuff)
|
||||||
|
wipe(password)
|
||||||
|
debug.FreeOSMemory()
|
||||||
if masterkey != nil {
|
if masterkey != nil {
|
||||||
volumeID = registerNewVolume(rootCipherDir, masterkey, cf)
|
volumeID = registerNewVolume(rootCipherDir, masterkey, cf)
|
||||||
wipe(masterkey)
|
wipe(masterkey)
|
||||||
@ -152,14 +156,14 @@ func gcf_is_closed(volumeID int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gcf_change_password
|
//export gcf_change_password
|
||||||
func gcf_change_password(rootCipherDir string, oldPassword, givenScryptHash, new_password, returnedScryptHashBuff []byte) bool {
|
func gcf_change_password(rootCipherDir string, oldPassword, givenScryptHash, newPassword, returnedScryptHashBuff []byte) bool {
|
||||||
success := false
|
success := false
|
||||||
cf, err := configfile.Load(filepath.Join(rootCipherDir, configfile.ConfDefaultName))
|
cf, err := configfile.Load(filepath.Join(rootCipherDir, configfile.ConfDefaultName))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
masterkey := cf.GetMasterkey(oldPassword, givenScryptHash, nil)
|
masterkey := cf.GetMasterkey(oldPassword, givenScryptHash, nil)
|
||||||
if masterkey != nil {
|
if masterkey != nil {
|
||||||
logN := cf.ScryptObject.LogN()
|
logN := cf.ScryptObject.LogN()
|
||||||
scryptHash := cf.EncryptKey(masterkey, new_password, logN, len(returnedScryptHashBuff) > 0)
|
scryptHash := cf.EncryptKey(masterkey, newPassword, logN, len(returnedScryptHashBuff) > 0)
|
||||||
wipe(masterkey)
|
wipe(masterkey)
|
||||||
for i := range scryptHash {
|
for i := range scryptHash {
|
||||||
returnedScryptHashBuff[i] = scryptHash[i]
|
returnedScryptHashBuff[i] = scryptHash[i]
|
||||||
@ -168,6 +172,9 @@ func gcf_change_password(rootCipherDir string, oldPassword, givenScryptHash, new
|
|||||||
success = errToBool(cf.WriteFile())
|
success = errToBool(cf.WriteFile())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wipe(newPassword)
|
||||||
|
wipe(oldPassword)
|
||||||
|
wipe(givenScryptHash)
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +198,9 @@ func gcf_create_volume(rootCipherDir string, password []byte, plaintextNames boo
|
|||||||
AESSIV: false,
|
AESSIV: false,
|
||||||
DeterministicNames: false,
|
DeterministicNames: false,
|
||||||
XChaCha20Poly1305: useXChaCha,
|
XChaCha20Poly1305: useXChaCha,
|
||||||
|
LongNameMax: 255,
|
||||||
}, returnedScryptHashBuff)
|
}, returnedScryptHashBuff)
|
||||||
|
wipe(password)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if plaintextNames {
|
if plaintextNames {
|
||||||
return true
|
return true
|
||||||
|
Loading…
Reference in New Issue
Block a user