diff options
Diffstat (limited to 'accounts/scwallet/wallet.go')
-rw-r--r-- | accounts/scwallet/wallet.go | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index c2cf93965..2f40afbaa 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -41,13 +41,26 @@ import ( "github.com/ethereum/go-ethereum/log" ) +// ErrPUKNeeded is returned if opening the smart card requires pairing with a PUK +// code. In this case, the calling application should request user input to enter +// the PUK and send it back. +var ErrPUKNeeded = errors.New("smartcard: puk needed") + +// ErrPINNeeded is returned if opening the smart card requires a PIN code. In +// this case, the calling application should request user input to enter the PIN +// and send it back. +var ErrPINNeeded = errors.New("smartcard: pin needed") + +// ErrAlreadyOpen is returned if the smart card is attempted to be opened, but +// there is already a paired and unlocked session. +var ErrAlreadyOpen = errors.New("smartcard: already open") + +// ErrPubkeyMismatch is returned if the public key recovered from a signature +// does not match the one expected by the user. +var ErrPubkeyMismatch = errors.New("smartcard: recovered public key mismatch") + var ( appletAID = []byte{0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x57, 0x61, 0x6C, 0x6C, 0x65, 0x74, 0x41, 0x70, 0x70} - AlreadyOpenError = errors.New("Wallet already open") - PairingRequiredError = errors.New("Pairing required with personal.openWallet(puk)") - PinRequiredError = errors.New("Must unlock with personal.openWallet(pin)") - PubkeyMismatchError = errors.New("Could not recover matching public key from signature") - WalletChangedError = errors.New("Smartcard has been changed") DerivationSignatureHash = sha256.Sum256([]byte("STATUS KEY DERIVATION")) ) @@ -240,21 +253,17 @@ func (w *Wallet) Unpair(pin []byte) error { defer w.lock.Unlock() if !w.session.paired() { - return fmt.Errorf("Wallet %x not paired", w.PublicKey) + return fmt.Errorf("wallet %x not paired", w.PublicKey) } - if err := w.session.verifyPin(pin); err != nil { - return fmt.Errorf("Error verifying pin: %s", err) + return fmt.Errorf("failed to verify pin: %s", err) } - if err := w.session.unpair(); err != nil { - return fmt.Errorf("Error unpairing: %s", err) + return fmt.Errorf("failed to unpair: %s", err) } - if err := w.Hub.setPairing(w, nil); err != nil { return err } - return nil } @@ -306,34 +315,39 @@ func (w *Wallet) Open(passphrase string) error { w.lock.Lock() defer w.lock.Unlock() + // If the session is already open, bail out if w.session.verified { - // Already open - return AlreadyOpenError + return ErrAlreadyOpen } - + // If the smart card is not yet paired, attempt to do so either from a previous + // pairing key or form the supplied PUK code. if !w.session.paired() { - // Unpaired. + // If a previous pairing exists, only ever try to use that if pairing := w.Hub.getPairing(w); pairing != nil { - // Authenticate with the existing pairing. if err := w.session.authenticate(*pairing); err != nil { - return fmt.Errorf("Could not authenticate with paired card %x: %s", w.PublicKey[:4], err) + return fmt.Errorf("failed to authenticate card %x: %s", w.PublicKey[:4], err) } - } else if passphrase != "" { - // Establish a new pairing - return w.pair([]byte(passphrase)) - } else { - return PairingRequiredError + return nil + } + // If no passphrase was supplied, request the PUK from the user + if passphrase == "" { + return ErrPUKNeeded } + // Attempt to pair the smart card with the user supplied PUK + if err := w.pair([]byte(passphrase)); err != nil { + return err + } + return ErrPINNeeded // We always need the PIN after the PUK } - + // The smart card was successfully paired, request a PIN code or use the one + // supplied by the user if passphrase == "" { - return PinRequiredError + return ErrPINNeeded } - // Verify pin if err := w.session.verifyPin([]byte(passphrase)); err != nil { return err } - + // Smart card paired and unlocked, initialize and register w.deriveReq = make(chan chan struct{}) w.deriveQuit = make(chan chan error) @@ -990,7 +1004,7 @@ func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) { return nil, err } } - return nil, PubkeyMismatchError + return nil, ErrPubkeyMismatch } // makeRecoverableSignature uses a signature and an expected public key to @@ -1007,5 +1021,5 @@ func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) return nil, err } } - return nil, PubkeyMismatchError + return nil, ErrPubkeyMismatch } |