diff options
| -rw-r--r-- | Documentation/MANPAGE.md | 10 | ||||
| -rw-r--r-- | cli_args.go | 10 | ||||
| -rw-r--r-- | init_dir.go | 14 | ||||
| -rw-r--r-- | internal/configfile/config_file.go | 10 | ||||
| -rw-r--r-- | internal/configfile/config_test.go | 8 | ||||
| -rw-r--r-- | internal/configfile/feature_flags.go | 4 | ||||
| -rw-r--r-- | internal/exitcodes/exitcodes.go | 4 | ||||
| -rw-r--r-- | internal/readpassword/trezor.go.broken | 119 | ||||
| -rw-r--r-- | internal/readpassword/trezor_disabled.go | 25 | ||||
| -rw-r--r-- | main.go | 31 | ||||
| -rw-r--r-- | tests/trezor/trezor_test.go | 58 | 
11 files changed, 14 insertions, 279 deletions
| diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 55939f4..ffbb43f 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -405,16 +405,6 @@ You need root permissions to use `-suid`.  #### -trace string  Write execution trace to file. View the trace using "go tool trace FILE". -#### -trezor -With `-init`: Protect the masterkey using a SatoshiLabs Trezor instead of a password. - -This feature is disabled by default and must be enabled at compile time using: - -    ./build.bash -tags enable_trezor - -You can determine if your gocryptfs binary has Trezor support enabled checking -if the `gocryptfs -version` output contains the string `enable_trezor`. -  #### -version  Print version and exit. The output contains three fields separated by ";".  Example: "gocryptfs v1.1.1-5-g75b776c; go-fuse 6b801d3; 2016-11-01 go1.7.3". diff --git a/cli_args.go b/cli_args.go index cae7723..8d0b7b5 100644 --- a/cli_args.go +++ b/cli_args.go @@ -18,7 +18,6 @@ import (  	"github.com/rfjakob/gocryptfs/internal/configfile"  	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/prefer_openssl" -	"github.com/rfjakob/gocryptfs/internal/readpassword"  	"github.com/rfjakob/gocryptfs/internal/stupidgcm"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) @@ -29,7 +28,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, trezor bool +	sharedstorage, devrandom, fsck bool  	// Mount options with opposites  	dev, nodev, suid, nosuid, exec, noexec, rw, ro bool  	masterkey, mountpoint, cipherdir, cpuprofile, @@ -170,9 +169,6 @@ 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") -	if readpassword.TrezorSupport { -		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") @@ -282,10 +278,6 @@ func parseCliOpts() (args argContainer) {  		tlog.Fatal.Printf("The options -extpass and -masterkey cannot be used at the same time")  		os.Exit(exitcodes.Usage)  	} -	if !args.extpass.Empty() && args.trezor { -		tlog.Fatal.Printf("The options -extpass and -trezor cannot be used at the same time") -		os.Exit(exitcodes.Usage) -	}  	if args.idle < 0 {  		tlog.Fatal.Printf("Idle timeout cannot be less than 0")  		os.Exit(exitcodes.Usage) diff --git a/init_dir.go b/init_dir.go index aea8b30..1bba59e 100644 --- a/init_dir.go +++ b/init_dir.go @@ -9,7 +9,6 @@ import (  	"syscall"  	"github.com/rfjakob/gocryptfs/internal/configfile" -	"github.com/rfjakob/gocryptfs/internal/cryptocore"  	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/nametransform"  	"github.com/rfjakob/gocryptfs/internal/readpassword" @@ -72,19 +71,10 @@ func initDir(args *argContainer) {  		tlog.Info.Printf("Choose a password for protecting your files.")  	}  	{ -		var password []byte -		var trezorPayload []byte -		if args.trezor { -			trezorPayload = cryptocore.RandBytes(readpassword.TrezorPayloadLen) -			// Get binary data from from Trezor -			password = readpassword.Trezor(trezorPayload) -		} else { -			// Normal password entry -			password = readpassword.Twice([]string(args.extpass), args.passfile) -		} +		password := readpassword.Twice([]string(args.extpass), args.passfile)  		creator := tlog.ProgramName + " " + GitVersion  		err = configfile.Create(args.config, password, args.plaintextnames, -			args.scryptn, creator, args.aessiv, args.devrandom, trezorPayload) +			args.scryptn, creator, args.aessiv, args.devrandom)  		if err != nil {  			tlog.Fatal.Println(err)  			os.Exit(exitcodes.WriteConf) diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index e93affd..c27ecd4 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -46,10 +46,6 @@ type ConfFile struct {  	// mounting. This mechanism is analogous to the ext4 feature flags that are  	// stored in the superblock.  	FeatureFlags []string -	// TrezorPayload stores 32 random bytes used for unlocking the master key using -	// a Trezor security module. The randomness makes sure that a unique unlock -	// value is used for each gocryptfs filesystem. -	TrezorPayload []byte `json:",omitempty"`  	// Filename is the name of the config file. Not exported to JSON.  	filename string  } @@ -73,7 +69,7 @@ func randBytesDevRandom(n int) []byte {  // "password" and write it to "filename".  // Uses scrypt with cost parameter logN.  func Create(filename string, password []byte, plaintextNames bool, -	logN int, creator string, aessiv bool, devrandom bool, trezorPayload []byte) error { +	logN int, creator string, aessiv bool, devrandom bool) error {  	var cf ConfFile  	cf.filename = filename  	cf.Creator = creator @@ -93,10 +89,6 @@ func Create(filename string, password []byte, plaintextNames bool,  	if aessiv {  		cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV])  	} -	if len(trezorPayload) > 0 { -		cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagTrezor]) -		cf.TrezorPayload = trezorPayload -	}  	{  		// Generate new random master key  		var key []byte diff --git a/internal/configfile/config_test.go b/internal/configfile/config_test.go index 0dd081c..832867c 100644 --- a/internal/configfile/config_test.go +++ b/internal/configfile/config_test.go @@ -62,7 +62,7 @@ func TestLoadV2StrangeFeature(t *testing.T) {  }  func TestCreateConfDefault(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, false, nil) +	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, false)  	if err != nil {  		t.Fatal(err)  	} @@ -83,14 +83,14 @@ func TestCreateConfDefault(t *testing.T) {  }  func TestCreateConfDevRandom(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, true, nil) +	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, true)  	if err != nil {  		t.Fatal(err)  	}  }  func TestCreateConfPlaintextnames(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, true, 10, "test", false, false, nil) +	err := Create("config_test/tmp.conf", testPw, true, 10, "test", 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 := Create("config_test/tmp.conf", testPw, false, 10, "test", true, false, nil) +	err := Create("config_test/tmp.conf", testPw, false, 10, "test", true, false)  	if err != nil {  		t.Fatal(err)  	} diff --git a/internal/configfile/feature_flags.go b/internal/configfile/feature_flags.go index 141b007..2d609f2 100644 --- a/internal/configfile/feature_flags.go +++ b/internal/configfile/feature_flags.go @@ -25,9 +25,6 @@ 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 @@ -40,7 +37,6 @@ var knownFlags = map[flagIota]string{  	FlagAESSIV:         "AESSIV",  	FlagRaw64:          "Raw64",  	FlagHKDF:           "HKDF", -	FlagTrezor:         "Trezor",  }  // Filesystems that do not have these feature flags set are deprecated. diff --git a/internal/exitcodes/exitcodes.go b/internal/exitcodes/exitcodes.go index cd36988..b876333 100644 --- a/internal/exitcodes/exitcodes.go +++ b/internal/exitcodes/exitcodes.go @@ -65,9 +65,7 @@ const (  	FsckErrors = 26  	// DeprecatedFS - this filesystem is deprecated  	DeprecatedFS = 27 -	// TrezorError - an error was encountered while interacting with a Trezor -	// device -	TrezorError = 28 +	// skip 28  	// ExcludeError - an error occurred while processing "-exclude"  	ExcludeError = 29  	// DevNull means that /dev/null could not be opened diff --git a/internal/readpassword/trezor.go.broken b/internal/readpassword/trezor.go.broken deleted file mode 100644 index a4d32cf..0000000 --- a/internal/readpassword/trezor.go.broken +++ /dev/null @@ -1,119 +0,0 @@ -// +build enable_trezor - -package readpassword - -import ( -	"bytes" -	"log" -	"os" - -	"github.com/rfjakob/gocryptfs/internal/exitcodes" -	"github.com/rfjakob/gocryptfs/internal/tlog" - -	"github.com/xaionaro-go/cryptoWallet" -	"github.com/xaionaro-go/cryptoWallet/vendors" -) - -const ( -	// TrezorPayloadLen is the length of the payload data passed to Trezor's -	// CipherKeyValue function. -	TrezorPayloadLen        = 32 -	trezorNonce             = "" // the "nonce" is optional and has no use in here -	trezorKeyName           = "gocryptfs" -	trezorKeyDerivationPath = `m/10019'/0'` -	// TrezorSupport is true when gocryptfs has been compile with -tags enable_trezor -	TrezorSupport = true -) - -func trezorGetPin(title, description, ok, cancel string) ([]byte, error) { -	return Once("", title), nil -} -func trezorGetConfirm(title, description, ok, cancel string) (bool, error) { -	return false, nil // do not retry on connection failure -} - -// Trezor reads 32 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 32 bytes or calls os.Exit to end -// the application. -func Trezor(payload []byte) []byte { -	if len(payload) != TrezorPayloadLen { -		tlog.Fatal.Printf("Invalid TrezorPayload length: wanted %d, got %d bytes\n", TrezorPayloadLen, len(payload)) -		os.Exit(exitcodes.LoadConf) -	} - -	// Find all trezor devices -	trezors := cryptoWallet.Find(cryptoWallet.Filter{ -		VendorID:   &[]uint16{vendors.GetVendorID("satoshilabs")}[0], -		ProductIDs: []uint16{1 /* Trezor One */}, -	}) - -	// ATM, we require to one and only one trezor device to be connected. -	// The support of multiple trezor devices is not implemented, yet. -	if len(trezors) == 0 { -		tlog.Fatal.Printf("Trezor device is not found. Check the connection.") -		os.Exit(exitcodes.TrezorError) -	} -	if len(trezors) > 1 { -		tlog.Fatal.Printf("It's more than one Trezor device connected. This case is not implemented, yet. The number of currently connected devices: %v.", len(trezors)) -		os.Exit(exitcodes.TrezorError) -	} - -	// Using the first found device -	trezor := trezors[0] - -	// Trezor may ask for PIN or Passphrase. Setting the handler for this case. -	trezor.SetGetPinFunc(trezorGetPin) - -	// In some cases (like lost connection to the Trezor device and cannot -	// reconnect) it's required to get a confirmation from the user to -	// retry to reconnect. Setting the handler for this case. -	trezor.SetGetConfirmFunc(trezorGetConfirm) - -	// To reset the state of the device and check if it's initialized. -	// If device is not initialized then trezor.Reset() will return an -	// error. -	err := trezor.Reset() -	if err != nil { -		tlog.Fatal.Printf("Cannot reset the Trezor device. Error: %v", err.Error()) -		os.Exit(exitcodes.TrezorError) -	} - -	// To generate a deterministic key we trying to decrypt our -	// predefined constant key using the Trezor device. The resulting key -	// will depend on next variables: -	// * the Trezor master key; -	// * the passphrase (passed to the Trezor). -	// -	// The right key will be received only if both values (mentioned -	// above) are correct. -	// -	// Note: -	// Also the resulting key depends on this values (that we defined as -	// constants above): -	// * the key derivation path; -	// * the "encrypted" payload; -	// * the nonce; -	// * the key name. -	key, err := trezor.DecryptKey(trezorKeyDerivationPath, payload, []byte(trezorNonce), trezorKeyName) -	if err != nil { -		tlog.Fatal.Printf("Cannot get the key from the Trezor device. Error description:\n\t%v", err.Error()) -		os.Exit(exitcodes.TrezorError) -	} - -	// Sanity checks -	if len(key) != TrezorPayloadLen { -		log.Panicf("BUG: decrypted value has wrong length %d", len(key)) -	} -	if bytes.Equal(key, payload) { -		log.Panicf("BUG: payload and decrypted value are identical") -	} -	zero := make([]byte, TrezorPayloadLen) -	if bytes.Equal(key, zero) { -		log.Panicf("BUG: decrypted value is all-zero") -	} - -	// Everything ok -	return key -} diff --git a/internal/readpassword/trezor_disabled.go b/internal/readpassword/trezor_disabled.go deleted file mode 100644 index 96a6082..0000000 --- a/internal/readpassword/trezor_disabled.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build !enable_trezor - -package readpassword - -import ( -	"os" - -	"github.com/rfjakob/gocryptfs/internal/tlog" -) - -const ( -	// TrezorPayloadLen is the length of the payload data passed to Trezor's -	// CipherKeyValue function. -	TrezorPayloadLen = 32 -	// TrezorSupport is true when gocryptfs has been compile with -tags enable_trezor -	TrezorSupport = false -) - -// Trezor determinitically derives 32 bytes from the payload and the connected -// USB security module. -func Trezor(payload []byte) []byte { -	tlog.Fatal.Printf("This binary has been compiled without Trezor support") -	os.Exit(1) -	return nil -} @@ -34,8 +34,7 @@ var raceDetector bool  // loadConfig loads the config file "args.config", prompting the user for the password  func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile, err error) { -	// First check if the file can be read at all, and find out if a Trezor should -	// be used instead of a password. +	// First check if the file can be read at all.  	cf, err = configfile.Load(args.config)  	if err != nil {  		tlog.Fatal.Printf("Cannot open config file: %v", err) @@ -47,14 +46,7 @@ func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile,  		masterkey = parseMasterKey(args.masterkey, false)  		return masterkey, cf, nil  	} -	var pw []byte -	if cf.IsFeatureFlagSet(configfile.FlagTrezor) { -		// Get binary data from Trezor -		pw = readpassword.Trezor(cf.TrezorPayload) -	} else { -		// Normal password entry -		pw = readpassword.Once([]string(args.extpass), args.passfile, "") -	} +	pw := readpassword.Once([]string(args.extpass), args.passfile, "")  	tlog.Info.Println("Decrypting master key")  	masterkey, err = cf.DecryptMasterKey(pw)  	for i := range pw { @@ -71,20 +63,10 @@ func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile,  // changePassword - change the password of config file "filename"  // Does not return (calls os.Exit both on success and on error).  func changePassword(args *argContainer) { -	// Parse the config file, but do not unlock the master key. We only want to -	// know if the Trezor flag is set. -	cf1, err := configfile.Load(args.config) -	if err != nil { -		tlog.Fatal.Printf("Cannot open config file: %v", err) -		os.Exit(exitcodes.LoadConf) -	} -	if cf1.IsFeatureFlagSet(configfile.FlagTrezor) { -		tlog.Fatal.Printf("Password change is not supported on Trezor-enabled filesystems.") -		os.Exit(exitcodes.Usage) -	}  	var confFile *configfile.ConfFile  	{  		var masterkey []byte +		var err error  		masterkey, confFile, err = loadConfig(args)  		if err != nil {  			exitcodes.Exit(err) @@ -111,7 +93,7 @@ func changePassword(args *argContainer) {  	// "-masterkey"?  	if args.masterkey != "" {  		bak := args.config + ".bak" -		err = os.Link(args.config, bak) +		err := os.Link(args.config, bak)  		if err != nil {  			tlog.Fatal.Printf("Could not create backup file: %v", err)  			os.Exit(exitcodes.Init) @@ -121,7 +103,7 @@ func changePassword(args *argContainer) {  			"Delete it after you have verified that you can access your files with the new password."+  			tlog.ColorReset, bak)  	} -	err = confFile.WriteFile() +	err := confFile.WriteFile()  	if err != nil {  		tlog.Fatal.Println(err)  		os.Exit(exitcodes.WriteConf) @@ -136,9 +118,6 @@ func printVersion() {  	if stupidgcm.BuiltWithoutOpenssl {  		tagsSlice = append(tagsSlice, "without_openssl")  	} -	if readpassword.TrezorSupport { -		tagsSlice = append(tagsSlice, "enable_trezor") -	}  	tags := ""  	if tagsSlice != nil {  		tags = " " + strings.Join(tagsSlice, " ") diff --git a/tests/trezor/trezor_test.go b/tests/trezor/trezor_test.go deleted file mode 100644 index 5e071fc..0000000 --- a/tests/trezor/trezor_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package trezor - -// Test operations with "-trezor". -// See also the "cli" package - the tests there are very similar. - -import ( -	"os/exec" -	"runtime" -	"testing" - -	"github.com/rfjakob/gocryptfs/internal/configfile" -	"github.com/rfjakob/gocryptfs/internal/exitcodes" - -	"github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func isTrezorConnected() bool { -	if runtime.GOOS != "linux" { -		return false -	} -	c := exec.Command("lsusb", "-d", "534c:0001") -	err := c.Run() -	if err != nil { -		return false -	} -	return true -} - -// Test -init with -trezor -func TestInitTrezor(t *testing.T) { -	if !isTrezorConnected() { -		t.Skip("No Trezor device connected") -	} -	t.Log("Trying gocryptfs -init -trezor ...") -	//                                        vvvvvvvvvvvvv disable -extpass -	dir := test_helpers.InitFS(t, "-trezor", "-extpass", "") -	// The freshly created config file should have the Trezor feature flag set. -	c, err := configfile.Load(dir + "/" + configfile.ConfDefaultName) -	if err != nil { -		t.Fatal(err) -	} -	if !c.IsFeatureFlagSet(configfile.FlagTrezor) { -		t.Error("Trezor flag should be set but is not") -	} -	if len(c.TrezorPayload) != 32 { -		t.Errorf("TrezorPayload has wrong length: %d", len(c.TrezorPayload)) -	} -} - -// Test using -trezor together with -extpass. Should fail with code 1 (usage error). -func TestTrezorExtpass(t *testing.T) { -	cmd := exec.Command(test_helpers.GocryptfsBinary, "-init", "-trezor", "-extpass", "foo", "/tmp") -	err := cmd.Run() -	exitCode := test_helpers.ExtractCmdExitCode(err) -	if exitCode != exitcodes.Usage { -		t.Errorf("wrong exit code: want %d, have %d", exitcodes.Usage, exitCode) -	} -} | 
