trezor: add TrezorPayload
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.
This commit is contained in:
parent
91de77943f
commit
9a15dfa494
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"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"
|
||||
@ -70,9 +71,11 @@ func initDir(args *argContainer) {
|
||||
}
|
||||
{
|
||||
var password []byte
|
||||
var trezorPayload []byte
|
||||
if args.trezor {
|
||||
trezorPayload = cryptocore.RandBytes(readpassword.TrezorPayloadLen)
|
||||
// Get binary data from from Trezor
|
||||
password = readpassword.Trezor()
|
||||
password = readpassword.Trezor(trezorPayload)
|
||||
} else {
|
||||
// Normal password entry
|
||||
password = readpassword.Twice(args.extpass)
|
||||
@ -80,7 +83,7 @@ func initDir(args *argContainer) {
|
||||
}
|
||||
creator := tlog.ProgramName + " " + GitVersion
|
||||
err = configfile.Create(args.config, password, args.plaintextnames,
|
||||
args.scryptn, creator, args.aessiv, args.devrandom, args.trezor)
|
||||
args.scryptn, creator, args.aessiv, args.devrandom, trezorPayload)
|
||||
if err != nil {
|
||||
tlog.Fatal.Println(err)
|
||||
os.Exit(exitcodes.WriteConf)
|
||||
|
@ -45,6 +45,10 @@ 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
|
||||
}
|
||||
@ -68,7 +72,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, trezor bool) error {
|
||||
logN int, creator string, aessiv bool, devrandom bool, trezorPayload []byte) error {
|
||||
var cf ConfFile
|
||||
cf.filename = filename
|
||||
cf.Creator = creator
|
||||
@ -88,8 +92,9 @@ func Create(filename string, password []byte, plaintextNames bool,
|
||||
if aessiv {
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV])
|
||||
}
|
||||
if trezor {
|
||||
if len(trezorPayload) > 0 {
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagTrezor])
|
||||
cf.TrezorPayload = trezorPayload
|
||||
}
|
||||
{
|
||||
// Generate new random master key
|
||||
|
@ -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, false)
|
||||
err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, false, nil)
|
||||
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, false)
|
||||
err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, true, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateConfPlaintextnames(t *testing.T) {
|
||||
err := Create("config_test/tmp.conf", testPw, true, 10, "test", false, false, false)
|
||||
err := Create("config_test/tmp.conf", testPw, true, 10, "test", false, false, nil)
|
||||
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, false)
|
||||
err := Create("config_test/tmp.conf", testPw, false, 10, "test", true, false, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -7,12 +7,22 @@ import (
|
||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||
)
|
||||
|
||||
const (
|
||||
// TrezorPayloadLen is the length of the payload data passed to Trezor's
|
||||
// CipherKeyValue function.
|
||||
TrezorPayloadLen = 32
|
||||
)
|
||||
|
||||
// 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 {
|
||||
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)
|
||||
}
|
||||
var err error
|
||||
// TODO try to read bytes here....
|
||||
// Handle errors
|
||||
@ -20,7 +30,6 @@ func Trezor() []byte {
|
||||
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")
|
||||
}
|
||||
|
2
main.go
2
main.go
@ -49,7 +49,7 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf
|
||||
var pw []byte
|
||||
if cf1.IsFeatureFlagSet(configfile.FlagTrezor) {
|
||||
// Get binary data from from Trezor
|
||||
pw = readpassword.Trezor()
|
||||
pw = readpassword.Trezor(cf1.TrezorPayload)
|
||||
} else {
|
||||
// Normal password entry
|
||||
pw = readpassword.Once(args.extpass, "")
|
||||
|
@ -42,6 +42,9 @@ func TestInitTrezor(t *testing.T) {
|
||||
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).
|
||||
|
Loading…
Reference in New Issue
Block a user