fusefrontend_reverse: move pathiv to its own package
We will also need it in forward mode.
This commit is contained in:
parent
4d2cc551cf
commit
857507e8b1
|
@ -6,6 +6,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/ctlsock"
|
"github.com/rfjakob/gocryptfs/internal/ctlsock"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ ctlsock.Interface = &ReverseFS{} // Verify that interface is implemented.
|
var _ ctlsock.Interface = &ReverseFS{} // Verify that interface is implemented.
|
||||||
|
@ -20,7 +21,7 @@ func (rfs *ReverseFS) EncryptPath(plainPath string) (string, error) {
|
||||||
cipherPath := ""
|
cipherPath := ""
|
||||||
parts := strings.Split(plainPath, "/")
|
parts := strings.Split(plainPath, "/")
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
dirIV := derivePathIV(cipherPath, ivPurposeDirIV)
|
dirIV := pathiv.Derive(cipherPath, pathiv.PurposeDirIV)
|
||||||
encryptedPart := rfs.nameTransform.EncryptName(part, dirIV)
|
encryptedPart := rfs.nameTransform.EncryptName(part, dirIV)
|
||||||
if rfs.args.LongNames && len(encryptedPart) > syscall.NAME_MAX {
|
if rfs.args.LongNames && len(encryptedPart) > syscall.NAME_MAX {
|
||||||
encryptedPart = rfs.nameTransform.HashLongName(encryptedPart)
|
encryptedPart = rfs.nameTransform.HashLongName(encryptedPart)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/hanwen/go-fuse/fuse/nodefs"
|
"github.com/hanwen/go-fuse/fuse/nodefs"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ func (rfs *ReverseFS) newNameFile(relPath string) (nodefs.File, fuse.Status) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
dirIV := derivePathIV(cDir, ivPurposeDirIV)
|
dirIV := pathiv.Derive(cDir, pathiv.PurposeDirIV)
|
||||||
// plain name
|
// plain name
|
||||||
pName, err := rfs.findLongnameParent(pDir, dirIV, longname)
|
pName, err := rfs.findLongnameParent(pDir, dirIV, longname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/hanwen/go-fuse/fuse/nodefs"
|
"github.com/hanwen/go-fuse/fuse/nodefs"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,8 +61,8 @@ func (rfs *ReverseFS) newFile(relPath string, flags uint32) (nodefs.File, fuse.S
|
||||||
tlog.Debug.Printf("ino%d: newFile: found in the inode table", st.Ino)
|
tlog.Debug.Printf("ino%d: newFile: found in the inode table", st.Ino)
|
||||||
derivedIVs = v.(derivedIVContainer)
|
derivedIVs = v.(derivedIVContainer)
|
||||||
} else {
|
} else {
|
||||||
derivedIVs.id = derivePathIV(relPath, ivPurposeFileID)
|
derivedIVs.id = pathiv.Derive(relPath, pathiv.PurposeFileID)
|
||||||
derivedIVs.block0IV = derivePathIV(relPath, ivPurposeBlock0IV)
|
derivedIVs.block0IV = pathiv.Derive(relPath, pathiv.PurposeBlock0IV)
|
||||||
// Nlink > 1 means there is more than one path to this file.
|
// Nlink > 1 means there is more than one path to this file.
|
||||||
// Store the derived values so we always return the same data,
|
// Store the derived values so we always return the same data,
|
||||||
// regardless of the path that is used to access the file.
|
// regardless of the path that is used to access the file.
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
||||||
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
|
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
|
||||||
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -263,7 +264,7 @@ func (rfs *ReverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse.
|
||||||
nVirtual := 1
|
nVirtual := 1
|
||||||
|
|
||||||
// Encrypt names
|
// Encrypt names
|
||||||
dirIV := derivePathIV(cipherPath, ivPurposeDirIV)
|
dirIV := pathiv.Derive(cipherPath, pathiv.PurposeDirIV)
|
||||||
for i := range entries {
|
for i := range entries {
|
||||||
var cName string
|
var cName string
|
||||||
// ".gocryptfs.reverse.conf" in the root directory is mapped to "gocryptfs.conf"
|
// ".gocryptfs.reverse.conf" in the root directory is mapped to "gocryptfs.conf"
|
||||||
|
@ -305,7 +306,7 @@ func (rfs *ReverseFS) Readlink(cipherPath string, context *fuse.Context) (string
|
||||||
if rfs.args.PlaintextNames {
|
if rfs.args.PlaintextNames {
|
||||||
return plainTarget, fuse.OK
|
return plainTarget, fuse.OK
|
||||||
}
|
}
|
||||||
nonce := derivePathIV(cipherPath, ivPurposeSymlinkIV)
|
nonce := pathiv.Derive(cipherPath, pathiv.PurposeSymlinkIV)
|
||||||
// Symlinks are encrypted like file contents and base64-encoded
|
// Symlinks are encrypted like file contents and base64-encoded
|
||||||
cBinTarget := rfs.contentEnc.EncryptBlockNonce([]byte(plainTarget), 0, nil, nonce)
|
cBinTarget := rfs.contentEnc.EncryptBlockNonce([]byte(plainTarget), 0, nil, nonce)
|
||||||
cTarget := rfs.nameTransform.B64.EncodeToString(cBinTarget)
|
cTarget := rfs.nameTransform.B64.EncodeToString(cBinTarget)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package fusefrontend_reverse
|
package fusefrontend_reverse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,23 +20,6 @@ func saneDir(path string) string {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
type ivPurposeType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ivPurposeDirIV ivPurposeType = "DIRIV"
|
|
||||||
ivPurposeFileID ivPurposeType = "FILEID"
|
|
||||||
ivPurposeSymlinkIV ivPurposeType = "SYMLINKIV"
|
|
||||||
ivPurposeBlock0IV ivPurposeType = "BLOCK0IV"
|
|
||||||
)
|
|
||||||
|
|
||||||
// derivePathIV derives an IV from an encrypted path by hashing it with sha256
|
|
||||||
func derivePathIV(path string, purpose ivPurposeType) []byte {
|
|
||||||
// Use null byte as separator as it cannot occur in the path
|
|
||||||
extended := []byte(path + "\000" + string(purpose))
|
|
||||||
hash := sha256.Sum256(extended)
|
|
||||||
return hash[:nametransform.DirIVLen]
|
|
||||||
}
|
|
||||||
|
|
||||||
// abs basically returns storage dir + "/" + relPath.
|
// abs basically returns storage dir + "/" + relPath.
|
||||||
// It takes an error parameter so it can directly wrap decryptPath like this:
|
// It takes an error parameter so it can directly wrap decryptPath like this:
|
||||||
// a, err := rfs.abs(rfs.decryptPath(relPath))
|
// a, err := rfs.abs(rfs.decryptPath(relPath))
|
||||||
|
@ -104,7 +87,7 @@ func (rfs *ReverseFS) decryptPath(relPath string) (string, error) {
|
||||||
// Start at the top and recurse
|
// Start at the top and recurse
|
||||||
currentCipherDir := filepath.Join(parts[:i]...)
|
currentCipherDir := filepath.Join(parts[:i]...)
|
||||||
currentPlainDir := filepath.Join(transformedParts[:i]...)
|
currentPlainDir := filepath.Join(transformedParts[:i]...)
|
||||||
dirIV = derivePathIV(currentCipherDir, ivPurposeDirIV)
|
dirIV = pathiv.Derive(currentCipherDir, pathiv.PurposeDirIV)
|
||||||
transformedPart, err := rfs.rDecryptName(parts[i], dirIV, currentPlainDir)
|
transformedPart, err := rfs.rDecryptName(parts[i], dirIV, currentPlainDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/hanwen/go-fuse/fuse"
|
"github.com/hanwen/go-fuse/fuse"
|
||||||
"github.com/hanwen/go-fuse/fuse/nodefs"
|
"github.com/hanwen/go-fuse/fuse/nodefs"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ func (rfs *ReverseFS) newDirIVFile(cRelPath string) (nodefs.File, fuse.Status) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
return rfs.newVirtualFile(derivePathIV(cDir, ivPurposeDirIV), absDir)
|
return rfs.newVirtualFile(pathiv.Derive(cDir, pathiv.PurposeDirIV), absDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
type virtualFile struct {
|
type virtualFile struct {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package pathiv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Purpose string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PurposeDirIV Purpose = "DIRIV"
|
||||||
|
PurposeFileID Purpose = "FILEID"
|
||||||
|
PurposeSymlinkIV Purpose = "SYMLINKIV"
|
||||||
|
PurposeBlock0IV Purpose = "BLOCK0IV"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Derive derives an IV from an encrypted path by hashing it with sha256
|
||||||
|
func Derive(path string, purpose Purpose) []byte {
|
||||||
|
// Use null byte as separator as it cannot occur in the path
|
||||||
|
extended := []byte(path + "\000" + string(purpose))
|
||||||
|
hash := sha256.Sum256(extended)
|
||||||
|
return hash[:nametransform.DirIVLen]
|
||||||
|
}
|
Loading…
Reference in New Issue