chore: project layout (#10)

* chore: move error, logger, types. and utils

* chore: make public methods, update references

* chore: move keycard_context

* chore: make public methods, update references

* chore: move pairing store

* chore: make public methods, update references

* chore: move flow files

* chore: make public, update references

* chore: gitignore jetbrains idea files
This commit is contained in:
Igor Sirotin 2025-01-10 12:13:43 +00:00 committed by GitHub
parent 8122bdc0f3
commit 683ce8523b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 1417 additions and 1369 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.vscode
.idea
/keycard
/build
/status-keycard-go

View File

@ -8,11 +8,11 @@ import (
"os"
"path/filepath"
skg "github.com/status-im/status-keycard-go"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
var flow *skg.KeycardFlow
var currentFlow *flow.KeycardFlow
var finished chan (struct{})
var correctPairing = "KeycardDefaultPairing"
var correctPIN = "123456"
@ -26,41 +26,41 @@ func signalHandler(j []byte) {
go func() {
switch sig.Type {
case skg.InsertCard:
case flow.InsertCard:
fmt.Print("Insert card\n")
case skg.CardInserted:
case flow.CardInserted:
fmt.Printf("Card inserted\n")
case skg.SwapCard:
case flow.SwapCard:
fmt.Printf("Swap card. Changing constraint\n")
flow.Resume(skg.FlowParams{skg.KeyUID: keyUID})
case skg.EnterPairing:
currentFlow.Resume(flow.FlowParams{flow.KeyUID: keyUID})
case flow.EnterPairing:
fmt.Printf("Entering pass: %+v\n", correctPairing)
flow.Resume(skg.FlowParams{skg.PairingPass: correctPairing})
case skg.EnterPIN:
currentFlow.Resume(flow.FlowParams{flow.PairingPass: correctPairing})
case flow.EnterPIN:
fmt.Printf("Entering PIN: %+v\n", correctPIN)
flow.Resume(skg.FlowParams{skg.PIN: correctPIN})
case skg.EnterNewPIN:
currentFlow.Resume(flow.FlowParams{flow.PIN: correctPIN})
case flow.EnterNewPIN:
fmt.Printf("Creating PIN: %+v\n", correctPIN)
flow.Resume(skg.FlowParams{skg.NewPIN: correctPIN})
case skg.EnterNewPUK:
currentFlow.Resume(flow.FlowParams{flow.NewPIN: correctPIN})
case flow.EnterNewPUK:
fmt.Printf("Creating PUK: %+v\n", correctPUK)
flow.Resume(skg.FlowParams{skg.NewPUK: correctPUK})
case skg.EnterNewPair:
currentFlow.Resume(flow.FlowParams{flow.NewPUK: correctPUK})
case flow.EnterNewPair:
fmt.Printf("Creating pairing: %+v\n", correctPairing)
flow.Resume(skg.FlowParams{skg.NewPairing: correctPairing})
case skg.EnterMnemonic:
currentFlow.Resume(flow.FlowParams{flow.NewPairing: correctPairing})
case flow.EnterMnemonic:
fmt.Printf("Loading mnemonic\n")
flow.Resume(skg.FlowParams{skg.Mnemonic: "receive fan copper bracket end train again sustain wet siren throw cigar"})
case skg.FlowResult:
currentFlow.Resume(flow.FlowParams{flow.Mnemonic: "receive fan copper bracket end train again sustain wet siren throw cigar"})
case flow.FlowResult:
fmt.Printf("Flow result: %+v\n", sig.Event)
close(finished)
}
}()
}
func testFlow(typ skg.FlowType, params skg.FlowParams) {
func testFlow(typ flow.FlowType, params flow.FlowParams) {
finished = make(chan struct{})
err := flow.Start(typ, params)
err := currentFlow.Start(typ, params)
if err != nil {
fmt.Printf("error: %+v\n", err)
@ -71,7 +71,7 @@ func testFlow(typ skg.FlowType, params skg.FlowParams) {
func testRecoverAccount() {
finished = make(chan struct{})
err := flow.Start(skg.RecoverAccount, skg.FlowParams{})
err := currentFlow.Start(flow.RecoverAccount, flow.FlowParams{})
if err != nil {
fmt.Printf("error: %+v\n", err)
@ -91,7 +91,7 @@ func main() {
pairingsFile := filepath.Join(dir, "keycard-pairings.json")
flow, err = skg.NewFlow(pairingsFile)
currentFlow, err = flow.NewFlow(pairingsFile)
if err != nil {
fmt.Printf("error: %+v\n", err)
@ -100,18 +100,18 @@ func main() {
signal.SetKeycardSignalHandler(signalHandler)
testFlow(skg.GetAppInfo, skg.FlowParams{skg.FactoryReset: true})
testFlow(skg.LoadAccount, skg.FlowParams{skg.MnemonicLen: 12})
testFlow(skg.UnpairThis, skg.FlowParams{skg.PIN: correctPIN})
testFlow(skg.RecoverAccount, skg.FlowParams{skg.PairingPass: "WrongPass", skg.PIN: "234567"})
testFlow(skg.Login, skg.FlowParams{skg.KeyUID: "60a78c98d5dd659f714eb7072bfb2c0d8a65f74a8f6aff7bb27cf56ae1feec17"})
testFlow(skg.GetAppInfo, skg.FlowParams{})
testFlow(skg.ExportPublic, skg.FlowParams{skg.BIP44Path: "m/44'/60'/0'/0/1", skg.ExportMaster: true})
testFlow(skg.ExportPublic, skg.FlowParams{skg.BIP44Path: "m/43'/60'/1581'/1'/0", skg.ExportPriv: true})
testFlow(skg.ExportPublic, skg.FlowParams{skg.BIP44Path: []interface{}{"m/44'/60'/0'/0/2", "m/44'/60'/0'/0/3", "m/44'/60'/0'/0/4"}})
testFlow(skg.Sign, skg.FlowParams{skg.TXHash: "60a78c98d5dd659f714eb7072bfb2c0d8a65f74a8f6aff7bb27cf56ae1feec17", skg.BIP44Path: "m/44'/60'/0'/0/0"})
testFlow(skg.StoreMetadata, skg.FlowParams{skg.CardName: "TestCard", skg.WalletPaths: []interface{}{"m/44'/60'/0'/0/0", "m/44'/60'/0'/0/1", "m/44'/60'/0'/0/5", "m/44'/60'/0'/0/6"}})
testFlow(skg.GetMetadata, skg.FlowParams{})
testFlow(skg.GetMetadata, skg.FlowParams{skg.ResolveAddr: true})
testFlow(skg.UnpairThis, skg.FlowParams{skg.PIN: correctPIN})
testFlow(flow.GetAppInfo, flow.FlowParams{flow.FactoryReset: true})
testFlow(flow.LoadAccount, flow.FlowParams{flow.MnemonicLen: 12})
testFlow(flow.UnpairThis, flow.FlowParams{flow.PIN: correctPIN})
testFlow(flow.RecoverAccount, flow.FlowParams{flow.PairingPass: "WrongPass", flow.PIN: "234567"})
testFlow(flow.Login, flow.FlowParams{flow.KeyUID: "60a78c98d5dd659f714eb7072bfb2c0d8a65f74a8f6aff7bb27cf56ae1feec17"})
testFlow(flow.GetAppInfo, flow.FlowParams{})
testFlow(flow.ExportPublic, flow.FlowParams{flow.BIP44Path: "m/44'/60'/0'/0/1", flow.ExportMaster: true})
testFlow(flow.ExportPublic, flow.FlowParams{flow.BIP44Path: "m/43'/60'/1581'/1'/0", flow.ExportPriv: true})
testFlow(flow.ExportPublic, flow.FlowParams{flow.BIP44Path: []interface{}{"m/44'/60'/0'/0/2", "m/44'/60'/0'/0/3", "m/44'/60'/0'/0/4"}})
testFlow(flow.Sign, flow.FlowParams{flow.TXHash: "60a78c98d5dd659f714eb7072bfb2c0d8a65f74a8f6aff7bb27cf56ae1feec17", flow.BIP44Path: "m/44'/60'/0'/0/0"})
testFlow(flow.StoreMetadata, flow.FlowParams{flow.CardName: "TestCard", flow.WalletPaths: []interface{}{"m/44'/60'/0'/0/0", "m/44'/60'/0'/0/1", "m/44'/60'/0'/0/5", "m/44'/60'/0'/0/6"}})
testFlow(flow.GetMetadata, flow.FlowParams{})
testFlow(flow.GetMetadata, flow.FlowParams{flow.ResolveAddr: true})
testFlow(flow.UnpairThis, flow.FlowParams{flow.PIN: correctPIN})
}

View File

@ -1,4 +1,4 @@
package statuskeycardgo
package internal
const (
ErrorKey = "error"

View File

@ -1,4 +1,4 @@
package statuskeycardgo
package internal
import (
"crypto/sha512"
@ -28,7 +28,7 @@ const (
Ack
)
type keycardContext struct {
type KeycardContext struct {
cardCtx *scard.Context
card *scard.Card
readers []string
@ -41,7 +41,7 @@ type keycardContext struct {
runErr error
}
func (kc *keycardContext) Transmit(apdu []byte) ([]byte, error) {
func (kc *KeycardContext) Transmit(apdu []byte) ([]byte, error) {
kc.apdu = apdu
kc.command <- Transmit
<-kc.command
@ -52,8 +52,8 @@ func (kc *keycardContext) Transmit(apdu []byte) ([]byte, error) {
return rpdu, err
}
func startKeycardContext() (*keycardContext, error) {
kctx := &keycardContext{
func StartKeycardContext() (*KeycardContext, error) {
kctx := &KeycardContext{
connected: make(chan (bool)),
command: make(chan (commandType)),
}
@ -69,14 +69,14 @@ func startKeycardContext() (*keycardContext, error) {
return kctx, nil
}
func (kc *keycardContext) run() {
func (kc *KeycardContext) run() {
runtime.LockOSThread()
var err error
defer func() {
if err != nil {
l(err.Error())
Printf(err.Error())
}
kc.runErr = err
@ -116,13 +116,13 @@ func (kc *keycardContext) run() {
}
}
func (kc *keycardContext) start() error {
func (kc *KeycardContext) start() error {
cardCtx, err := scard.EstablishContext()
if err != nil {
return errors.New(ErrorPCSC)
}
l("listing readers")
Printf("listing readers")
readers, err := cardCtx.ListReaders()
if err != nil {
return errors.New(ErrorReaderList)
@ -138,21 +138,21 @@ func (kc *keycardContext) start() error {
return nil
}
func (kc *keycardContext) stop() {
func (kc *KeycardContext) Stop() {
close(kc.command)
}
func (kc *keycardContext) connect() error {
l("waiting for card")
func (kc *KeycardContext) connect() error {
Printf("waiting for card")
index, err := kc.waitForCard(kc.cardCtx, kc.readers)
if err != nil {
return err
}
l("card found at index %d", index)
Printf("card found at index %d", index)
reader := kc.readers[index]
l("using reader %s", reader)
Printf("using reader %s", reader)
card, err := kc.cardCtx.Connect(reader, scard.ShareShared, scard.ProtocolAny)
if err != nil {
@ -169,11 +169,11 @@ func (kc *keycardContext) connect() error {
switch status.ActiveProtocol {
case scard.ProtocolT0:
l("card protocol T0")
Printf("card protocol T0")
case scard.ProtocolT1:
l("card protocol T1")
Printf("card protocol T1")
default:
l("card protocol T unknown")
Printf("card protocol T unknown")
}
kc.card = card
@ -183,7 +183,7 @@ func (kc *keycardContext) connect() error {
return nil
}
func (kc *keycardContext) waitForCard(ctx *scard.Context, readers []string) (int, error) {
func (kc *KeycardContext) waitForCard(ctx *scard.Context, readers []string) (int, error) {
rs := make([]scard.ReaderState, len(readers))
for i := range rs {
@ -207,14 +207,14 @@ func (kc *keycardContext) waitForCard(ctx *scard.Context, readers []string) (int
}
}
func (kc *keycardContext) selectApplet() (*types.ApplicationInfo, error) {
func (kc *KeycardContext) SelectApplet() (*types.ApplicationInfo, error) {
err := kc.cmdSet.Select()
if err != nil {
if e, ok := err.(*apdu.ErrBadResponse); ok && e.Sw == globalplatform.SwFileNotFound {
err = nil
kc.cmdSet.ApplicationInfo = &types.ApplicationInfo{}
} else {
l("select failed %+v", err)
Printf("select failed %+v", err)
return nil, err
}
}
@ -222,41 +222,41 @@ func (kc *keycardContext) selectApplet() (*types.ApplicationInfo, error) {
return kc.cmdSet.ApplicationInfo, nil
}
func (kc *keycardContext) pair(pairingPassword string) (*types.PairingInfo, error) {
func (kc *KeycardContext) Pair(pairingPassword string) (*types.PairingInfo, error) {
err := kc.cmdSet.Pair(pairingPassword)
if err != nil {
l("pair failed %+v", err)
Printf("Pair failed %+v", err)
return nil, err
}
return kc.cmdSet.PairingInfo, nil
}
func (kc *keycardContext) openSecureChannel(index int, key []byte) error {
func (kc *KeycardContext) OpenSecureChannel(index int, key []byte) error {
kc.cmdSet.SetPairingInfo(key, index)
err := kc.cmdSet.OpenSecureChannel()
if err != nil {
l("openSecureChannel failed %+v", err)
Printf("OpenSecureChannel failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) verifyPin(pin string) error {
func (kc *KeycardContext) VerifyPin(pin string) error {
err := kc.cmdSet.VerifyPIN(pin)
if err != nil {
l("verifyPin failed %+v", err)
Printf("VerifyPin failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) unblockPIN(puk string, newPIN string) error {
func (kc *KeycardContext) UnblockPIN(puk string, newPIN string) error {
err := kc.cmdSet.UnblockPIN(puk, newPIN)
if err != nil {
l("unblockPIN failed %+v", err)
Printf("UnblockPIN failed %+v", err)
return err
}
@ -264,41 +264,41 @@ func (kc *keycardContext) unblockPIN(puk string, newPIN string) error {
}
//lint:ignore U1000 will be used
func (kc *keycardContext) generateKey() ([]byte, error) {
func (kc *KeycardContext) GenerateKey() ([]byte, error) {
appStatus, err := kc.cmdSet.GetStatusApplication()
if err != nil {
l("getStatus failed %+v", err)
Printf("getStatus failed %+v", err)
return nil, err
}
if appStatus.KeyInitialized {
l("generateKey failed - already generated - %+v", err)
Printf("generateKey failed - already generated - %+v", err)
return nil, errors.New("key already generated")
}
keyUID, err := kc.cmdSet.GenerateKey()
if err != nil {
l("generateKey failed %+v", err)
Printf("generateKey failed %+v", err)
return nil, err
}
return keyUID, nil
}
func (kc *keycardContext) generateMnemonic(checksumSize int) ([]int, error) {
func (kc *KeycardContext) GenerateMnemonic(checksumSize int) ([]int, error) {
indexes, err := kc.cmdSet.GenerateMnemonic(checksumSize)
if err != nil {
l("generateMnemonic failed %+v", err)
Printf("generateMnemonic failed %+v", err)
return nil, err
}
return indexes, nil
}
func (kc *keycardContext) removeKey() error {
func (kc *KeycardContext) RemoveKey() error {
err := kc.cmdSet.RemoveKey()
if err != nil {
l("removeKey failed %+v", err)
Printf("removeKey failed %+v", err)
return err
}
@ -306,31 +306,31 @@ func (kc *keycardContext) removeKey() error {
}
//lint:ignore U1000 will be used
func (kc *keycardContext) deriveKey(path string) error {
func (kc *KeycardContext) DeriveKey(path string) error {
err := kc.cmdSet.DeriveKey(path)
if err != nil {
l("deriveKey failed %+v", err)
Printf("deriveKey failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) signWithPath(data []byte, path string) (*types.Signature, error) {
func (kc *KeycardContext) SignWithPath(data []byte, path string) (*types.Signature, error) {
sig, err := kc.cmdSet.SignWithPath(data, path)
if err != nil {
l("signWithPath failed %+v", err)
Printf("signWithPath failed %+v", err)
return nil, err
}
return sig, nil
}
func (kc *keycardContext) exportKey(derive bool, makeCurrent bool, onlyPublic bool, path string) (*KeyPair, error) {
func (kc *KeycardContext) ExportKey(derive bool, makeCurrent bool, onlyPublic bool, path string) (*KeyPair, error) {
address := ""
privKey, pubKey, err := kc.cmdSet.ExportKey(derive, makeCurrent, onlyPublic, path)
if err != nil {
l("exportKey failed %+v", err)
Printf("exportKey failed %+v", err)
return nil, err
}
@ -346,125 +346,125 @@ func (kc *keycardContext) exportKey(derive bool, makeCurrent bool, onlyPublic bo
return &KeyPair{Address: address, PublicKey: pubKey, PrivateKey: privKey}, nil
}
func (kc *keycardContext) loadSeed(seed []byte) ([]byte, error) {
func (kc *KeycardContext) loadSeed(seed []byte) ([]byte, error) {
pubKey, err := kc.cmdSet.LoadSeed(seed)
if err != nil {
l("loadSeed failed %+v", err)
Printf("loadSeed failed %+v", err)
return nil, err
}
return pubKey, nil
}
func (kc *keycardContext) loadMnemonic(mnemonic string, password string) ([]byte, error) {
func (kc *KeycardContext) LoadMnemonic(mnemonic string, password string) ([]byte, error) {
seed := pbkdf2.Key(norm.NFKD.Bytes([]byte(mnemonic)), norm.NFKD.Bytes([]byte(bip39Salt+password)), 2048, 64, sha512.New)
return kc.loadSeed(seed)
}
func (kc *keycardContext) init(pin, puk, pairingPassword string) error {
func (kc *KeycardContext) Init(pin, puk, pairingPassword string) error {
secrets := keycard.NewSecrets(pin, puk, pairingPassword)
err := kc.cmdSet.Init(secrets)
if err != nil {
l("init failed %+v", err)
Printf("init failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) unpair(index uint8) error {
func (kc *KeycardContext) Unpair(index uint8) error {
err := kc.cmdSet.Unpair(index)
if err != nil {
l("unpair failed %+v", err)
Printf("Unpair failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) unpairCurrent() error {
return kc.unpair(uint8(kc.cmdSet.PairingInfo.Index))
func (kc *KeycardContext) UnpairCurrent() error {
return kc.Unpair(uint8(kc.cmdSet.PairingInfo.Index))
}
func (kc *keycardContext) getStatusApplication() (*types.ApplicationStatus, error) {
func (kc *KeycardContext) GetStatusApplication() (*types.ApplicationStatus, error) {
status, err := kc.cmdSet.GetStatusApplication()
if err != nil {
l("getStatusApplication failed %+v", err)
Printf("getStatusApplication failed %+v", err)
return nil, err
}
return status, nil
}
func (kc *keycardContext) changePin(pin string) error {
func (kc *KeycardContext) ChangePin(pin string) error {
err := kc.cmdSet.ChangePIN(pin)
if err != nil {
l("chaingePin failed %+v", err)
Printf("chaingePin failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) changePuk(puk string) error {
func (kc *KeycardContext) ChangePuk(puk string) error {
err := kc.cmdSet.ChangePUK(puk)
if err != nil {
l("chaingePuk failed %+v", err)
Printf("chaingePuk failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) changePairingPassword(pairingPassword string) error {
func (kc *KeycardContext) ChangePairingPassword(pairingPassword string) error {
err := kc.cmdSet.ChangePairingSecret(pairingPassword)
if err != nil {
l("chaingePairingPassword failed %+v", err)
Printf("chaingePairingPassword failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) factoryResetFallback(retry bool) error {
func (kc *KeycardContext) factoryResetFallback(retry bool) error {
cmdSet := globalplatform.NewCommandSet(kc.c)
if err := cmdSet.Select(); err != nil {
l("select ISD failed", "error", err)
Printf("select ISD failed", "error", err)
return err
}
if err := cmdSet.OpenSecureChannel(); err != nil {
l("open secure channel failed", "error", err)
Printf("open secure channel failed", "error", err)
return err
}
aid, err := identifiers.KeycardInstanceAID(1)
if err != nil {
l("error getting keycard aid %+v", err)
Printf("error getting keycard aid %+v", err)
return err
}
if err := cmdSet.DeleteObject(aid); err != nil {
l("error deleting keycard aid %+v", err)
Printf("error deleting keycard aid %+v", err)
if retry {
return kc.factoryReset(false)
return kc.FactoryReset(false)
} else {
return err
}
}
if err := cmdSet.InstallKeycardApplet(); err != nil {
l("error installing Keycard applet %+v", err)
Printf("error installing Keycard applet %+v", err)
return err
}
return nil
}
func (kc *keycardContext) factoryReset(retry bool) error {
appInfo, err := kc.selectApplet()
func (kc *KeycardContext) FactoryReset(retry bool) error {
appInfo, err := kc.SelectApplet()
if err != nil || !appInfo.HasFactoryResetCapability() {
return kc.factoryResetFallback(retry)
@ -479,24 +479,40 @@ func (kc *keycardContext) factoryReset(retry bool) error {
return nil
}
func (kc *keycardContext) storeMetadata(metadata *types.Metadata) error {
func (kc *KeycardContext) StoreMetadata(metadata *types.Metadata) error {
err := kc.cmdSet.StoreData(keycard.P1StoreDataPublic, metadata.Serialize())
if err != nil {
l("storeMetadata failed %+v", err)
Printf("storeMetadata failed %+v", err)
return err
}
return nil
}
func (kc *keycardContext) getMetadata() (*types.Metadata, error) {
func (kc *KeycardContext) GetMetadata() (*types.Metadata, error) {
data, err := kc.cmdSet.GetData(keycard.P1StoreDataPublic)
if err != nil {
l("getMetadata failed %+v", err)
Printf("getMetadata failed %+v", err)
return nil, err
}
return types.ParseMetadata(data)
}
func (kc *KeycardContext) PairingInfo() *types.PairingInfo {
return kc.cmdSet.PairingInfo
}
func (kc *KeycardContext) ApplicationInfo() *types.ApplicationInfo {
return kc.cmdSet.ApplicationInfo
}
func (kc *KeycardContext) Connected() <-chan bool {
return kc.connected
}
func (kc *KeycardContext) RunErr() error {
return kc.runErr
}

View File

@ -1,8 +1,8 @@
package statuskeycardgo
package internal
import "fmt"
func l(format string, args ...interface{}) {
func Printf(format string, args ...interface{}) {
f := fmt.Sprintf("keycard - %s\n", format)
fmt.Printf(f, args...)
}

View File

@ -1,64 +1,64 @@
package statuskeycardgo
package internal
import (
"encoding/json"
)
type hexString []byte
type HexString []byte
// MarshalJSON serializes hexString to hex
func (s hexString) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(btox(s))
// MarshalJSON serializes HexString to hex
func (s HexString) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(Btox(s))
return bytes, err
}
// UnmarshalJSON deserializes hexString to hex
func (s *hexString) UnmarshalJSON(data []byte) error {
// UnmarshalJSON deserializes HexString to hex
func (s *HexString) UnmarshalJSON(data []byte) error {
var x string
err := json.Unmarshal(data, &x)
if err != nil {
return err
}
str, err := xtob(x)
str, err := Xtob(x)
if err != nil {
return err
}
*s = hexString([]byte(str))
*s = HexString([]byte(str))
return nil
}
type Signature struct {
R hexString `json:"r"`
S hexString `json:"s"`
R HexString `json:"r"`
S HexString `json:"s"`
V byte `json:"v"`
}
type ApplicationInfo struct {
Initialized bool `json:"initialized"`
InstanceUID hexString `json:"instanceUID"`
InstanceUID HexString `json:"instanceUID"`
Version int `json:"version"`
AvailableSlots int `json:"availableSlots"`
// KeyUID is the sha256 of of the master public key on the card.
// KeyUID is the sha256 of the master public key on the card.
// It's empty if the card doesn't contain any key.
KeyUID hexString `json:"keyUID"`
KeyUID HexString `json:"keyUID"`
}
type PairingInfo struct {
Key hexString `json:"key"`
Key HexString `json:"key"`
Index int `json:"index"`
}
type KeyPair struct {
Address string `json:"address"`
PublicKey hexString `json:"publicKey"`
PrivateKey hexString `json:"privateKey,omitempty"`
PublicKey HexString `json:"publicKey"`
PrivateKey HexString `json:"privateKey,omitempty"`
}
type Wallet struct {
Path string `json:"path"`
Address string `json:"address,omitempty"`
PublicKey hexString `json:"publicKey"`
PublicKey HexString `json:"publicKey"`
}
type Metadata struct {

View File

@ -1,4 +1,4 @@
package statuskeycardgo
package internal
import (
"encoding/binary"
@ -10,12 +10,12 @@ import (
ktypes "github.com/status-im/keycard-go/types"
)
func isSCardError(err error) bool {
func IsSCardError(err error) bool {
_, ok := err.(scard.Error)
return ok
}
func getRetries(err error) (int, bool) {
func GetRetries(err error) (int, bool) {
if wrongPIN, ok := err.(*keycard.WrongPINError); ok {
return wrongPIN.RemainingAttempts, ok
} else if wrongPUK, ok := err.(*keycard.WrongPUKError); ok {
@ -25,15 +25,15 @@ func getRetries(err error) (int, bool) {
}
}
func btox(bytes []byte) string {
func Btox(bytes []byte) string {
return hex.EncodeToString(bytes)
}
func xtob(str string) ([]byte, error) {
func Xtob(str string) ([]byte, error) {
return hex.DecodeString(str)
}
func bytesToInt(s []byte) int {
func BytesToInt(s []byte) int {
if len(s) > 4 {
return 0
}
@ -43,24 +43,24 @@ func bytesToInt(s []byte) int {
return int(binary.BigEndian.Uint32(b[:]))
}
func toAppInfo(r *ktypes.ApplicationInfo) ApplicationInfo {
func ToAppInfo(r *ktypes.ApplicationInfo) ApplicationInfo {
return ApplicationInfo{
Initialized: r.Initialized,
InstanceUID: r.InstanceUID,
Version: bytesToInt(r.Version),
AvailableSlots: bytesToInt(r.AvailableSlots),
Version: BytesToInt(r.Version),
AvailableSlots: BytesToInt(r.AvailableSlots),
KeyUID: r.KeyUID,
}
}
func toPairInfo(r *ktypes.PairingInfo) *PairingInfo {
func ToPairInfo(r *ktypes.PairingInfo) *PairingInfo {
return &PairingInfo{
Key: r.Key,
Index: r.Index,
}
}
func toSignature(r *ktypes.Signature) *Signature {
func ToSignature(r *ktypes.Signature) *Signature {
return &Signature{
R: r.R(),
S: r.S(),
@ -68,7 +68,7 @@ func toSignature(r *ktypes.Signature) *Signature {
}
}
func toMetadata(r *ktypes.Metadata) *Metadata {
func ToMetadata(r *ktypes.Metadata) *Metadata {
paths := r.Paths()
wallets := make([]Wallet, len(paths))

View File

@ -1,84 +0,0 @@
package statuskeycardgo
import (
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleGetAppInfoFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
flowStatus = FlowStatus{
PINRetries: mkf.insertedKeycard.PinRetries,
PUKRetries: mkf.insertedKeycard.PukRetries,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
flowStatus[ErrorKey] = ErrorNoKeys
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
var (
enteredPIN string
factoryReset bool
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[FactoryReset]; ok {
factoryReset = v.(bool)
}
if factoryReset {
mkf.state = Idle
*mkf.insertedKeycard = MockedKeycard{}
signal.Send(FlowResult, FlowStatus{
ErrorKey: ErrorOK,
Paired: false,
AppInfo: ApplicationInfo{
Initialized: false,
InstanceUID: []byte(""),
Version: 0,
AvailableSlots: 0,
KeyUID: []byte(""),
},
})
return
}
keycardStoresKeys := mkf.insertedKeycard.InstanceUID != "" && mkf.insertedKeycard.KeyUID != ""
if len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin || !keycardStoresKeys {
flowStatus[ErrorKey] = ErrorOK
flowStatus[Paired] = keycardStoresKeys
flowStatus[AppInfo] = ApplicationInfo{
Initialized: keycardStoresKeys,
InstanceUID: hexString(mkf.insertedKeycard.InstanceUID),
Version: 123,
AvailableSlots: mkf.insertedKeycard.FreePairingSlots,
KeyUID: hexString(mkf.insertedKeycard.KeyUID),
}
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
return
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[InstanceUID] = mkf.insertedKeycard.InstanceUID
flowStatus[KeyUID] = mkf.insertedKeycard.KeyUID
mkf.state = Paused
signal.Send(EnterPIN, flowStatus)
}

View File

@ -1,125 +0,0 @@
package statuskeycardgo
import (
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleChangePinFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" && mkf.insertedKeycard.KeyUID == "" {
flowStatus[ErrorKey] = ErrorRequireInit
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = Paused
signal.Send(EnterNewPIN, flowStatus)
return
}
if mkf.insertedKeycard.FreePairingSlots == 0 {
flowStatus[ErrorKey] = FreeSlots
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
overwrite bool
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[Overwrite]; ok {
overwrite = v.(bool)
}
finalType := EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == defPUKLen {
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
flowStatus[ErrorKey] = PUK
finalType = EnterPUK
}
}
} else {
flowStatus[ErrorKey] = ErrorUnblocking
finalType = EnterNewPIN
}
} else {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == defPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[ErrorKey] = PIN
finalType = EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
}
}
}
if len(enteredNewPIN) == 0 {
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[ErrorKey] = ErrorChanging
finalType = EnterNewPIN
}
} else {
if overwrite && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == defPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
signal.Send(FlowResult, flowStatus)
return
}
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,129 +0,0 @@
package statuskeycardgo
import (
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleChangePukFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" && mkf.insertedKeycard.KeyUID == "" {
flowStatus[ErrorKey] = ErrorRequireInit
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = Paused
signal.Send(EnterNewPIN, flowStatus)
return
}
if mkf.insertedKeycard.FreePairingSlots == 0 {
flowStatus[ErrorKey] = FreeSlots
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
enteredNewPUK string
overwrite bool
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[NewPUK]; ok {
enteredNewPUK = v.(string)
}
if v, ok := mkf.params[Overwrite]; ok {
overwrite = v.(bool)
}
finalType := EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == defPUKLen {
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
flowStatus[ErrorKey] = PUK
finalType = EnterPUK
}
}
} else {
flowStatus[ErrorKey] = ErrorUnblocking
finalType = EnterNewPIN
}
} else {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == defPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[ErrorKey] = PIN
finalType = EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == defPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if len(enteredNewPUK) == 0 {
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[ErrorKey] = ErrorChanging
finalType = EnterNewPUK
} else if overwrite && len(enteredPUK) == defPUKLen && enteredPUK == enteredNewPUK {
flowStatus[ErrorKey] = ""
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Puk = enteredPUK
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
return
}
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,145 +0,0 @@
package statuskeycardgo
import (
"math/rand"
"strconv"
"strings"
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleGetMetadataFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
mkf.state = Idle
signal.Send(FlowResult, FlowStatus{ErrorKey: ErrorNoKeys})
return
}
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
if resolveAddr, ok := mkf.params[ResolveAddr]; ok && resolveAddr.(bool) {
if mkf.insertedKeycard.FreePairingSlots == 0 {
flowStatus[ErrorKey] = FreeSlots
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
exportMaster bool
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[ExportMaster]; ok {
exportMaster = v.(bool)
}
finalType := EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == defPUKLen {
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
flowStatus[ErrorKey] = PUK
finalType = EnterPUK
}
}
} else {
flowStatus[ErrorKey] = ErrorUnblocking
finalType = EnterNewPIN
}
} else {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == defPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[ErrorKey] = PIN
finalType = EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == defPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if exportMaster {
if mkf.insertedKeycardHelper.MasterKeyAddress == "" {
iAsStr := strconv.Itoa(rand.Intn(100) + 100)
mkf.insertedKeycardHelper.MasterKeyAddress = "0x" + strings.Repeat("0", 40-len(iAsStr)) + iAsStr
}
flowStatus[MasterAddr] = mkf.insertedKeycardHelper.MasterKeyAddress
}
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[ErrorKey] = ""
flowStatus[CardMeta] = mkf.insertedKeycard.Metadata
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
return
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
return
}
pubMetadata := Metadata{
Name: mkf.insertedKeycard.Metadata.Name,
}
for _, m := range mkf.insertedKeycard.Metadata.Wallets {
pubMetadata.Wallets = append(pubMetadata.Wallets, Wallet{
Path: m.Path,
})
}
flowStatus[CardMeta] = pubMetadata
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
}

View File

@ -1,135 +0,0 @@
package statuskeycardgo
import (
"math/rand"
"strings"
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleLoadAccountFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
finalType := SwapCard
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
var (
factoryReset bool
overwrite bool
enteredMnemonicLength int
enteredMnemonic string
enteredNewPUK string
enteredPIN string
enteredNewPIN string
)
if v, ok := mkf.params[FactoryReset]; ok {
factoryReset = v.(bool)
}
if v, ok := mkf.params[Overwrite]; ok {
overwrite = v.(bool)
}
if v, ok := mkf.params[MnemonicLen]; ok {
switch t := v.(type) {
case int:
enteredMnemonicLength = t
case float64:
enteredMnemonicLength = int(t)
default:
enteredMnemonicLength = defMnemoLen
}
} else {
enteredMnemonicLength = defMnemoLen
}
if v, ok := mkf.params[Mnemonic]; ok {
enteredMnemonic = v.(string)
}
if v, ok := mkf.params[NewPUK]; ok {
enteredNewPUK = v.(string)
}
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
enteredNewPIN = v.(string)
}
if factoryReset {
*mkf.insertedKeycard = MockedKeycard{}
}
if mkf.insertedKeycard.InstanceUID != "" && mkf.insertedKeycard.KeyUID != "" {
flowStatus[ErrorKey] = ErrorHasKeys
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = Paused
signal.Send(finalType, flowStatus)
return
}
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN && len(enteredNewPUK) == defPUKLen {
if overwrite && enteredMnemonic == "" {
if mkf.insertedKeycard.InstanceUID == "" {
mkf.insertedKeycard.InstanceUID = mkf.insertedKeycardHelper.InstanceUID
mkf.insertedKeycard.PairingInfo = mkf.insertedKeycardHelper.PairingInfo
}
mkf.pairings.store(mkf.insertedKeycard.InstanceUID, mkf.insertedKeycard.PairingInfo)
var indexes []int
for len(indexes) < enteredMnemonicLength {
indexes = append(indexes, rand.Intn(2048))
}
finalType = EnterMnemonic
flowStatus[ErrorKey] = ErrorLoading
flowStatus[MnemonicIdxs] = indexes
flowStatus[InstanceUID] = mkf.insertedKeycard.InstanceUID
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
return
} else {
realMnemonicLength := len(strings.Split(enteredMnemonic, " "))
if enteredMnemonicLength == realMnemonicLength {
mkf.insertedKeycard.InstanceUID = mkf.insertedKeycardHelper.InstanceUID
mkf.insertedKeycard.PairingInfo = mkf.insertedKeycardHelper.PairingInfo
mkf.insertedKeycard.KeyUID = mkf.insertedKeycardHelper.KeyUID
mkf.insertedKeycard.Pin = enteredPIN
mkf.insertedKeycard.Puk = enteredNewPUK
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.FreePairingSlots = maxFreeSlots - 1
mkf.pairings.store(mkf.insertedKeycard.InstanceUID, mkf.insertedKeycard.PairingInfo)
finalType = FlowResult
flowStatus[InstanceUID] = mkf.insertedKeycard.InstanceUID
flowStatus[KeyUID] = mkf.insertedKeycard.KeyUID
mkf.state = Idle
signal.Send(finalType, flowStatus)
return
}
}
}
finalType = EnterNewPIN
flowStatus[ErrorKey] = ErrorRequireInit
mkf.state = Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,110 +0,0 @@
package statuskeycardgo
import (
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleLoginFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
finalType := SwapCard
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
finalType = SwapCard
flowStatus[ErrorKey] = ErrorNoKeys
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(finalType, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[PUK]; ok {
enteredPUK = v.(string)
}
finalType = EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == defPUKLen {
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
flowStatus[ErrorKey] = PUK
finalType = EnterPUK
}
}
} else {
flowStatus[ErrorKey] = ErrorUnblocking
finalType = EnterNewPIN
}
} else {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == defPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[ErrorKey] = PIN
finalType = EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == defPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[ErrorKey] = ""
flowStatus[WhisperKey] = mkf.insertedKeycardHelper.ExportedKey[whisperPath]
flowStatus[EncKey] = mkf.insertedKeycardHelper.ExportedKey[encryptionPath]
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
return
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,114 +0,0 @@
package statuskeycardgo
import (
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleRecoverAccountFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
finalType := SwapCard
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
finalType = SwapCard
flowStatus[ErrorKey] = ErrorNoKeys
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(finalType, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[PUK]; ok {
enteredPUK = v.(string)
}
finalType = EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == defPUKLen {
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
} else {
flowStatus[ErrorKey] = PUK
finalType = EnterPUK
}
}
} else {
flowStatus[ErrorKey] = ErrorUnblocking
finalType = EnterNewPIN
}
} else {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == defPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[ErrorKey] = PIN
finalType = EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == defPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[ErrorKey] = ""
flowStatus[MasterKey] = mkf.insertedKeycardHelper.ExportedKey[masterPath]
flowStatus[WalleRootKey] = mkf.insertedKeycardHelper.ExportedKey[walletRoothPath]
flowStatus[WalletKey] = mkf.insertedKeycardHelper.ExportedKey[walletPath]
flowStatus[EIP1581Key] = mkf.insertedKeycardHelper.ExportedKey[eip1581Path]
flowStatus[WhisperKey] = mkf.insertedKeycardHelper.ExportedKey[whisperPath]
flowStatus[EncKey] = mkf.insertedKeycardHelper.ExportedKey[encryptionPath]
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
return
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,94 +0,0 @@
package statuskeycardgo
import (
"strconv"
"strings"
"github.com/status-im/status-keycard-go/signal"
)
func (mkf *MockedKeycardFlow) handleStoreMetadataFlow() {
flowStatus := FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
return
}
finalType := FlowResult
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
}
var (
enteredPIN string
enteredCardName string
)
if v, ok := mkf.params[PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[CardName]; ok {
enteredCardName = v.(string)
}
if len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin && enteredCardName != "" {
mkf.insertedKeycard.Metadata.Name = enteredCardName
mkf.insertedKeycard.Metadata.Wallets = []Wallet{}
if v, ok := mkf.params[WalletPaths]; ok {
wallets := v.([]interface{})
for i, p := range wallets {
if !strings.HasPrefix(p.(string), walletRoothPath) {
panic("path must start with " + walletRoothPath)
}
tmpWallet := Wallet{
Path: p.(string),
}
found := false
for _, w := range mkf.insertedKeycardHelper.Metadata.Wallets {
if w.Path == tmpWallet.Path {
found = true
tmpWallet = w
break
}
}
if !found {
iAsStr := strconv.Itoa(i + 1)
tmpWallet.Address = "0x" + strings.Repeat("0", 40-len(iAsStr)) + iAsStr
tmpWallet.PublicKey = []byte(strings.Repeat("0", 130-len(iAsStr)) + iAsStr)
mkf.insertedKeycardHelper.Metadata.Wallets = append(mkf.insertedKeycardHelper.Metadata.Wallets, tmpWallet)
}
mkf.insertedKeycard.Metadata.Wallets = append(mkf.insertedKeycard.Metadata.Wallets, tmpWallet)
}
}
mkf.state = Idle
signal.Send(finalType, flowStatus)
return
}
if len(enteredPIN) != defPINLen || enteredPIN != mkf.insertedKeycard.Pin {
finalType = EnterPIN
} else if enteredCardName == "" {
finalType = EnterName
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,4 +1,4 @@
package statuskeycardgo
package flow
import (
"errors"
@ -8,34 +8,35 @@ import (
"github.com/status-im/keycard-go/apdu"
"github.com/status-im/keycard-go/derivationpath"
ktypes "github.com/status-im/keycard-go/types"
"github.com/status-im/status-keycard-go/internal"
)
func (f *KeycardFlow) factoryReset(kc *keycardContext) error {
err := kc.factoryReset(true)
func (f *KeycardFlow) factoryReset(kc *internal.KeycardContext) error {
err := kc.FactoryReset(true)
if err == nil {
delete(f.params, FactoryReset)
return restartErr()
} else if isSCardError(err) {
} else if internal.IsSCardError(err) {
return restartErr()
} else {
return err
}
}
func (f *KeycardFlow) selectKeycard(kc *keycardContext) error {
appInfo, err := kc.selectApplet()
func (f *KeycardFlow) selectKeycard(kc *internal.KeycardContext) error {
appInfo, err := kc.SelectApplet()
if err != nil {
return restartErr()
}
f.cardInfo.instanceUID = btox(appInfo.InstanceUID)
f.cardInfo.keyUID = btox(appInfo.KeyUID)
f.cardInfo.freeSlots = bytesToInt(appInfo.AvailableSlots)
f.cardInfo.instanceUID = internal.Btox(appInfo.InstanceUID)
f.cardInfo.keyUID = internal.Btox(appInfo.KeyUID)
f.cardInfo.freeSlots = internal.BytesToInt(appInfo.AvailableSlots)
if !appInfo.Installed {
return f.pauseAndRestart(SwapCard, ErrorNotAKeycard)
return f.pauseAndRestart(SwapCard, internal.ErrorNotAKeycard)
}
if requiredInstanceUID, ok := f.params[InstanceUID]; ok {
@ -53,7 +54,7 @@ func (f *KeycardFlow) selectKeycard(kc *keycardContext) error {
return nil
}
func (f *KeycardFlow) pair(kc *keycardContext) error {
func (f *KeycardFlow) pair(kc *internal.KeycardContext) error {
if f.cardInfo.freeSlots == 0 {
return f.pauseAndRestart(SwapCard, FreeSlots)
}
@ -64,17 +65,17 @@ func (f *KeycardFlow) pair(kc *keycardContext) error {
pairingPass = DefPairing
}
pairing, err := kc.pair(pairingPass.(string))
pairing, err := kc.Pair(pairingPass.(string))
if err == nil {
return f.pairings.store(f.cardInfo.instanceUID, toPairInfo(pairing))
} else if isSCardError(err) {
return f.pairings.Store(f.cardInfo.instanceUID, internal.ToPairInfo(pairing))
} else if internal.IsSCardError(err) {
return restartErr()
}
delete(f.params, PairingPass)
err = f.pauseAndWait(EnterPairing, ErrorPairing)
err = f.pauseAndWait(EnterPairing, internal.ErrorPairing)
if err != nil {
return err
@ -83,11 +84,11 @@ func (f *KeycardFlow) pair(kc *keycardContext) error {
return f.pair(kc)
}
func (f *KeycardFlow) initCard(kc *keycardContext) error {
func (f *KeycardFlow) initCard(kc *internal.KeycardContext) error {
newPIN, pinOK := f.params[NewPIN]
if !pinOK {
err := f.pauseAndWait(EnterNewPIN, ErrorRequireInit)
err := f.pauseAndWait(EnterNewPIN, internal.ErrorRequireInit)
if err != nil {
return err
}
@ -97,7 +98,7 @@ func (f *KeycardFlow) initCard(kc *keycardContext) error {
newPUK, pukOK := f.params[NewPUK]
if !pukOK {
err := f.pauseAndWait(EnterNewPUK, ErrorRequireInit)
err := f.pauseAndWait(EnterNewPUK, internal.ErrorRequireInit)
if err != nil {
return err
}
@ -110,9 +111,9 @@ func (f *KeycardFlow) initCard(kc *keycardContext) error {
newPairing = DefPairing
}
err := kc.init(newPIN.(string), newPUK.(string), newPairing.(string))
err := kc.Init(newPIN.(string), newPUK.(string), newPairing.(string))
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
} else if err != nil {
return err
@ -127,20 +128,20 @@ func (f *KeycardFlow) initCard(kc *keycardContext) error {
return restartErr()
}
func (f *KeycardFlow) openSC(kc *keycardContext, giveup bool) error {
var pairing *PairingInfo
func (f *KeycardFlow) openSC(kc *internal.KeycardContext, giveup bool) error {
var pairing *internal.PairingInfo
if !kc.cmdSet.ApplicationInfo.Initialized && !giveup {
if !kc.ApplicationInfo().Initialized && !giveup {
return f.initCard(kc)
} else {
pairing = f.pairings.get(f.cardInfo.instanceUID)
pairing = f.pairings.Get(f.cardInfo.instanceUID)
}
if pairing != nil {
err := kc.openSecureChannel(pairing.Index, pairing.Key)
err := kc.OpenSecureChannel(pairing.Index, pairing.Key)
if err == nil {
appStatus, err := kc.getStatusApplication()
appStatus, err := kc.GetStatusApplication()
if err != nil {
// getStatus can only fail for connection errors
@ -151,11 +152,11 @@ func (f *KeycardFlow) openSC(kc *keycardContext, giveup bool) error {
f.cardInfo.pukRetries = appStatus.PUKRetryCount
return nil
} else if isSCardError(err) {
} else if internal.IsSCardError(err) {
return restartErr()
}
f.pairings.delete(f.cardInfo.instanceUID)
f.pairings.Delete(f.cardInfo.instanceUID)
}
if giveup {
@ -171,7 +172,7 @@ func (f *KeycardFlow) openSC(kc *keycardContext, giveup bool) error {
return f.openSC(kc, giveup)
}
func (f *KeycardFlow) unblockPIN(kc *keycardContext) error {
func (f *KeycardFlow) unblockPIN(kc *internal.KeycardContext) error {
if f.cardInfo.pukRetries == 0 {
return f.pauseAndRestart(SwapCard, PUKRetries)
}
@ -183,18 +184,18 @@ func (f *KeycardFlow) unblockPIN(kc *keycardContext) error {
puk, pukOK := f.params[PUK]
if pinOK && pukOK {
err = kc.unblockPIN(puk.(string), newPIN.(string))
err = kc.UnblockPIN(puk.(string), newPIN.(string))
if err == nil {
f.cardInfo.pinRetries = maxPINRetries
f.cardInfo.pukRetries = maxPUKRetries
f.cardInfo.pinRetries = MaxPINRetries
f.cardInfo.pukRetries = MaxPUKRetries
f.params[PIN] = newPIN
delete(f.params, NewPIN)
delete(f.params, PUK)
return nil
} else if isSCardError(err) {
} else if internal.IsSCardError(err) {
return restartErr()
} else if leftRetries, ok := getRetries(err); ok {
} else if leftRetries, ok := internal.GetRetries(err); ok {
f.cardInfo.pukRetries = leftRetries
delete(f.params, PUK)
pukOK = false
@ -210,7 +211,7 @@ func (f *KeycardFlow) unblockPIN(kc *keycardContext) error {
if !pukOK {
err = f.pauseAndWait(EnterPUK, pukError)
} else if !pinOK {
err = f.pauseAndWait(EnterNewPIN, ErrorUnblocking)
err = f.pauseAndWait(EnterNewPIN, internal.ErrorUnblocking)
}
if err != nil {
@ -220,7 +221,7 @@ func (f *KeycardFlow) unblockPIN(kc *keycardContext) error {
return f.unblockPIN(kc)
}
func (f *KeycardFlow) authenticate(kc *keycardContext) error {
func (f *KeycardFlow) authenticate(kc *internal.KeycardContext) error {
if f.cardInfo.pinRetries == 0 {
// succesful unblock leaves the card authenticated
return f.unblockPIN(kc)
@ -229,14 +230,14 @@ func (f *KeycardFlow) authenticate(kc *keycardContext) error {
pinError := ""
if pin, ok := f.params[PIN]; ok {
err := kc.verifyPin(pin.(string))
err := kc.VerifyPin(pin.(string))
if err == nil {
f.cardInfo.pinRetries = maxPINRetries
f.cardInfo.pinRetries = MaxPINRetries
return nil
} else if isSCardError(err) {
} else if internal.IsSCardError(err) {
return restartErr()
} else if leftRetries, ok := getRetries(err); ok {
} else if leftRetries, ok := internal.GetRetries(err); ok {
f.cardInfo.pinRetries = leftRetries
delete(f.params, PIN)
}
@ -257,7 +258,7 @@ func (f *KeycardFlow) authenticate(kc *keycardContext) error {
return f.authenticate(kc)
}
func (f *KeycardFlow) openSCAndAuthenticate(kc *keycardContext, giveup bool) error {
func (f *KeycardFlow) openSCAndAuthenticate(kc *internal.KeycardContext, giveup bool) error {
err := f.openSC(kc, giveup)
if err != nil {
@ -267,61 +268,61 @@ func (f *KeycardFlow) openSCAndAuthenticate(kc *keycardContext, giveup bool) err
return f.authenticate(kc)
}
func (f *KeycardFlow) unpairCurrent(kc *keycardContext) error {
err := kc.unpairCurrent()
func (f *KeycardFlow) unpairCurrent(kc *internal.KeycardContext) error {
err := kc.UnpairCurrent()
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
}
return err
}
func (f *KeycardFlow) unpair(kc *keycardContext, idx int) error {
err := kc.unpair(uint8(idx))
func (f *KeycardFlow) unpair(kc *internal.KeycardContext, idx int) error {
err := kc.Unpair(uint8(idx))
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
}
return err
}
func (f *KeycardFlow) removeKey(kc *keycardContext) error {
err := kc.removeKey()
func (f *KeycardFlow) removeKey(kc *internal.KeycardContext) error {
err := kc.RemoveKey()
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
}
return err
}
func (f *KeycardFlow) getMetadata(kc *keycardContext) (*Metadata, error) {
m, err := kc.getMetadata()
func (f *KeycardFlow) getMetadata(kc *internal.KeycardContext) (*internal.Metadata, error) {
m, err := kc.GetMetadata()
if err == nil {
return toMetadata(m), nil
} else if isSCardError(err) {
return internal.ToMetadata(m), nil
} else if internal.IsSCardError(err) {
return nil, restartErr()
} else if serr, ok := err.(*apdu.ErrBadResponse); ok {
if serr.Sw == 0x6d00 {
return nil, errors.New(ErrorNoKeys)
return nil, errors.New(internal.ErrorNoKeys)
} else {
return nil, err
}
} else if err == io.EOF {
return nil, errors.New(ErrorNoData)
return nil, errors.New(internal.ErrorNoData)
} else {
return nil, err
}
}
func (f *KeycardFlow) storeMetadata(kc *keycardContext) error {
func (f *KeycardFlow) storeMetadata(kc *internal.KeycardContext) error {
cardName, cardNameOK := f.params[CardName]
if !cardNameOK {
err := f.pauseAndWait(EnterName, ErrorStoreMeta)
err := f.pauseAndWait(EnterName, internal.ErrorStoreMeta)
if err != nil {
return err
}
@ -332,7 +333,7 @@ func (f *KeycardFlow) storeMetadata(kc *keycardContext) error {
w, walletsOK := f.params[WalletPaths]
if !walletsOK {
err := f.pauseAndWait(EnterWallets, ErrorStoreMeta)
err := f.pauseAndWait(EnterWallets, internal.ErrorStoreMeta)
if err != nil {
return err
}
@ -344,8 +345,8 @@ func (f *KeycardFlow) storeMetadata(kc *keycardContext) error {
paths := make([]uint32, len(wallets))
for i, p := range wallets {
if !strings.HasPrefix(p.(string), walletRoothPath) {
return errors.New("path must start with " + walletRoothPath)
if !strings.HasPrefix(p.(string), WalletRoothPath) {
return errors.New("path must start with " + WalletRoothPath)
}
_, components, err := derivationpath.Decode(p.(string))
@ -361,26 +362,26 @@ func (f *KeycardFlow) storeMetadata(kc *keycardContext) error {
return err
}
err = kc.storeMetadata(m)
err = kc.StoreMetadata(m)
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
}
return err
}
func (f *KeycardFlow) exportKey(kc *keycardContext, path string, onlyPublic bool) (*KeyPair, error) {
keyPair, err := kc.exportKey(true, path == masterPath, onlyPublic, path)
func (f *KeycardFlow) exportKey(kc *internal.KeycardContext, path string, onlyPublic bool) (*internal.KeyPair, error) {
keyPair, err := kc.ExportKey(true, path == MasterPath, onlyPublic, path)
if isSCardError(err) {
if internal.IsSCardError(err) {
return nil, restartErr()
}
return keyPair, err
}
func (f *KeycardFlow) exportBIP44Key(kc *keycardContext) (interface{}, error) {
func (f *KeycardFlow) exportBIP44Key(kc *internal.KeycardContext) (interface{}, error) {
if path, ok := f.params[BIP44Path]; ok {
exportPrivParam, ok := f.params[ExportPriv]
exportPrivate := (!ok || !exportPrivParam.(bool))
@ -388,7 +389,7 @@ func (f *KeycardFlow) exportBIP44Key(kc *keycardContext) (interface{}, error) {
if pathStr, ok := path.(string); ok {
return f.exportKey(kc, pathStr, exportPrivate)
} else if paths, ok := path.([]interface{}); ok {
keys := make([]*KeyPair, len(paths))
keys := make([]*internal.KeyPair, len(paths))
for i, path := range paths {
key, err := f.exportKey(kc, path.(string), exportPrivate)
@ -406,7 +407,7 @@ func (f *KeycardFlow) exportBIP44Key(kc *keycardContext) (interface{}, error) {
}
}
err := f.pauseAndWait(EnterPath, ErrorExporting)
err := f.pauseAndWait(EnterPath, internal.ErrorExporting)
if err != nil {
return nil, err
@ -415,17 +416,17 @@ func (f *KeycardFlow) exportBIP44Key(kc *keycardContext) (interface{}, error) {
return f.exportBIP44Key(kc)
}
func (f *KeycardFlow) loadKeys(kc *keycardContext) error {
func (f *KeycardFlow) loadKeys(kc *internal.KeycardContext) error {
if mnemonic, ok := f.params[Mnemonic]; ok {
keyUID, err := kc.loadMnemonic(mnemonic.(string), "")
keyUID, err := kc.LoadMnemonic(mnemonic.(string), "")
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
} else if err != nil {
return err
}
f.cardInfo.keyUID = btox(keyUID)
f.cardInfo.keyUID = internal.Btox(keyUID)
return nil
}
@ -438,21 +439,21 @@ func (f *KeycardFlow) loadKeys(kc *keycardContext) error {
case float64:
mnemonicLength = int(t)
default:
mnemonicLength = defMnemoLen
mnemonicLength = DefMnemoLen
}
} else {
mnemonicLength = defMnemoLen
mnemonicLength = DefMnemoLen
}
indexes, err := kc.generateMnemonic(mnemonicLength / 3)
indexes, err := kc.GenerateMnemonic(mnemonicLength / 3)
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
} else if err != nil {
return err
}
err = f.pauseAndWaitWithStatus(EnterMnemonic, ErrorLoading, FlowParams{MnemonicIdxs: indexes})
err = f.pauseAndWaitWithStatus(EnterMnemonic, internal.ErrorLoading, FlowParams{MnemonicIdxs: indexes})
if err != nil {
return err
@ -461,11 +462,11 @@ func (f *KeycardFlow) loadKeys(kc *keycardContext) error {
return f.loadKeys(kc)
}
func (f *KeycardFlow) changePIN(kc *keycardContext) error {
func (f *KeycardFlow) changePIN(kc *internal.KeycardContext) error {
if newPIN, ok := f.params[NewPIN]; ok {
err := kc.changePin(newPIN.(string))
err := kc.ChangePin(newPIN.(string))
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
} else if err != nil {
return err
@ -474,7 +475,7 @@ func (f *KeycardFlow) changePIN(kc *keycardContext) error {
return nil
}
err := f.pauseAndWait(EnterNewPIN, ErrorChanging)
err := f.pauseAndWait(EnterNewPIN, internal.ErrorChanging)
if err != nil {
return err
@ -483,11 +484,11 @@ func (f *KeycardFlow) changePIN(kc *keycardContext) error {
return f.changePIN(kc)
}
func (f *KeycardFlow) changePUK(kc *keycardContext) error {
func (f *KeycardFlow) changePUK(kc *internal.KeycardContext) error {
if newPUK, ok := f.params[NewPUK]; ok {
err := kc.changePuk(newPUK.(string))
err := kc.ChangePuk(newPUK.(string))
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
} else if err != nil {
return err
@ -496,7 +497,7 @@ func (f *KeycardFlow) changePUK(kc *keycardContext) error {
return nil
}
err := f.pauseAndWait(EnterNewPUK, ErrorChanging)
err := f.pauseAndWait(EnterNewPUK, internal.ErrorChanging)
if err != nil {
return err
@ -505,11 +506,11 @@ func (f *KeycardFlow) changePUK(kc *keycardContext) error {
return f.changePUK(kc)
}
func (f *KeycardFlow) changePairing(kc *keycardContext) error {
func (f *KeycardFlow) changePairing(kc *internal.KeycardContext) error {
if newPairing, ok := f.params[NewPairing]; ok {
err := kc.changePairingPassword(newPairing.(string))
err := kc.ChangePairingPassword(newPairing.(string))
if isSCardError(err) {
if internal.IsSCardError(err) {
return restartErr()
} else if err != nil {
return err
@ -518,7 +519,7 @@ func (f *KeycardFlow) changePairing(kc *keycardContext) error {
return nil
}
err := f.pauseAndWait(EnterNewPair, ErrorChanging)
err := f.pauseAndWait(EnterNewPair, internal.ErrorChanging)
if err != nil {
return err
@ -527,13 +528,13 @@ func (f *KeycardFlow) changePairing(kc *keycardContext) error {
return f.changePairing(kc)
}
func (f *KeycardFlow) sign(kc *keycardContext) (*Signature, error) {
func (f *KeycardFlow) sign(kc *internal.KeycardContext) (*internal.Signature, error) {
var err error
path, pathOK := f.params[BIP44Path]
if !pathOK {
err = f.pauseAndWait(EnterPath, ErrorSigning)
err = f.pauseAndWait(EnterPath, internal.ErrorSigning)
if err != nil {
return nil, err
}
@ -546,14 +547,14 @@ func (f *KeycardFlow) sign(kc *keycardContext) (*Signature, error) {
var rawHash []byte
if hashOK {
rawHash, err = xtob(hash.(string))
rawHash, err = internal.Xtob(hash.(string))
if err != nil {
hashOK = false
}
}
if !hashOK {
err := f.pauseAndWait(EnterTXHash, ErrorSigning)
err := f.pauseAndWait(EnterTXHash, internal.ErrorSigning)
if err != nil {
return nil, err
}
@ -561,13 +562,13 @@ func (f *KeycardFlow) sign(kc *keycardContext) (*Signature, error) {
return f.sign(kc)
}
signature, err := kc.signWithPath(rawHash, path.(string))
signature, err := kc.SignWithPath(rawHash, path.(string))
if isSCardError(err) {
if internal.IsSCardError(err) {
return nil, restartErr()
} else if err != nil {
return nil, err
}
return toSignature(signature), nil
return internal.ToSignature(signature), nil
}

View File

@ -1,10 +1,12 @@
package statuskeycardgo
package flow
import (
"errors"
"time"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/pairing"
)
type cardStatus struct {
@ -17,15 +19,15 @@ type cardStatus struct {
type KeycardFlow struct {
flowType FlowType
state runState
state RunState
wakeUp chan (struct{})
pairings *pairingStore
pairings *pairing.Store
params FlowParams
cardInfo cardStatus
}
func NewFlow(storageDir string) (*KeycardFlow, error) {
p, err := newPairingStore(storageDir)
p, err := pairing.NewStore(storageDir)
if err != nil {
return nil, err
@ -92,7 +94,7 @@ func (f *KeycardFlow) runFlow() {
if _, ok := err.(*restartError); !ok {
if result == nil {
result = FlowStatus{ErrorKey: err.Error()}
result = FlowStatus{internal.ErrorKey: err.Error()}
if f.cardInfo.freeSlots != -1 {
result[InstanceUID] = f.cardInfo.instanceUID
result[KeyUID] = f.cardInfo.keyUID
@ -111,7 +113,7 @@ func (f *KeycardFlow) runFlow() {
}
func (f *KeycardFlow) pause(action string, errMsg string, status FlowParams) {
status[ErrorKey] = errMsg
status[internal.ErrorKey] = errMsg
if f.cardInfo.freeSlots != -1 {
status[InstanceUID] = f.cardInfo.instanceUID
@ -163,7 +165,7 @@ func (f *KeycardFlow) requireKeys() error {
return nil
}
return f.pauseAndRestart(SwapCard, ErrorNoKeys)
return f.pauseAndRestart(SwapCard, internal.ErrorNoKeys)
}
func (f *KeycardFlow) requireNoKeys() error {
@ -175,17 +177,17 @@ func (f *KeycardFlow) requireNoKeys() error {
return nil
}
return f.pauseAndRestart(SwapCard, ErrorHasKeys)
return f.pauseAndRestart(SwapCard, internal.ErrorHasKeys)
}
func (f *KeycardFlow) closeKeycard(kc *keycardContext) {
func (f *KeycardFlow) closeKeycard(kc *internal.KeycardContext) {
if kc != nil {
kc.stop()
kc.Stop()
}
}
func (f *KeycardFlow) connect() (*keycardContext, error) {
kc, err := startKeycardContext()
func (f *KeycardFlow) connect() (*internal.KeycardContext, error) {
kc, err := internal.StartKeycardContext()
if err != nil {
return nil, err
@ -200,8 +202,8 @@ func (f *KeycardFlow) connect() (*keycardContext, error) {
panic("Resuming is not expected during connection")
}
return nil, giveupErr()
case <-kc.connected:
if kc.runErr != nil {
case <-kc.Connected():
if kc.RunErr() != nil {
return nil, restartErr()
}
t.Stop()
@ -212,7 +214,7 @@ func (f *KeycardFlow) connect() (*keycardContext, error) {
return kc, nil
case <-t.C:
f.pause(InsertCard, ErrorConnection, FlowParams{})
f.pause(InsertCard, internal.ErrorConnection, FlowParams{})
}
}
}
@ -269,12 +271,12 @@ func (f *KeycardFlow) connectedFlow() (FlowStatus, error) {
case GetMetadata:
return f.getMetadataFlow(kc)
default:
return nil, errors.New(ErrorUnknownFlow)
return nil, errors.New(internal.ErrorUnknownFlow)
}
}
func (f *KeycardFlow) getAppInfoFlow(kc *keycardContext) (FlowStatus, error) {
res := FlowStatus{ErrorKey: ErrorOK, AppInfo: toAppInfo(kc.cmdSet.ApplicationInfo)}
func (f *KeycardFlow) getAppInfoFlow(kc *internal.KeycardContext) (FlowStatus, error) {
res := FlowStatus{internal.ErrorKey: internal.ErrorOK, AppInfo: internal.ToAppInfo(kc.ApplicationInfo())}
err := f.openSCAndAuthenticate(kc, true)
if err == nil {
@ -290,7 +292,7 @@ func (f *KeycardFlow) getAppInfoFlow(kc *keycardContext) (FlowStatus, error) {
return res, nil
}
func (f *KeycardFlow) exportKeysFlow(kc *keycardContext, recover bool) (FlowStatus, error) {
func (f *KeycardFlow) exportKeysFlow(kc *internal.KeycardContext, recover bool) (FlowStatus, error) {
err := f.requireKeys()
if err != nil {
@ -305,38 +307,38 @@ func (f *KeycardFlow) exportKeysFlow(kc *keycardContext, recover bool) (FlowStat
result := FlowStatus{KeyUID: f.cardInfo.keyUID, InstanceUID: f.cardInfo.instanceUID}
key, err := f.exportKey(kc, encryptionPath, false)
key, err := f.exportKey(kc, EncryptionPath, false)
if err != nil {
return nil, err
}
result[EncKey] = key
key, err = f.exportKey(kc, whisperPath, false)
key, err = f.exportKey(kc, WhisperPath, false)
if err != nil {
return nil, err
}
result[WhisperKey] = key
if recover {
key, err = f.exportKey(kc, eip1581Path, true)
key, err = f.exportKey(kc, Eip1581Path, true)
if err != nil {
return nil, err
}
result[EIP1581Key] = key
key, err = f.exportKey(kc, walletRoothPath, true)
key, err = f.exportKey(kc, WalletRoothPath, true)
if err != nil {
return nil, err
}
result[WalleRootKey] = key
key, err = f.exportKey(kc, walletPath, true)
key, err = f.exportKey(kc, WalletPath, true)
if err != nil {
return nil, err
}
result[WalletKey] = key
key, err = f.exportKey(kc, masterPath, true)
key, err = f.exportKey(kc, MasterPath, true)
if err != nil {
return nil, err
}
@ -346,7 +348,7 @@ func (f *KeycardFlow) exportKeysFlow(kc *keycardContext, recover bool) (FlowStat
return result, nil
}
func (f *KeycardFlow) exportPublicFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) exportPublicFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.requireKeys()
if err != nil {
@ -362,7 +364,7 @@ func (f *KeycardFlow) exportPublicFlow(kc *keycardContext) (FlowStatus, error) {
result := FlowStatus{KeyUID: f.cardInfo.keyUID, InstanceUID: f.cardInfo.instanceUID}
if exportMaster, ok := f.params[ExportMaster]; ok && exportMaster.(bool) {
masterKey, err := f.exportKey(kc, masterPath, true)
masterKey, err := f.exportKey(kc, MasterPath, true)
result[MasterAddr] = masterKey.Address
if err != nil {
@ -381,7 +383,7 @@ func (f *KeycardFlow) exportPublicFlow(kc *keycardContext) (FlowStatus, error) {
return result, nil
}
func (f *KeycardFlow) loadKeysFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) loadKeysFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.requireNoKeys()
if err != nil {
@ -403,7 +405,7 @@ func (f *KeycardFlow) loadKeysFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{KeyUID: f.cardInfo.keyUID, InstanceUID: f.cardInfo.instanceUID}, nil
}
func (f *KeycardFlow) signFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) signFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.requireKeys()
if err != nil {
@ -425,7 +427,7 @@ func (f *KeycardFlow) signFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{KeyUID: f.cardInfo.keyUID, InstanceUID: f.cardInfo.instanceUID, TXSignature: signature}, nil
}
func (f *KeycardFlow) changePINFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) changePINFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, false)
if err != nil {
@ -441,7 +443,7 @@ func (f *KeycardFlow) changePINFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID}, nil
}
func (f *KeycardFlow) changePUKFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) changePUKFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, false)
if err != nil {
@ -457,7 +459,7 @@ func (f *KeycardFlow) changePUKFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID}, nil
}
func (f *KeycardFlow) changePairingFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) changePairingFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, false)
if err != nil {
@ -473,7 +475,7 @@ func (f *KeycardFlow) changePairingFlow(kc *keycardContext) (FlowStatus, error)
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID}, nil
}
func (f *KeycardFlow) unpairThisFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) unpairThisFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, true)
if err != nil {
@ -490,15 +492,15 @@ func (f *KeycardFlow) unpairThisFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID, FreeSlots: f.cardInfo.freeSlots}, nil
}
func (f *KeycardFlow) unpairOthersFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) unpairOthersFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, true)
if err != nil {
return nil, err
}
for i := 0; i < maxFreeSlots; i++ {
if i == kc.cmdSet.PairingInfo.Index {
for i := 0; i < MaxFreeSlots; i++ {
if i == kc.PairingInfo().Index {
continue
}
@ -513,7 +515,7 @@ func (f *KeycardFlow) unpairOthersFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID, FreeSlots: f.cardInfo.freeSlots}, nil
}
func (f *KeycardFlow) deleteUnpairFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) deleteUnpairFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, true)
if err != nil {
@ -539,7 +541,7 @@ func (f *KeycardFlow) deleteUnpairFlow(kc *keycardContext) (FlowStatus, error) {
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID, FreeSlots: f.cardInfo.freeSlots}, nil
}
func (f *KeycardFlow) storeMetadataFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) storeMetadataFlow(kc *internal.KeycardContext) (FlowStatus, error) {
err := f.openSCAndAuthenticate(kc, false)
if err != nil {
@ -555,7 +557,7 @@ func (f *KeycardFlow) storeMetadataFlow(kc *keycardContext) (FlowStatus, error)
return FlowStatus{InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID}, nil
}
func (f *KeycardFlow) getMetadataFlow(kc *keycardContext) (FlowStatus, error) {
func (f *KeycardFlow) getMetadataFlow(kc *internal.KeycardContext) (FlowStatus, error) {
m, err := f.getMetadata(kc)
if err != nil {
@ -566,7 +568,7 @@ func (f *KeycardFlow) getMetadataFlow(kc *keycardContext) (FlowStatus, error) {
if resolveAddr, ok := f.params[ResolveAddr]; ok && resolveAddr.(bool) {
if f.cardInfo.keyUID == "" {
return FlowStatus{ErrorKey: ErrorNoKeys, InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID, CardMeta: m}, nil
return FlowStatus{internal.ErrorKey: internal.ErrorNoKeys, InstanceUID: f.cardInfo.instanceUID, KeyUID: f.cardInfo.keyUID, CardMeta: m}, nil
}
err := f.openSCAndAuthenticate(kc, false)
@ -576,7 +578,7 @@ func (f *KeycardFlow) getMetadataFlow(kc *keycardContext) (FlowStatus, error) {
}
if exportMaster, ok := f.params[ExportMaster]; ok && exportMaster.(bool) {
masterKey, err := f.exportKey(kc, masterPath, true)
masterKey, err := f.exportKey(kc, MasterPath, true)
result[MasterAddr] = masterKey.Address
if err != nil {

View File

@ -1,4 +1,4 @@
package statuskeycardgo
package mocked
import (
"encoding/json"
@ -7,13 +7,16 @@ import (
"path/filepath"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/pairing"
"github.com/status-im/status-keycard-go/pkg/flow"
)
type MockedKeycardFlow struct {
flowType FlowType
state runState
params FlowParams
pairings *pairingStore
flowType flow.FlowType
state flow.RunState
params flow.FlowParams
pairings *pairing.Store
mockedKeycardsStoreFilePath string
@ -27,7 +30,7 @@ type MockedKeycardFlow struct {
}
func NewMockedFlow(storageDir string) (*MockedKeycardFlow, error) {
p, err := newPairingStore(storageDir)
p, err := pairing.NewStore(storageDir)
if err != nil {
return nil, err
}
@ -48,27 +51,27 @@ func NewMockedFlow(storageDir string) (*MockedKeycardFlow, error) {
return flow, nil
}
func (mkf *MockedKeycardFlow) Start(flowType FlowType, params FlowParams) error {
if mkf.state != Idle {
func (mkf *MockedKeycardFlow) Start(flowType flow.FlowType, params flow.FlowParams) error {
if mkf.state != flow.Idle {
return errors.New("already running")
}
mkf.flowType = flowType
mkf.params = params
mkf.state = Running
mkf.state = flow.Running
go mkf.runFlow()
return nil
}
func (mkf *MockedKeycardFlow) Resume(params FlowParams) error {
if mkf.state != Paused {
func (mkf *MockedKeycardFlow) Resume(params flow.FlowParams) error {
if mkf.state != flow.Paused {
return errors.New("only paused flows can be resumed")
}
if mkf.params == nil {
mkf.params = FlowParams{}
mkf.params = flow.FlowParams{}
}
for k, v := range params {
@ -82,11 +85,11 @@ func (mkf *MockedKeycardFlow) Resume(params FlowParams) error {
func (mkf *MockedKeycardFlow) Cancel() error {
if mkf.state == Idle {
if mkf.state == flow.Idle {
return errors.New("cannot cancel idle flow")
}
mkf.state = Idle
mkf.state = flow.Idle
mkf.params = nil
return nil
@ -95,7 +98,7 @@ func (mkf *MockedKeycardFlow) Cancel() error {
func (mkf *MockedKeycardFlow) ReaderPluggedIn() error {
mkf.currentReaderState = NoKeycard
if mkf.state == Running {
if mkf.state == flow.Running {
go mkf.runFlow()
}
@ -122,7 +125,7 @@ func (mkf *MockedKeycardFlow) KeycardInserted(cardIndex int) error {
mkf.insertedKeycard = mkf.registeredKeycards[cardIndex]
mkf.insertedKeycardHelper = mkf.registeredKeycardHelpers[cardIndex]
if mkf.state == Running {
if mkf.state == flow.Running {
go mkf.runFlow()
}
@ -135,7 +138,7 @@ func (mkf *MockedKeycardFlow) KeycardRemoved() error {
mkf.insertedKeycard = nil
mkf.insertedKeycardHelper = nil
if mkf.state == Running {
if mkf.state == flow.Running {
go mkf.runFlow()
}
@ -144,7 +147,7 @@ func (mkf *MockedKeycardFlow) KeycardRemoved() error {
func (mkf *MockedKeycardFlow) RegisterKeycard(cardIndex int, readerState MockedReaderState, keycardState MockedKeycardState,
keycard *MockedKeycard, keycardHelper *MockedKeycard) error {
mkf.state = Idle
mkf.state = flow.Idle
mkf.params = nil
newKeycard := &MockedKeycard{}
@ -164,7 +167,7 @@ func (mkf *MockedKeycardFlow) RegisterKeycard(cardIndex int, readerState MockedR
case MaxPUKRetriesReached:
newKeycard.PukRetries = 0
case KeycardWithMnemonicOnly:
newKeycard.Metadata = Metadata{}
newKeycard.Metadata = internal.Metadata{}
case KeycardWithMnemonicAndMedatada:
*newKeycard = mockedKeycard
default:
@ -189,38 +192,38 @@ func (mkf *MockedKeycardFlow) RegisterKeycard(cardIndex int, readerState MockedR
func (mkf *MockedKeycardFlow) runFlow() {
switch mkf.currentReaderState {
case NoReader:
signal.Send(FlowResult, FlowStatus{ErrorKey: ErrorNoReader})
signal.Send(flow.FlowResult, flow.FlowStatus{internal.ErrorKey: internal.ErrorNoReader})
return
case NoKeycard:
signal.Send(InsertCard, FlowStatus{ErrorKey: ErrorConnection})
signal.Send(flow.InsertCard, flow.FlowStatus{internal.ErrorKey: internal.ErrorConnection})
return
default:
switch mkf.flowType {
case GetAppInfo:
case flow.GetAppInfo:
mkf.handleGetAppInfoFlow()
case RecoverAccount:
case flow.RecoverAccount:
mkf.handleRecoverAccountFlow()
case LoadAccount:
case flow.LoadAccount:
mkf.handleLoadAccountFlow()
case Login:
case flow.Login:
mkf.handleLoginFlow()
case ExportPublic:
case flow.ExportPublic:
mkf.handleExportPublicFlow()
case ChangePIN:
case flow.ChangePIN:
mkf.handleChangePinFlow()
case ChangePUK:
case flow.ChangePUK:
mkf.handleChangePukFlow()
case StoreMetadata:
case flow.StoreMetadata:
mkf.handleStoreMetadataFlow()
case GetMetadata:
case flow.GetMetadata:
mkf.handleGetMetadataFlow()
}
}
if mkf.insertedKeycard.InstanceUID != "" {
pairing := mkf.pairings.get(mkf.insertedKeycard.InstanceUID)
pairing := mkf.pairings.Get(mkf.insertedKeycard.InstanceUID)
if pairing == nil {
mkf.pairings.store(mkf.insertedKeycard.InstanceUID, mkf.insertedKeycard.PairingInfo)
mkf.pairings.Store(mkf.insertedKeycard.InstanceUID, mkf.insertedKeycard.PairingInfo)
}
}

View File

@ -0,0 +1,86 @@
package mocked
import (
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleGetAppInfoFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
flowStatus = flow.FlowStatus{
flow.PINRetries: mkf.insertedKeycard.PinRetries,
flow.PUKRetries: mkf.insertedKeycard.PukRetries,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
flowStatus[internal.ErrorKey] = internal.ErrorNoKeys
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
var (
enteredPIN string
factoryReset bool
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.FactoryReset]; ok {
factoryReset = v.(bool)
}
if factoryReset {
mkf.state = flow.Idle
*mkf.insertedKeycard = MockedKeycard{}
signal.Send(flow.FlowResult, flow.FlowStatus{
internal.ErrorKey: internal.ErrorOK,
flow.Paired: false,
flow.AppInfo: internal.ApplicationInfo{
Initialized: false,
InstanceUID: []byte(""),
Version: 0,
AvailableSlots: 0,
KeyUID: []byte(""),
},
})
return
}
keycardStoresKeys := mkf.insertedKeycard.InstanceUID != "" && mkf.insertedKeycard.KeyUID != ""
if len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin || !keycardStoresKeys {
flowStatus[internal.ErrorKey] = internal.ErrorOK
flowStatus[flow.Paired] = keycardStoresKeys
flowStatus[flow.AppInfo] = internal.ApplicationInfo{
Initialized: keycardStoresKeys,
InstanceUID: internal.HexString(mkf.insertedKeycard.InstanceUID),
Version: 123,
AvailableSlots: mkf.insertedKeycard.FreePairingSlots,
KeyUID: internal.HexString(mkf.insertedKeycard.KeyUID),
}
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
return
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.InstanceUID] = mkf.insertedKeycard.InstanceUID
flowStatus[flow.KeyUID] = mkf.insertedKeycard.KeyUID
mkf.state = flow.Paused
signal.Send(flow.EnterPIN, flowStatus)
}

View File

@ -0,0 +1,127 @@
package mocked
import (
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleChangePinFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" && mkf.insertedKeycard.KeyUID == "" {
flowStatus[internal.ErrorKey] = internal.ErrorRequireInit
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = flow.Paused
signal.Send(flow.EnterNewPIN, flowStatus)
return
}
if mkf.insertedKeycard.FreePairingSlots == 0 {
flowStatus[internal.ErrorKey] = flow.FreeSlots
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
overwrite bool
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[flow.PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[flow.Overwrite]; ok {
overwrite = v.(bool)
}
finalType := flow.EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == flow.DefPUKLen {
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
flowStatus[internal.ErrorKey] = flow.PUK
finalType = flow.EnterPUK
}
}
} else {
flowStatus[internal.ErrorKey] = internal.ErrorUnblocking
finalType = flow.EnterNewPIN
}
} else {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[internal.ErrorKey] = flow.PIN
finalType = flow.EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
}
}
}
if len(enteredNewPIN) == 0 {
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[internal.ErrorKey] = internal.ErrorChanging
finalType = flow.EnterNewPIN
}
} else {
if overwrite && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == flow.DefPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
signal.Send(flow.FlowResult, flowStatus)
return
}
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -0,0 +1,131 @@
package mocked
import (
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleChangePukFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" && mkf.insertedKeycard.KeyUID == "" {
flowStatus[internal.ErrorKey] = internal.ErrorRequireInit
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = flow.Paused
signal.Send(flow.EnterNewPIN, flowStatus)
return
}
if mkf.insertedKeycard.FreePairingSlots == 0 {
flowStatus[internal.ErrorKey] = flow.FreeSlots
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
enteredNewPUK string
overwrite bool
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[flow.PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[flow.NewPUK]; ok {
enteredNewPUK = v.(string)
}
if v, ok := mkf.params[flow.Overwrite]; ok {
overwrite = v.(bool)
}
finalType := flow.EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == flow.DefPUKLen {
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
flowStatus[internal.ErrorKey] = flow.PUK
finalType = flow.EnterPUK
}
}
} else {
flowStatus[internal.ErrorKey] = internal.ErrorUnblocking
finalType = flow.EnterNewPIN
}
} else {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[internal.ErrorKey] = flow.PIN
finalType = flow.EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == flow.DefPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if len(enteredNewPUK) == 0 {
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[internal.ErrorKey] = internal.ErrorChanging
finalType = flow.EnterNewPUK
} else if overwrite && len(enteredPUK) == flow.DefPUKLen && enteredPUK == enteredNewPUK {
flowStatus[internal.ErrorKey] = ""
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Puk = enteredPUK
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
return
}
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,4 +1,4 @@
package statuskeycardgo
package mocked
import (
"math/rand"
@ -6,31 +6,33 @@ import (
"strings"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleExportPublicFlow() {
flowStatus := FlowStatus{}
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[ErrorKey] = ErrorNotAKeycard
flowStatus[InstanceUID] = ""
flowStatus[KeyUID] = ""
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
flowStatus = FlowStatus{
InstanceUID: mkf.insertedKeycard.InstanceUID,
KeyUID: mkf.insertedKeycard.KeyUID,
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
flowStatus[ErrorKey] = ErrorNoKeys
flowStatus[FreeSlots] = 0
mkf.state = Paused
signal.Send(SwapCard, flowStatus)
flowStatus[internal.ErrorKey] = internal.ErrorNoKeys
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
@ -42,67 +44,67 @@ func (mkf *MockedKeycardFlow) handleExportPublicFlow() {
exportPrivate bool
)
if v, ok := mkf.params[PIN]; ok {
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[NewPIN]; ok {
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[PUK]; ok {
if v, ok := mkf.params[flow.PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[ExportMaster]; ok {
if v, ok := mkf.params[flow.ExportMaster]; ok {
exportMaster = v.(bool)
}
if v, ok := mkf.params[ExportPriv]; ok {
if v, ok := mkf.params[flow.ExportPriv]; ok {
exportPrivate = v.(bool)
}
finalType := EnterPIN
finalType := flow.EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == defPUKLen {
if len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if len(enteredPUK) == flow.DefPUKLen {
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[ErrorKey] = PUKRetries
finalType = SwapCard
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
flowStatus[ErrorKey] = PUK
finalType = EnterPUK
flowStatus[internal.ErrorKey] = flow.PUK
finalType = flow.EnterPUK
}
}
} else {
flowStatus[ErrorKey] = ErrorUnblocking
finalType = EnterNewPIN
flowStatus[internal.ErrorKey] = internal.ErrorUnblocking
finalType = flow.EnterNewPIN
}
} else {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == defPINLen && enteredPIN != mkf.insertedKeycard.Pin {
if len(enteredNewPIN) == 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[ErrorKey] = PIN
finalType = EnterPIN
flowStatus[internal.ErrorKey] = flow.PIN
finalType = flow.EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[ErrorKey] = ""
finalType = EnterPUK
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == defPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == defPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == defPINLen && enteredPIN == enteredNewPIN {
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == flow.DefPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = maxPINRetries
mkf.insertedKeycard.PukRetries = maxPUKRetries
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
if exportMaster {
@ -110,12 +112,12 @@ func (mkf *MockedKeycardFlow) handleExportPublicFlow() {
iAsStr := strconv.Itoa(rand.Intn(100) + 100)
mkf.insertedKeycardHelper.MasterKeyAddress = "0x" + strings.Repeat("0", 40-len(iAsStr)) + iAsStr
}
flowStatus[MasterAddr] = mkf.insertedKeycardHelper.MasterKeyAddress
flowStatus[flow.MasterAddr] = mkf.insertedKeycardHelper.MasterKeyAddress
}
if path, ok := mkf.params[BIP44Path]; ok {
if path, ok := mkf.params[flow.BIP44Path]; ok {
if mkf.insertedKeycardHelper.ExportedKey == nil {
mkf.insertedKeycardHelper.ExportedKey = make(map[string]KeyPair)
mkf.insertedKeycardHelper.ExportedKey = make(map[string]internal.KeyPair)
}
if pathStr, ok := path.(string); ok {
@ -136,9 +138,9 @@ func (mkf *MockedKeycardFlow) handleExportPublicFlow() {
}
mkf.insertedKeycardHelper.ExportedKey[pathStr] = keyPair
flowStatus[ExportedKey] = keyPair
flowStatus[flow.ExportedKey] = keyPair
} else if paths, ok := path.([]interface{}); ok {
keys := make([]*KeyPair, len(paths))
keys := make([]*internal.KeyPair, len(paths))
for i, path := range paths {
keyPair, _ := mkf.insertedKeycardHelper.ExportedKey[path.(string)]
@ -163,18 +165,18 @@ func (mkf *MockedKeycardFlow) handleExportPublicFlow() {
mkf.insertedKeycardHelper.ExportedKey[path.(string)] = keyPair
keys[i] = &keyPair
}
flowStatus[ExportedKey] = keys
flowStatus[flow.ExportedKey] = keys
}
}
mkf.state = Idle
signal.Send(FlowResult, flowStatus)
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
return
}
flowStatus[FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = Paused
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -0,0 +1,147 @@
package mocked
import (
"math/rand"
"strconv"
"strings"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleGetMetadataFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flow.FlowStatus{internal.ErrorKey: internal.ErrorNoKeys})
return
}
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
if resolveAddr, ok := mkf.params[flow.ResolveAddr]; ok && resolveAddr.(bool) {
if mkf.insertedKeycard.FreePairingSlots == 0 {
flowStatus[internal.ErrorKey] = flow.FreeSlots
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
exportMaster bool
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[flow.PUK]; ok {
enteredPUK = v.(string)
}
if v, ok := mkf.params[flow.ExportMaster]; ok {
exportMaster = v.(bool)
}
finalType := flow.EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == flow.DefPUKLen {
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
flowStatus[internal.ErrorKey] = flow.PUK
finalType = flow.EnterPUK
}
}
} else {
flowStatus[internal.ErrorKey] = internal.ErrorUnblocking
finalType = flow.EnterNewPIN
}
} else {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[internal.ErrorKey] = flow.PIN
finalType = flow.EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == flow.DefPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if exportMaster {
if mkf.insertedKeycardHelper.MasterKeyAddress == "" {
iAsStr := strconv.Itoa(rand.Intn(100) + 100)
mkf.insertedKeycardHelper.MasterKeyAddress = "0x" + strings.Repeat("0", 40-len(iAsStr)) + iAsStr
}
flowStatus[flow.MasterAddr] = mkf.insertedKeycardHelper.MasterKeyAddress
}
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[internal.ErrorKey] = ""
flowStatus[flow.CardMeta] = mkf.insertedKeycard.Metadata
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
return
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
return
}
pubMetadata := internal.Metadata{
Name: mkf.insertedKeycard.Metadata.Name,
}
for _, m := range mkf.insertedKeycard.Metadata.Wallets {
pubMetadata.Wallets = append(pubMetadata.Wallets, internal.Wallet{
Path: m.Path,
})
}
flowStatus[flow.CardMeta] = pubMetadata
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
}

View File

@ -0,0 +1,137 @@
package mocked
import (
"math/rand"
"strings"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleLoadAccountFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
finalType := flow.SwapCard
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
var (
factoryReset bool
overwrite bool
enteredMnemonicLength int
enteredMnemonic string
enteredNewPUK string
enteredPIN string
enteredNewPIN string
)
if v, ok := mkf.params[flow.FactoryReset]; ok {
factoryReset = v.(bool)
}
if v, ok := mkf.params[flow.Overwrite]; ok {
overwrite = v.(bool)
}
if v, ok := mkf.params[flow.MnemonicLen]; ok {
switch t := v.(type) {
case int:
enteredMnemonicLength = t
case float64:
enteredMnemonicLength = int(t)
default:
enteredMnemonicLength = flow.DefMnemoLen
}
} else {
enteredMnemonicLength = flow.DefMnemoLen
}
if v, ok := mkf.params[flow.Mnemonic]; ok {
enteredMnemonic = v.(string)
}
if v, ok := mkf.params[flow.NewPUK]; ok {
enteredNewPUK = v.(string)
}
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if factoryReset {
*mkf.insertedKeycard = MockedKeycard{}
}
if mkf.insertedKeycard.InstanceUID != "" && mkf.insertedKeycard.KeyUID != "" {
flowStatus[internal.ErrorKey] = internal.ErrorHasKeys
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
return
}
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN && len(enteredNewPUK) == flow.DefPUKLen {
if overwrite && enteredMnemonic == "" {
if mkf.insertedKeycard.InstanceUID == "" {
mkf.insertedKeycard.InstanceUID = mkf.insertedKeycardHelper.InstanceUID
mkf.insertedKeycard.PairingInfo = mkf.insertedKeycardHelper.PairingInfo
}
mkf.pairings.Store(mkf.insertedKeycard.InstanceUID, mkf.insertedKeycard.PairingInfo)
var indexes []int
for len(indexes) < enteredMnemonicLength {
indexes = append(indexes, rand.Intn(2048))
}
finalType = flow.EnterMnemonic
flowStatus[internal.ErrorKey] = internal.ErrorLoading
flowStatus[flow.MnemonicIdxs] = indexes
flowStatus[flow.InstanceUID] = mkf.insertedKeycard.InstanceUID
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
return
} else {
realMnemonicLength := len(strings.Split(enteredMnemonic, " "))
if enteredMnemonicLength == realMnemonicLength {
mkf.insertedKeycard.InstanceUID = mkf.insertedKeycardHelper.InstanceUID
mkf.insertedKeycard.PairingInfo = mkf.insertedKeycardHelper.PairingInfo
mkf.insertedKeycard.KeyUID = mkf.insertedKeycardHelper.KeyUID
mkf.insertedKeycard.Pin = enteredPIN
mkf.insertedKeycard.Puk = enteredNewPUK
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.FreePairingSlots = flow.MaxFreeSlots - 1
mkf.pairings.Store(mkf.insertedKeycard.InstanceUID, mkf.insertedKeycard.PairingInfo)
finalType = flow.FlowResult
flowStatus[flow.InstanceUID] = mkf.insertedKeycard.InstanceUID
flowStatus[flow.KeyUID] = mkf.insertedKeycard.KeyUID
mkf.state = flow.Idle
signal.Send(finalType, flowStatus)
return
}
}
}
finalType = flow.EnterNewPIN
flowStatus[internal.ErrorKey] = internal.ErrorRequireInit
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -0,0 +1,112 @@
package mocked
import (
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleLoginFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
finalType := flow.SwapCard
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
finalType = flow.SwapCard
flowStatus[internal.ErrorKey] = internal.ErrorNoKeys
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[flow.PUK]; ok {
enteredPUK = v.(string)
}
finalType = flow.EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == flow.DefPUKLen {
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
flowStatus[internal.ErrorKey] = flow.PUK
finalType = flow.EnterPUK
}
}
} else {
flowStatus[internal.ErrorKey] = internal.ErrorUnblocking
finalType = flow.EnterNewPIN
}
} else {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[internal.ErrorKey] = flow.PIN
finalType = flow.EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == flow.DefPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[internal.ErrorKey] = ""
flowStatus[flow.WhisperKey] = mkf.insertedKeycardHelper.ExportedKey[flow.WhisperPath]
flowStatus[flow.EncKey] = mkf.insertedKeycardHelper.ExportedKey[flow.EncryptionPath]
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
return
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -0,0 +1,116 @@
package mocked
import (
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleRecoverAccountFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
finalType := flow.SwapCard
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
if mkf.insertedKeycard.InstanceUID == "" || mkf.insertedKeycard.KeyUID == "" {
finalType = flow.SwapCard
flowStatus[internal.ErrorKey] = internal.ErrorNoKeys
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
return
}
var (
enteredPIN string
enteredNewPIN string
enteredPUK string
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.NewPIN]; ok {
enteredNewPIN = v.(string)
}
if v, ok := mkf.params[flow.PUK]; ok {
enteredPUK = v.(string)
}
finalType = flow.EnterPIN
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
if mkf.insertedKeycard.PinRetries == 0 {
if len(enteredPUK) == flow.DefPUKLen {
if len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
if enteredPUK != mkf.insertedKeycard.Puk {
mkf.insertedKeycard.PukRetries--
if mkf.insertedKeycard.PukRetries == 0 {
flowStatus[internal.ErrorKey] = flow.PUKRetries
finalType = flow.SwapCard
} else {
flowStatus[internal.ErrorKey] = flow.PUK
finalType = flow.EnterPUK
}
}
} else {
flowStatus[internal.ErrorKey] = internal.ErrorUnblocking
finalType = flow.EnterNewPIN
}
} else {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
} else {
if len(enteredNewPIN) == 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN != mkf.insertedKeycard.Pin {
mkf.insertedKeycard.PinRetries--
flowStatus[internal.ErrorKey] = flow.PIN
finalType = flow.EnterPIN
if mkf.insertedKeycard.PinRetries == 0 {
flowStatus[internal.ErrorKey] = ""
finalType = flow.EnterPUK
}
}
}
}
if mkf.insertedKeycard.PinRetries > 0 && len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin ||
mkf.insertedKeycard.PinRetries == 0 && mkf.insertedKeycard.PukRetries > 0 && len(enteredPUK) == flow.DefPUKLen &&
enteredPUK == mkf.insertedKeycard.Puk && len(enteredPIN) == flow.DefPINLen && enteredPIN == enteredNewPIN {
mkf.insertedKeycard.PinRetries = flow.MaxPINRetries
mkf.insertedKeycard.PukRetries = flow.MaxPUKRetries
mkf.insertedKeycard.Pin = enteredPIN
flowStatus[internal.ErrorKey] = ""
flowStatus[flow.MasterKey] = mkf.insertedKeycardHelper.ExportedKey[flow.MasterPath]
flowStatus[flow.WalleRootKey] = mkf.insertedKeycardHelper.ExportedKey[flow.WalletRoothPath]
flowStatus[flow.WalletKey] = mkf.insertedKeycardHelper.ExportedKey[flow.WalletPath]
flowStatus[flow.EIP1581Key] = mkf.insertedKeycardHelper.ExportedKey[flow.Eip1581Path]
flowStatus[flow.WhisperKey] = mkf.insertedKeycardHelper.ExportedKey[flow.WhisperPath]
flowStatus[flow.EncKey] = mkf.insertedKeycardHelper.ExportedKey[flow.EncryptionPath]
mkf.state = flow.Idle
signal.Send(flow.FlowResult, flowStatus)
return
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -0,0 +1,96 @@
package mocked
import (
"strconv"
"strings"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func (mkf *MockedKeycardFlow) handleStoreMetadataFlow() {
flowStatus := flow.FlowStatus{}
if mkf.insertedKeycard.NotStatusKeycard {
flowStatus[internal.ErrorKey] = internal.ErrorNotAKeycard
flowStatus[flow.InstanceUID] = ""
flowStatus[flow.KeyUID] = ""
flowStatus[flow.FreeSlots] = 0
mkf.state = flow.Paused
signal.Send(flow.SwapCard, flowStatus)
return
}
finalType := flow.FlowResult
flowStatus = flow.FlowStatus{
flow.InstanceUID: mkf.insertedKeycard.InstanceUID,
flow.KeyUID: mkf.insertedKeycard.KeyUID,
}
var (
enteredPIN string
enteredCardName string
)
if v, ok := mkf.params[flow.PIN]; ok {
enteredPIN = v.(string)
}
if v, ok := mkf.params[flow.CardName]; ok {
enteredCardName = v.(string)
}
if len(enteredPIN) == flow.DefPINLen && enteredPIN == mkf.insertedKeycard.Pin && enteredCardName != "" {
mkf.insertedKeycard.Metadata.Name = enteredCardName
mkf.insertedKeycard.Metadata.Wallets = []internal.Wallet{}
if v, ok := mkf.params[flow.WalletPaths]; ok {
wallets := v.([]interface{})
for i, p := range wallets {
if !strings.HasPrefix(p.(string), flow.WalletRoothPath) {
panic("path must start with " + flow.WalletRoothPath)
}
tmpWallet := internal.Wallet{
Path: p.(string),
}
found := false
for _, w := range mkf.insertedKeycardHelper.Metadata.Wallets {
if w.Path == tmpWallet.Path {
found = true
tmpWallet = w
break
}
}
if !found {
iAsStr := strconv.Itoa(i + 1)
tmpWallet.Address = "0x" + strings.Repeat("0", 40-len(iAsStr)) + iAsStr
tmpWallet.PublicKey = []byte(strings.Repeat("0", 130-len(iAsStr)) + iAsStr)
mkf.insertedKeycardHelper.Metadata.Wallets = append(mkf.insertedKeycardHelper.Metadata.Wallets, tmpWallet)
}
mkf.insertedKeycard.Metadata.Wallets = append(mkf.insertedKeycard.Metadata.Wallets, tmpWallet)
}
}
mkf.state = flow.Idle
signal.Send(finalType, flowStatus)
return
}
if len(enteredPIN) != flow.DefPINLen || enteredPIN != mkf.insertedKeycard.Pin {
finalType = flow.EnterPIN
} else if enteredCardName == "" {
finalType = flow.EnterName
}
flowStatus[flow.FreeSlots] = mkf.insertedKeycard.FreePairingSlots
flowStatus[flow.PINRetries] = mkf.insertedKeycard.PinRetries
flowStatus[flow.PUKRetries] = mkf.insertedKeycard.PukRetries
mkf.state = flow.Paused
signal.Send(finalType, flowStatus)
}

View File

@ -1,4 +1,9 @@
package statuskeycardgo
package mocked
import (
"github.com/status-im/status-keycard-go/internal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
type MockedReaderState int
@ -21,35 +26,35 @@ const (
)
type MockedKeycard struct {
PairingInfo *PairingInfo `json:"pairing-info"`
NotStatusKeycard bool `json:"not-status-keycard"`
InstanceUID string `json:"instance-uid"`
KeyUID string `json:"key-uid"`
FreePairingSlots int `json:"free-pairing-slots"`
PinRetries int `json:"pin-retries"`
PukRetries int `json:"puk-retries"`
Pin string `json:"pin"`
Puk string `json:"puk"`
Metadata Metadata `json:"card-metadata"`
MasterKeyAddress string `json:"master-key-address"` // used to predefine master key address in specific flows (like ExportPublic)
ExportedKey map[string]KeyPair `json:"exported-key"` // [path]KeyPair - used to predefine adderss/private/public keys in specific flows (like ExportPublic)
PairingInfo *internal.PairingInfo `json:"pairing-info"`
NotStatusKeycard bool `json:"not-status-keycard"`
InstanceUID string `json:"instance-uid"`
KeyUID string `json:"key-uid"`
FreePairingSlots int `json:"free-pairing-slots"`
PinRetries int `json:"pin-retries"`
PukRetries int `json:"puk-retries"`
Pin string `json:"pin"`
Puk string `json:"puk"`
Metadata internal.Metadata `json:"card-metadata"`
MasterKeyAddress string `json:"master-key-address"` // used to predefine master key address in specific flows (like ExportPublic)
ExportedKey map[string]internal.KeyPair `json:"exported-key"` // [path]KeyPair - used to predefine adderss/private/public keys in specific flows (like ExportPublic)
}
var mockedKeycard = MockedKeycard{
InstanceUID: "00000000000000000000001234567890",
KeyUID: "0000000000000000000000000000000000000000000000000000001234567890",
FreePairingSlots: maxFreeSlots - 1,
PinRetries: maxPINRetries,
PukRetries: maxPUKRetries,
FreePairingSlots: flow.MaxFreeSlots - 1,
PinRetries: flow.MaxPINRetries,
PukRetries: flow.MaxPUKRetries,
Pin: "111111",
Puk: "111111111111",
PairingInfo: &PairingInfo{
PairingInfo: &internal.PairingInfo{
Key: []byte("0000000000000000000000000000000000000000000000000000001111111111"),
Index: 0,
},
Metadata: Metadata{
Metadata: internal.Metadata{
Name: "Card-1 Name",
Wallets: []Wallet{
Wallets: []internal.Wallet{
{
Path: "m/44'/60'/0'/0/0",
Address: "0x0000000000000000000000000000000000000001",
@ -67,18 +72,18 @@ var mockedKeycard = MockedKeycard{
var mockedKeycardHelper = MockedKeycard{
InstanceUID: "00000000000000000000001234567890",
KeyUID: "0000000000000000000000000000000000000000000000000000001234567890",
FreePairingSlots: maxFreeSlots - 1,
PinRetries: maxPINRetries,
PukRetries: maxPUKRetries,
FreePairingSlots: flow.MaxFreeSlots - 1,
PinRetries: flow.MaxPINRetries,
PukRetries: flow.MaxPUKRetries,
Pin: "111111",
Puk: "111111111111",
PairingInfo: &PairingInfo{
PairingInfo: &internal.PairingInfo{
Key: []byte("0000000000000000000000000000000000000000000000000000001111111111"),
Index: 0,
},
Metadata: Metadata{
Metadata: internal.Metadata{
Name: "Card-1 Name",
Wallets: []Wallet{
Wallets: []internal.Wallet{
{
Path: "m/44'/60'/0'/0/0",
Address: "0x0000000000000000000000000000000000000001",
@ -92,7 +97,7 @@ var mockedKeycardHelper = MockedKeycard{
},
},
MasterKeyAddress: "0x0000000000000000000000000000000000000100",
ExportedKey: map[string]KeyPair{
ExportedKey: map[string]internal.KeyPair{
"m/44'/60'/0'/0/0": {
Address: "0x0000000000000000000000000000000000000001",
PublicKey: []byte("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"),

View File

@ -1,9 +1,9 @@
package statuskeycardgo
package flow
type FlowType int
type FlowParams map[string]interface{}
type FlowStatus map[string]interface{}
type runState int
type RunState int
type restartError struct{}
type giveupError struct{}
@ -42,7 +42,7 @@ const (
)
const (
Idle runState = iota
Idle RunState = iota
Running
Paused
Resuming
@ -107,19 +107,19 @@ const (
)
const (
maxPINRetries = 3
maxPUKRetries = 5
maxFreeSlots = 5
defMnemoLen = 12
defPINLen = 6
defPUKLen = 12
MaxPINRetries = 3
MaxPUKRetries = 5
MaxFreeSlots = 5
DefMnemoLen = 12
DefPINLen = 6
DefPUKLen = 12
)
const (
masterPath = "m"
walletRoothPath = "m/44'/60'/0'/0"
walletPath = walletRoothPath + "/0"
eip1581Path = "m/43'/60'/1581'"
whisperPath = eip1581Path + "/0'/0"
encryptionPath = eip1581Path + "/1'/0"
MasterPath = "m"
WalletRoothPath = "m/44'/60'/0'/0"
WalletPath = WalletRoothPath + "/0"
Eip1581Path = "m/43'/60'/1581'"
WhisperPath = Eip1581Path + "/0'/0"
EncryptionPath = Eip1581Path + "/1'/0"
)

View File

@ -1,18 +1,19 @@
package statuskeycardgo
package pairing
import (
"encoding/json"
"os"
"path/filepath"
"github.com/status-im/status-keycard-go/internal"
)
type pairingStore struct {
type Store struct {
path string
values map[string]*PairingInfo
values map[string]*internal.PairingInfo
}
func newPairingStore(storage string) (*pairingStore, error) {
p := &pairingStore{path: storage}
func NewStore(storage string) (*Store, error) {
p := &Store{path: storage}
b, err := os.ReadFile(p.path)
if err != nil {
@ -24,7 +25,7 @@ func newPairingStore(storage string) (*pairingStore, error) {
return nil, err
}
p.values = map[string]*PairingInfo{}
p.values = map[string]*internal.PairingInfo{}
} else {
return nil, err
}
@ -39,7 +40,7 @@ func newPairingStore(storage string) (*pairingStore, error) {
return p, nil
}
func (p *pairingStore) save() error {
func (p *Store) save() error {
b, err := json.Marshal(p.values)
if err != nil {
@ -55,15 +56,15 @@ func (p *pairingStore) save() error {
return nil
}
func (p *pairingStore) store(instanceUID string, pairing *PairingInfo) error {
func (p *Store) Store(instanceUID string, pairing *internal.PairingInfo) error {
p.values[instanceUID] = pairing
return p.save()
}
func (p *pairingStore) get(instanceUID string) *PairingInfo {
func (p *Store) Get(instanceUID string) *internal.PairingInfo {
return p.values[instanceUID]
}
func (p *pairingStore) delete(instanceUID string) {
func (p *Store) Delete(instanceUID string) {
delete(p.values, instanceUID)
}

View File

@ -8,13 +8,14 @@ import (
"encoding/json"
"unsafe"
skg "github.com/status-im/status-keycard-go"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/pkg/flow"
"github.com/status-im/status-keycard-go/pkg/flow/mocked"
)
func main() {}
var globalFlow *skg.MockedKeycardFlow
var globalFlow *mocked.MockedKeycardFlow
func retErr(err error) *C.char {
if err == nil {
@ -24,8 +25,8 @@ func retErr(err error) *C.char {
}
}
func jsonToParams(jsonParams *C.char) (skg.FlowParams, error) {
var params skg.FlowParams
func jsonToParams(jsonParams *C.char) (flow.FlowParams, error) {
var params flow.FlowParams
if err := json.Unmarshal([]byte(C.GoString(jsonParams)), &params); err != nil {
return nil, err
@ -34,13 +35,13 @@ func jsonToParams(jsonParams *C.char) (skg.FlowParams, error) {
return params, nil
}
func jsonToMockedKeycard(jsonKeycard *C.char) (*skg.MockedKeycard, error) {
func jsonToMockedKeycard(jsonKeycard *C.char) (*mocked.MockedKeycard, error) {
bytes := []byte(C.GoString(jsonKeycard))
if len(bytes) == 0 {
return nil, nil
}
mockedKeycard := &skg.MockedKeycard{}
mockedKeycard := &mocked.MockedKeycard{}
if err := json.Unmarshal(bytes, mockedKeycard); err != nil {
return nil, err
}
@ -52,7 +53,7 @@ func jsonToMockedKeycard(jsonKeycard *C.char) (*skg.MockedKeycard, error) {
func KeycardInitFlow(storageDir *C.char) *C.char {
var err error
globalFlow, err = skg.NewMockedFlow(C.GoString(storageDir))
globalFlow, err = mocked.NewMockedFlow(C.GoString(storageDir))
return retErr(err)
}
@ -65,7 +66,7 @@ func KeycardStartFlow(flowType C.int, jsonParams *C.char) *C.char {
return retErr(err)
}
err = globalFlow.Start(skg.FlowType(flowType), params)
err = globalFlow.Start(flow.FlowType(flowType), params)
return retErr(err)
}
@ -109,7 +110,7 @@ func MockedLibRegisterKeycard(cardIndex C.int, readerState C.int, keycardState C
return retErr(err)
}
err = globalFlow.RegisterKeycard(int(cardIndex), skg.MockedReaderState(readerState), skg.MockedKeycardState(keycardState),
err = globalFlow.RegisterKeycard(int(cardIndex), mocked.MockedReaderState(readerState), mocked.MockedKeycardState(keycardState),
mockedKeycardInst, mockedKeycardHelperInst)
return retErr(err)
}

View File

@ -9,15 +9,15 @@ import (
"errors"
"unsafe"
skg "github.com/status-im/status-keycard-go"
"github.com/status-im/status-keycard-go/signal"
"github.com/status-im/status-keycard-go/pkg/flow"
)
func main() {}
var notAvailable = errors.New("not available in this context")
var globalFlow *skg.KeycardFlow
var globalFlow *flow.KeycardFlow
func retErr(err error) *C.char {
if err == nil {
@ -27,8 +27,8 @@ func retErr(err error) *C.char {
}
}
func jsonToParams(jsonParams *C.char) (skg.FlowParams, error) {
var params skg.FlowParams
func jsonToParams(jsonParams *C.char) (flow.FlowParams, error) {
var params flow.FlowParams
if err := json.Unmarshal([]byte(C.GoString(jsonParams)), &params); err != nil {
return nil, err
@ -40,7 +40,7 @@ func jsonToParams(jsonParams *C.char) (skg.FlowParams, error) {
//export KeycardInitFlow
func KeycardInitFlow(storageDir *C.char) *C.char {
var err error
globalFlow, err = skg.NewFlow(C.GoString(storageDir))
globalFlow, err = flow.NewFlow(C.GoString(storageDir))
return retErr(err)
}
@ -53,7 +53,7 @@ func KeycardStartFlow(flowType C.int, jsonParams *C.char) *C.char {
return retErr(err)
}
err = globalFlow.Start(skg.FlowType(flowType), params)
err = globalFlow.Start(flow.FlowType(flowType), params)
return retErr(err)
}