trezor: add skeleton for Trezor support
readpassword.Trezor() is not implemented yet and returns a hardcoded dummy key.
This commit is contained in:
parent
02ab358451
commit
c6f6e8ec4d
@ -22,7 +22,7 @@ type argContainer struct {
|
||||
plaintextnames, quiet, nosyslog, wpanic,
|
||||
longnames, allow_other, reverse, aessiv, nonempty, raw64,
|
||||
noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info,
|
||||
sharedstorage, devrandom, fsck bool
|
||||
sharedstorage, devrandom, fsck, trezor bool
|
||||
// Mount options with opposites
|
||||
dev, nodev, suid, nosuid, exec, noexec, rw, ro bool
|
||||
masterkey, mountpoint, cipherdir, cpuprofile, extpass,
|
||||
@ -138,6 +138,7 @@ func parseCliOpts() (args argContainer) {
|
||||
flagSet.BoolVar(&args.sharedstorage, "sharedstorage", false, "Make concurrent access to a shared CIPHERDIR safer")
|
||||
flagSet.BoolVar(&args.devrandom, "devrandom", false, "Use /dev/random for generating master key")
|
||||
flagSet.BoolVar(&args.fsck, "fsck", false, "Run a filesystem check on CIPHERDIR")
|
||||
flagSet.BoolVar(&args.trezor, "trezor", false, "Protect the masterkey using a SatoshiLabs Trezor instead of a password")
|
||||
|
||||
// Mount options with opposites
|
||||
flagSet.BoolVar(&args.dev, "dev", false, "Allow device files")
|
||||
|
21
init_dir.go
21
init_dir.go
@ -43,11 +43,12 @@ func isDir(dir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// initDir prepares a directory for use as a gocryptfs storage directory.
|
||||
// initDir handles "gocryptfs -init". It prepares a directory for use as a
|
||||
// gocryptfs storage directory.
|
||||
// In forward mode, this means creating the gocryptfs.conf and gocryptfs.diriv
|
||||
// files in an empty directory.
|
||||
// In reverse mode, we create .gocryptfs.reverse.conf and the directory does
|
||||
// not to be empty.
|
||||
// not need to be empty.
|
||||
func initDir(args *argContainer) {
|
||||
var err error
|
||||
if args.reverse {
|
||||
@ -68,10 +69,18 @@ func initDir(args *argContainer) {
|
||||
tlog.Info.Printf("Choose a password for protecting your files.")
|
||||
}
|
||||
{
|
||||
var password []byte
|
||||
if args.trezor {
|
||||
// Get binary data from from Trezor
|
||||
password = readpassword.Trezor()
|
||||
} else {
|
||||
// Normal password entry
|
||||
password = readpassword.Twice(args.extpass)
|
||||
readpassword.CheckTrailingGarbage()
|
||||
}
|
||||
creator := tlog.ProgramName + " " + GitVersion
|
||||
password := readpassword.Twice(args.extpass)
|
||||
readpassword.CheckTrailingGarbage()
|
||||
err = configfile.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn, creator, args.aessiv, args.devrandom)
|
||||
err = configfile.CreateConfFile(args.config, password, args.plaintextnames,
|
||||
args.scryptn, creator, args.aessiv, args.devrandom, args.trezor)
|
||||
if err != nil {
|
||||
tlog.Fatal.Println(err)
|
||||
os.Exit(exitcodes.WriteConf)
|
||||
@ -81,7 +90,7 @@ func initDir(args *argContainer) {
|
||||
}
|
||||
// password runs out of scope here
|
||||
}
|
||||
// Forward mode with filename encryption enabled needs a gocryptfs.diriv
|
||||
// Forward mode with filename encryption enabled needs a gocryptfs.diriv file
|
||||
// in the root dir
|
||||
if !args.plaintextnames && !args.reverse {
|
||||
err = nametransform.WriteDirIV(nil, args.cipherdir)
|
||||
|
@ -67,7 +67,8 @@ func randBytesDevRandom(n int) []byte {
|
||||
// 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 []byte, plaintextNames bool, logN int, creator string, aessiv bool, devrandom bool) error {
|
||||
func CreateConfFile(filename string, password []byte, plaintextNames bool,
|
||||
logN int, creator string, aessiv bool, devrandom bool, trezor bool) error {
|
||||
var cf ConfFile
|
||||
cf.filename = filename
|
||||
cf.Creator = creator
|
||||
@ -87,6 +88,9 @@ func CreateConfFile(filename string, password []byte, plaintextNames bool, logN
|
||||
if aessiv {
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV])
|
||||
}
|
||||
if trezor {
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagTrezor])
|
||||
}
|
||||
{
|
||||
// Generate new random master key
|
||||
var key []byte
|
||||
|
@ -62,7 +62,7 @@ func TestLoadV2StrangeFeature(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateConfDefault(t *testing.T) {
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, false, 10, "test", false, false)
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, false, 10, "test", false, false, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -83,14 +83,14 @@ func TestCreateConfDefault(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateConfDevRandom(t *testing.T) {
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, false, 10, "test", false, true)
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, false, 10, "test", false, true, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateConfPlaintextnames(t *testing.T) {
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, true, 10, "test", false, false)
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, true, 10, "test", false, false, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -111,7 +111,7 @@ func TestCreateConfPlaintextnames(t *testing.T) {
|
||||
|
||||
// Reverse mode uses AESSIV
|
||||
func TestCreateConfFileAESSIV(t *testing.T) {
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, false, 10, "test", true, false)
|
||||
err := CreateConfFile("config_test/tmp.conf", testPw, false, 10, "test", true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ const (
|
||||
// Note that this flag does not change the password hashing algorithm
|
||||
// which always is scrypt.
|
||||
FlagHKDF
|
||||
// FlagTrezor means that "-trezor" was used when creating the filesystem.
|
||||
// The masterkey is protected using a Trezor device instead of a password.
|
||||
FlagTrezor
|
||||
)
|
||||
|
||||
// knownFlags stores the known feature flags and their string representation
|
||||
@ -37,6 +40,7 @@ var knownFlags = map[flagIota]string{
|
||||
FlagAESSIV: "AESSIV",
|
||||
FlagRaw64: "Raw64",
|
||||
FlagHKDF: "HKDF",
|
||||
FlagTrezor: "Trezor",
|
||||
}
|
||||
|
||||
// Filesystems that do not have these feature flags set are deprecated.
|
||||
|
@ -65,6 +65,9 @@ const (
|
||||
FsckErrors = 26
|
||||
// DeprecatedFS - this filesystem is deprecated
|
||||
DeprecatedFS = 27
|
||||
// TrezorError - an error was encountered while interacting with a Trezor
|
||||
// device
|
||||
TrezorError = 28
|
||||
)
|
||||
|
||||
// Err wraps an error with an associated numeric exit code
|
||||
|
26
internal/readpassword/trezor.go
Normal file
26
internal/readpassword/trezor.go
Normal file
@ -0,0 +1,26 @@
|
||||
package readpassword
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||
)
|
||||
|
||||
// Trezor reads 16 deterministically derived bytes from a
|
||||
// SatoshiLabs Trezor USB security module.
|
||||
// The bytes are pseudorandom binary data and may contain null bytes.
|
||||
// This function either succeeds and returns 16 bytes or calls os.Exit to end
|
||||
// the application.
|
||||
func Trezor() []byte {
|
||||
var err error
|
||||
// TODO try to read bytes here....
|
||||
// Handle errors
|
||||
if err != nil {
|
||||
tlog.Fatal.Printf("xxx some error was encountered...")
|
||||
os.Exit(exitcodes.TrezorError)
|
||||
}
|
||||
|
||||
tlog.Warn.Println("XXX readpassword.Trezor(): not implemented yet - returning hardcoded dummy bytes XXX")
|
||||
return []byte("1234567890123456")
|
||||
}
|
38
main.go
38
main.go
@ -33,26 +33,33 @@ var raceDetector bool
|
||||
|
||||
// loadConfig loads the config file "args.config", prompting the user for the password
|
||||
func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.ConfFile, err error) {
|
||||
// Check if the file can be opened at all before prompting for a password
|
||||
fd, err := os.Open(args.config)
|
||||
// First check if the file can be read at all, and find out if a Trezor should
|
||||
// be used instead of a password.
|
||||
_, cf1, err := configfile.LoadConfFile(args.config, nil)
|
||||
if err != nil {
|
||||
tlog.Fatal.Printf("Cannot open config file: %v", err)
|
||||
return nil, nil, exitcodes.NewErr(err.Error(), exitcodes.OpenConf)
|
||||
return nil, nil, err
|
||||
}
|
||||
fd.Close()
|
||||
// The user has passed the master key (probably because he forgot the
|
||||
// password).
|
||||
// The user has passed the master key on the command line (probably because
|
||||
// he forgot the password).
|
||||
if args.masterkey != "" {
|
||||
masterkey = parseMasterKey(args.masterkey, false)
|
||||
_, confFile, err = configfile.LoadConfFile(args.config, nil)
|
||||
} else {
|
||||
pw := readpassword.Once(args.extpass, "")
|
||||
tlog.Info.Println("Decrypting master key")
|
||||
masterkey, confFile, err = configfile.LoadConfFile(args.config, pw)
|
||||
for i := range pw {
|
||||
pw[i] = 0
|
||||
}
|
||||
return masterkey, cf1, nil
|
||||
}
|
||||
var pw []byte
|
||||
if cf1.IsFeatureFlagSet(configfile.FlagTrezor) {
|
||||
// Get binary data from from Trezor
|
||||
pw = readpassword.Trezor()
|
||||
} else {
|
||||
// Normal password entry
|
||||
pw = readpassword.Once(args.extpass, "")
|
||||
}
|
||||
tlog.Info.Println("Decrypting master key")
|
||||
masterkey, confFile, err = configfile.LoadConfFile(args.config, pw)
|
||||
for i := range pw {
|
||||
pw[i] = 0
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
tlog.Fatal.Println(err)
|
||||
return nil, nil, err
|
||||
@ -71,6 +78,9 @@ func changePassword(args *argContainer) {
|
||||
if err != nil {
|
||||
exitcodes.Exit(err)
|
||||
}
|
||||
if len(masterkey) == 0 {
|
||||
panic("empty masterkey")
|
||||
}
|
||||
tlog.Info.Println("Please enter your new password.")
|
||||
newPw := readpassword.Twice(args.extpass)
|
||||
readpassword.CheckTrailingGarbage()
|
||||
|
@ -103,7 +103,9 @@ func getMasterKey(args *argContainer) (masterkey []byte, confFile *configfile.Co
|
||||
}
|
||||
exitcodes.Exit(err)
|
||||
}
|
||||
readpassword.CheckTrailingGarbage()
|
||||
if !args.trezor {
|
||||
readpassword.CheckTrailingGarbage()
|
||||
}
|
||||
if !args.fsck {
|
||||
// We only want to print the masterkey message on a normal mount.
|
||||
printMasterKey(masterkey)
|
||||
|
@ -69,6 +69,7 @@ func TestExampleFses(t *testing.T) {
|
||||
fsNames = append(fsNames, e.Name())
|
||||
}
|
||||
for _, n := range fsNames {
|
||||
t.Logf("Checking %q", n)
|
||||
path := "../example_filesystems/" + n
|
||||
cmd := exec.Command(test_helpers.GocryptfsBinary, "-fsck", "-extpass", "echo test", path)
|
||||
outBin, err := cmd.CombinedOutput()
|
||||
|
Loading…
Reference in New Issue
Block a user