aboutsummaryrefslogtreecommitdiff
path: root/internal/readpassword/trezor.go.broken
diff options
context:
space:
mode:
Diffstat (limited to 'internal/readpassword/trezor.go.broken')
-rw-r--r--internal/readpassword/trezor.go.broken119
1 files changed, 119 insertions, 0 deletions
diff --git a/internal/readpassword/trezor.go.broken b/internal/readpassword/trezor.go.broken
new file mode 100644
index 0000000..a4d32cf
--- /dev/null
+++ b/internal/readpassword/trezor.go.broken
@@ -0,0 +1,119 @@
+// +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
+}