diff --git a/internal/keycard_context.go b/internal/keycard_context.go index b953712..8350059 100644 --- a/internal/keycard_context.go +++ b/internal/keycard_context.go @@ -326,16 +326,16 @@ func (kc *KeycardContext) SignWithPath(data []byte, path string) (*types.Signatu 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, p2 uint8, path string) (*KeyPair, error) { address := "" - privKey, pubKey, err := kc.cmdSet.ExportKey(derive, makeCurrent, onlyPublic, path) + exportedKey, err := kc.cmdSet.ExportKeyExtended(derive, makeCurrent, p2, path) if err != nil { Printf("exportKey failed %+v", err) return nil, err } - if pubKey != nil { - ecdsaPubKey, err := crypto.UnmarshalPubkey(pubKey) + if exportedKey.PubKey() != nil { + ecdsaPubKey, err := crypto.UnmarshalPubkey(exportedKey.PubKey()) if err != nil { return nil, err } @@ -343,7 +343,7 @@ func (kc *KeycardContext) ExportKey(derive bool, makeCurrent bool, onlyPublic bo address = crypto.PubkeyToAddress(*ecdsaPubKey).Hex() } - return &KeyPair{Address: address, PublicKey: pubKey, PrivateKey: privKey}, nil + return &KeyPair{Address: address, PublicKey: exportedKey.PubKey(), PrivateKey: exportedKey.PrivKey(), ChainCode: exportedKey.ChainCode()}, nil } func (kc *KeycardContext) loadSeed(seed []byte) ([]byte, error) { diff --git a/internal/types.go b/internal/types.go index 1b32c3e..84d67f1 100644 --- a/internal/types.go +++ b/internal/types.go @@ -53,6 +53,7 @@ type KeyPair struct { Address string `json:"address"` PublicKey HexString `json:"publicKey"` PrivateKey HexString `json:"privateKey,omitempty"` + ChainCode HexString `json:"chainCode,omitempty"` } type Wallet struct { diff --git a/pkg/flow/commands.go b/pkg/flow/commands.go index f3ddeb8..326950c 100644 --- a/pkg/flow/commands.go +++ b/pkg/flow/commands.go @@ -5,6 +5,7 @@ import ( "io" "strings" + keycard "github.com/status-im/keycard-go" "github.com/status-im/keycard-go/apdu" "github.com/status-im/keycard-go/derivationpath" ktypes "github.com/status-im/keycard-go/types" @@ -34,6 +35,7 @@ func (f *KeycardFlow) selectKeycard(kc *internal.KeycardContext) error { f.cardInfo.instanceUID = internal.Btox(appInfo.InstanceUID) f.cardInfo.keyUID = internal.Btox(appInfo.KeyUID) f.cardInfo.freeSlots = internal.BytesToInt(appInfo.AvailableSlots) + f.cardInfo.version = internal.BytesToInt(appInfo.Version) if !appInfo.Installed { return f.pauseAndRestart(SwapCard, internal.ErrorNotAKeycard) @@ -372,7 +374,18 @@ func (f *KeycardFlow) storeMetadata(kc *internal.KeycardContext) error { } func (f *KeycardFlow) exportKey(kc *internal.KeycardContext, path string, onlyPublic bool) (*internal.KeyPair, error) { - keyPair, err := kc.ExportKey(true, path == MasterPath, onlyPublic, path) + var p2 uint8 + if onlyPublic { + p2 = keycard.P2ExportKeyPublicOnly + } else { + p2 = keycard.P2ExportKeyPrivateAndPublic + } + + return f.exportKeyExtended(kc, path, p2) +} + +func (f *KeycardFlow) exportKeyExtended(kc *internal.KeycardContext, path string, p2 uint8) (*internal.KeyPair, error) { + keyPair, err := kc.ExportKey(true, path == MasterPath, p2, path) if internal.IsSCardError(err) { return nil, restartErr() diff --git a/pkg/flow/flow.go b/pkg/flow/flow.go index b1b1cb6..673b679 100644 --- a/pkg/flow/flow.go +++ b/pkg/flow/flow.go @@ -4,9 +4,10 @@ import ( "errors" "time" - "github.com/status-im/status-keycard-go/signal" + "github.com/status-im/keycard-go" "github.com/status-im/status-keycard-go/internal" "github.com/status-im/status-keycard-go/pkg/pairing" + "github.com/status-im/status-keycard-go/signal" ) type cardStatus struct { @@ -15,6 +16,7 @@ type cardStatus struct { freeSlots int pinRetries int pukRetries int + version int } type KeycardFlow struct { @@ -326,17 +328,27 @@ func (f *KeycardFlow) exportKeysFlow(kc *internal.KeycardContext, recover bool) } result[EIP1581Key] = key - key, err = f.exportKey(kc, WalletRoothPath, true) + var exportP2 uint8 + + if f.cardInfo.version < 0x0310 { + exportP2 = keycard.P2ExportKeyPublicOnly + } else { + exportP2 = keycard.P2ExportKeyExtendedPublic + } + + key, err = f.exportKeyExtended(kc, WalletRoothPath, exportP2) if err != nil { return nil, err } result[WalleRootKey] = key - key, err = f.exportKey(kc, WalletPath, true) - if err != nil { - return nil, err + if key.ChainCode == nil { + key, err = f.exportKey(kc, WalletPath, true) + if err != nil { + return nil, err + } + result[WalletKey] = key } - result[WalletKey] = key key, err = f.exportKey(kc, MasterPath, true) if err != nil {