bitbox

package
v4.14.1+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2019 License: Apache-2.0 Imports: 44 Imported by: 9

Documentation

Overview

Package bitbox contains the API to the physical device.

Index

Constants

View Source
const (
	// EventStatusChanged is fired when the status changes. Check the status using Status().
	EventStatusChanged event.Event = "statusChanged"

	// EventBootloaderStatusChanged is fired when the bootloader status changes. Check the status
	// using BootloaderStatus().
	EventBootloaderStatusChanged event.Event = "bootloaderStatusChanged"

	// ProductName is the name of the bitbox.
	// If you change this, be sure to check the frontend and other places which assume this is a
	// constant.
	ProductName = "bitbox"
)
View Source
const (
	// ErrIONoPassword is returned when no password has been configured.
	ErrIONoPassword = 101

	// ErrTouchAbort is returned when the user short-touches the button.
	ErrTouchAbort = 600

	// ErrTouchTimeout is returned when the user does not confirm or abort for 30s.
	ErrTouchTimeout = 601

	// ErrSDCard is returned when the SD card is needed, but not inserted.
	ErrSDCard = 400

	// ErrInitializing is returned when the device is still booting up.
	ErrInitializing = 503

	// ErrSDNoMatch is returned when the backup check fails.
	ErrSDNoMatch = 410
)
View Source
const (
	// EventPairingStarted is fired when the pairing started.
	EventPairingStarted event.Event = "pairingStarted"

	// EventPairingTimedout is fired when the pairing timed out.
	EventPairingTimedout event.Event = "pairingTimedout"

	// EventPairingAborted is fired when the pairing aborted.
	EventPairingAborted event.Event = "pairingAborted"

	// EventPairingError is fired when an error happened during the pairing.
	EventPairingError event.Event = "pairingError"

	// EventPairingSuccess is fired when the pairing successfully finished.
	EventPairingSuccess event.Event = "pairingSuccess"

	// EventSignProgress is fired when starting to sign a new batch of hashes.
	EventSignProgress event.Event = "signProgress"

	// EventSignConfirmDevice is fired when the user is about to be prompted to sign the tx with the
	// device.
	EventSignConfirm event.Event = "signConfirm"
)

TODO: improve error handling and change event data into a JSON object, and split BitBox events from generic device events

Variables

View Source
var ErrMustBeLoggedIn = errors.New("must be logged in")

ErrMustBeLoggedIn is returned by API calls when a login is required, but the device has not beed unlocked.

Functions

func Asset

func Asset(name string) ([]byte, error)

Asset loads and returns the asset for the given name. It returns an error if the asset could not be found or could not be loaded.

func AssetDir

func AssetDir(name string) ([]string, error)

AssetDir returns the file names below a certain directory embedded in the file by go-bindata. For example if you run go-bindata on data/... and data contains the following hierarchy:

data/
  foo.txt
  img/
    a.png
    b.png

then AssetDir("data") would return []string{"foo.txt", "img"} AssetDir("data/img") would return []string{"a.png", "b.png"} AssetDir("foo.txt") and AssetDir("notexist") would return an error AssetDir("") will return []string{"data"}.

func AssetInfo

func AssetInfo(name string) (os.FileInfo, error)

AssetInfo loads and returns the asset info for the given name. It returns an error if the asset could not be found or could not be loaded.

func AssetNames

func AssetNames() []string

AssetNames returns the names of the assets.

func BundledFirmware

func BundledFirmware() []byte

BundledFirmware returns the binary of the bundled firmware.

func BundledFirmwareVersion

func BundledFirmwareVersion() *semver.SemVer

BundledFirmwareVersion returns the version of the bundled firmware.

func IsErrorSDCard

func IsErrorSDCard(err error) bool

IsErrorSDCard returns whether the SD card was not inserted during an operation that requires it.

func MustAsset

func MustAsset(name string) []byte

MustAsset is like Asset but panics when Asset would return an error. It simplifies safe initialization of global variables.

func RestoreAsset

func RestoreAsset(dir, name string) error

RestoreAsset restores an asset under the given directory

func RestoreAssets

func RestoreAssets(dir, name string) error

RestoreAssets restores an asset under the given directory recursively

Types

type BootloaderStatus

type BootloaderStatus struct {
	Upgrading         bool    `json:"upgrading"`
	Progress          float64 `json:"progress"`
	UpgradeSuccessful bool    `json:"upgradeSuccessful"`
	ErrMsg            string  `json:"errMsg"`
}

BootloaderStatus has all the info to handle the bootloader mode.

type Communication

type Communication struct {
	// contains filtered or unexported fields
}

Communication implements CommunicationInterface.

func NewCommunication

func NewCommunication(
	device io.ReadWriteCloser,
	version *semver.SemVer,
	log *logrus.Entry,
) *Communication

NewCommunication creates a new Communication instance.

func (*Communication) Close

func (communication *Communication) Close()

Close implements CommunicationInterface.

func (*Communication) SendBootloader

func (communication *Communication) SendBootloader(msg []byte) ([]byte, error)

SendBootloader sends a message in the format the bootloader expects and fetches the response.

func (*Communication) SendEncrypt

func (communication *Communication) SendEncrypt(msg, password string) (map[string]interface{}, error)

SendEncrypt sends an encrypted message. The response is json-deserialized into a map. If the response contains an error field, it is returned as a DBBErr.

func (*Communication) SendPlain

func (communication *Communication) SendPlain(msg string) (map[string]interface{}, error)

SendPlain sends an unecrypted message. The response is json-deserialized into a map.

type CommunicationInterface

type CommunicationInterface interface {
	SendPlain(string) (map[string]interface{}, error)
	SendEncrypt(string, string) (map[string]interface{}, error)
	SendBootloader([]byte) ([]byte, error)
	Close()
}

CommunicationInterface contains functions needed to communicate with the device.

type Device

type Device struct {
	// contains filtered or unexported fields
}

Device provides the API to communicate with the digital bitbox. It is not safe for concurrent use.

func NewDevice

func NewDevice(
	deviceID string,
	bootloader bool,
	version *semver.SemVer,
	channelConfigDir string,
	communication CommunicationInterface,
	socksProxy socksproxy.SocksProxy) (*Device, error)

NewDevice creates a new instance of Device. bootloader enables the bootloader API and should be true only if the device is in bootloader mode. communication is used for transporting messages to/from the device. Use NewCommunication() for production.

The channelConfigDir is the location of the channel settings file. Callers can use util/config.AppDir to obtain user standard config dir.

func (*Device) BackupList

func (dbb *Device) BackupList() ([]map[string]string, error)

BackupList returns a list of backup filenames.

func (dbb *Device) Blink() error

Blink flashes the LED.

func (*Device) BootloaderStatus

func (dbb *Device) BootloaderStatus() (*BootloaderStatus, error)

BootloaderStatus returns the progress of a firmware upgrade. Returns an error if the device is not in bootloader mode.

func (*Device) BootloaderUpgradeFirmware

func (dbb *Device) BootloaderUpgradeFirmware(signedFirmware []byte) error

BootloaderUpgradeFirmware uploads a signed bitbox firmware release to the device. Returns an error if the device is not in bootloader mode. See https://github.com/digitalbitbox/mcu/releases

func (*Device) ChangePassword

func (dbb *Device) ChangePassword(oldPIN string, newPIN string) error

ChangePassword replaces the PIN for the device. This only works when logged in, so the oldPIN can be checked.

func (*Device) CheckBackup

func (dbb *Device) CheckBackup(backupPassword, filename string) (bool, error)

CheckBackup uses the provided backup file and recovery password to check if they correspond to the current wallet. Returns true if it matches, false if not.

func (*Device) Close

func (dbb *Device) Close()

Close closes the HID device.

func (*Device) CreateBackup

func (dbb *Device) CreateBackup(backupName string, recoveryPassword string) (bool, error)

CreateBackup creates a new backup of the current device seed on the SD card. The recoveryPassword is used as a sanity check (does the backed up seed + recoveryPassword dervive the current keys in the BitBox?). Returns false if this check fails.

func (*Device) CreateWallet

func (dbb *Device) CreateWallet(walletName string, backupPassword string) error

CreateWallet creates a new wallet and stores a backup containing `walletName` in the filename. The password used for the backup is passed, and different from the device PIN.

func (*Device) DeviceInfo

func (dbb *Device) DeviceInfo() (*DeviceInfo, error)

DeviceInfo gets device information.

func (*Device) EraseBackup

func (dbb *Device) EraseBackup(filename string) error

EraseBackup deletes a backup.

func (*Device) ExtendedPublicKey

func (dbb *Device) ExtendedPublicKey(keypath signing.AbsoluteKeypath) (*hdkeychain.ExtendedKey, error)

ExtendedPublicKey implements device.Interface.

func (*Device) FeatureSet

func (dbb *Device) FeatureSet(featureSet *FeatureSet) error

FeatureSet modifies device features.

func (*Device) HasMobileChannel

func (dbb *Device) HasMobileChannel() bool

HasMobileChannel returns whether a channel to a mobile exists.

func (*Device) Identifier

func (dbb *Device) Identifier() string

Identifier implements device.Interface.

func (*Device) Init

func (dbb *Device) Init(testing bool) error

Init initialized the device. testing means the device is initialized for testnet.

func (*Device) KeystoreForConfiguration

func (dbb *Device) KeystoreForConfiguration(
	configuration *signing.Configuration,
	cosignerIndex int,
) keystoreInterface.Keystore

KeystoreForConfiguration implements device.Interface.

func (*Device) Lock

func (dbb *Device) Lock() (bool, error)

Lock locks the device for 2FA. Returns true if successful and false if aborted by the user.

func (*Device) LockBootloader

func (dbb *Device) LockBootloader() error

LockBootloader locks the bootloader.

func (*Device) Login

func (dbb *Device) Login(pin string) (bool, string, error)

Login validates the pin. This needs to be called before using any API call except for Ping() and SetPassword(). It returns whether the next login attempt requires a long-touch, and the number of remaining attempts.

func (*Device) Ping

func (dbb *Device) Ping() (bool, error)

Ping returns true if the device is initialized, and false if it is not.

func (*Device) PingMobile

func (dbb *Device) PingMobile() error

PingMobile pings the mobile if a channel exists. Only returns no error if the pong was received.

func (*Device) ProductName

func (dbb *Device) ProductName() string

ProductName implements device.Interface.

func (*Device) Random

func (dbb *Device) Random(typ string) (string, error)

Random generates a 16 byte random number, hex encoded. typ can be either "true" or "pseudo".

func (*Device) Reset

func (dbb *Device) Reset(pin string) (bool, error)

Reset resets the device. Returns true if erased and false if aborted by the user. Only callable when logged in, so the PIN can be checked.

func (*Device) RestoreBackup

func (dbb *Device) RestoreBackup(backupPassword, filename string) (bool, error)

RestoreBackup restores a backup from the SD card. Returns true if restored and false if aborted by the user.

func (*Device) SetHiddenPassword

func (dbb *Device) SetHiddenPassword(hiddenPIN string, hiddenBackupPassword string) (bool, error)

SetHiddenPassword creates a hidden pin/seed. Returns false if aborted by the user.

func (*Device) SetName

func (dbb *Device) SetName(name string) error

SetName sets the device name. Retrieve the device name using DeviceInfo().

func (*Device) SetOnEvent

func (dbb *Device) SetOnEvent(onEvent func(event.Event, interface{}))

SetOnEvent installs a callback which is called for various events.

func (*Device) SetPassword

func (dbb *Device) SetPassword(pin string) error

SetPassword defines a PIN for the device. This only works on a fresh device. If a password has already been configured, a new one cannot be set until the device is reset.

func (*Device) Sign

func (dbb *Device) Sign(
	txProposal *maketx.TxProposal,
	signatureHashes [][]byte,
	keyPaths []string,
) ([]SignatureWithRecID, error)

Sign returns signatures for the provided hashes. The private keys used to sign them are derived using the provided keyPaths.

func (*Device) StartPairing

func (dbb *Device) StartPairing() (*relay.Channel, error)

StartPairing creates, stores and returns a new channel and finishes the pairing asynchronously.

func (*Device) Status

func (dbb *Device) Status() Status

Status returns the device state. See the Status* constants.

func (*Device) UnlockBootloader

func (dbb *Device) UnlockBootloader() (bool, error)

UnlockBootloader unlocks the bootloader. It returns true on success, and false on user abort.

type DeviceInfo

type DeviceInfo struct {
	Version         string `json:"version"`
	Serial          string `json:"serial"`
	ID              string `json:"id"`
	TFA             string `json:"TFA"`
	Bootlock        bool   `json:"bootlock"`
	Name            string `json:"name"`
	SDCard          bool   `json:"sdcard"`
	Lock            bool   `json:"lock"`
	U2F             bool   `json:"U2F"`
	U2FHijack       bool   `json:"U2F_hijack"`
	Seeded          bool   `json:"seeded"`
	NewHiddenWallet bool   `json:"new_hidden_wallet"`
	Pairing         bool   `json:"pairing"`
}

DeviceInfo is the data returned from the device info api call.

type Error

type Error struct {
	Code float64
	// contains filtered or unexported fields
}

Error wraps an error by the bitbox.

func NewError

func NewError(message string, code float64) *Error

NewError creates a error with the given message and code.

func (*Error) Error

func (err *Error) Error() string

Error implements the error interface.

type FeatureSet

type FeatureSet struct {
	NewHiddenWallet *bool `json:"new_hidden_wallet,omitempty"`
	Pairing         *bool `json:"pairing,omitempty"`
}

FeatureSet are the device features one can modify with FeatureSet().

type PasswordPolicy

type PasswordPolicy struct {
	// contains filtered or unexported fields
}

PasswordPolicy represents the password policy.

func NewPasswordPolicy

func NewPasswordPolicy(mustMatchPattern string) *PasswordPolicy

NewPasswordPolicy creates a new password policy with a regular expression pattern, which is used to match the password.

func (*PasswordPolicy) ValidatePassword

func (passwordMatcher *PasswordPolicy) ValidatePassword(password string) (bool, error)

ValidatePassword evaluates a given password against the password policy. If valid, returns true if invalid, returns false and the PasswordValidationError that explains what went wrong.

type PasswordValidationError

type PasswordValidationError string

PasswordValidationError indicates an error when the given password does not comply with the policy.

func (PasswordValidationError) Error

func (p PasswordValidationError) Error() string

type SignatureWithRecID

type SignatureWithRecID struct {
	btcec.Signature
	RecID int64
}

SignatureWithRecID also contains the recoverable ID, with which one can more efficiently recover the public key.

type Status

type Status string

Status represents the device status.

const (
	// StatusBootloader means that the device is in bootloader mode, and the bootloader API can be
	// used.
	StatusBootloader Status = "bootloader"

	// StatusUninitialized is the uninitialized device, i.e. unseeded and no password set.
	// Use SetPassword() to proceed to StatusLoggedIn.
	StatusUninitialized Status = "uninitialized"

	// StatusInitialized means the password was set and the device was seeded. Use Login() to
	// proceed to StatusSeeded.
	StatusInitialized Status = "initialized"

	// StatusLoggedIn means device authentication was successful, but the device is not yet
	// seeded. Use CreateWallet() or RestoreBackup() to seed and proceed to StatusSeeded.
	StatusLoggedIn Status = "logged_in"

	// StatusSeeded means we are authenticated, and the device is seeded. We are ready to use
	// XPub(), Sign() etc.
	StatusSeeded Status = "seeded"

	// StatusRequireFirmwareUpgrade means that the a firmware upgrade is required before being able
	// to proceed to StatusLoggedIn or StatusSeeded (firmware version too old).
	StatusRequireFirmwareUpgrade Status = "require_firmware_upgrade"

	// StatusRequireAppUpgrade means that the an app upgrade is required (firmware version too new).
	StatusRequireAppUpgrade Status = "require_app_upgrade"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL