mirror of
https://github.com/status-im/status-keycard-go.git
synced 2025-02-24 12:08:38 +00:00
implement sign flow
This commit is contained in:
parent
d45beefc14
commit
e3c16d0e57
@ -94,5 +94,6 @@ func main() {
|
|||||||
testFlow(skg.RecoverAccount, skg.FlowParams{skg.PIN: "234567"})
|
testFlow(skg.RecoverAccount, skg.FlowParams{skg.PIN: "234567"})
|
||||||
testFlow(skg.Login, skg.FlowParams{})
|
testFlow(skg.Login, skg.FlowParams{})
|
||||||
testFlow(skg.GetAppInfo, skg.FlowParams{})
|
testFlow(skg.GetAppInfo, skg.FlowParams{})
|
||||||
|
testFlow(skg.Sign, skg.FlowParams{skg.TXHash: "60a78c98d5dd659f714eb7072bfb2c0d8a65f74a8f6aff7bb27cf56ae1feec17", skg.BIP44Path: "m/44'/60'/0'/0/0"})
|
||||||
testFlow(skg.UnpairThis, skg.FlowParams{skg.PIN: correctPIN})
|
testFlow(skg.UnpairThis, skg.FlowParams{skg.PIN: correctPIN})
|
||||||
}
|
}
|
||||||
|
31
flow.go
31
flow.go
@ -326,17 +326,8 @@ func (f *KeycardFlow) exportPublicFlow(kc *keycardContext) (FlowStatus, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
path, ok := f.params[BIP44Path]
|
key, err := f.exportBIP44Key(kc)
|
||||||
|
|
||||||
if !ok {
|
|
||||||
err := f.pauseAndWait(EnterPath, ErrorExporting)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := f.exportKey(kc, path.(string), true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -349,7 +340,25 @@ func (f *KeycardFlow) loadKeysFlow(kc *keycardContext) (FlowStatus, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *KeycardFlow) signFlow(kc *keycardContext) (FlowStatus, error) {
|
func (f *KeycardFlow) signFlow(kc *keycardContext) (FlowStatus, error) {
|
||||||
return nil, errors.New("not implemented yet")
|
err := f.requireKeys()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = f.openSCAndAuthenticate(kc, false)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signature, err := f.sign(kc)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlowStatus{KeyUID: f.cardInfo.keyUID, TXSignature: signature}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *KeycardFlow) changePINFlow(kc *keycardContext) (FlowStatus, error) {
|
func (f *KeycardFlow) changePINFlow(kc *keycardContext) (FlowStatus, error) {
|
||||||
|
@ -12,8 +12,8 @@ func (f *KeycardFlow) factoryReset(kc *keycardContext) error {
|
|||||||
func (f *KeycardFlow) selectKeycard(kc *keycardContext) error {
|
func (f *KeycardFlow) selectKeycard(kc *keycardContext) error {
|
||||||
appInfo, err := kc.selectApplet()
|
appInfo, err := kc.selectApplet()
|
||||||
|
|
||||||
f.cardInfo.instanceUID = tox(appInfo.InstanceUID)
|
f.cardInfo.instanceUID = btox(appInfo.InstanceUID)
|
||||||
f.cardInfo.keyUID = tox(appInfo.KeyUID)
|
f.cardInfo.keyUID = btox(appInfo.KeyUID)
|
||||||
f.cardInfo.freeSlots = bytesToInt(appInfo.AvailableSlots)
|
f.cardInfo.freeSlots = bytesToInt(appInfo.AvailableSlots)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -280,6 +280,22 @@ func (f *KeycardFlow) exportKey(kc *keycardContext, path string, onlyPublic bool
|
|||||||
return keyPair, err
|
return keyPair, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *KeycardFlow) exportBIP44Key(kc *keycardContext) (*KeyPair, error) {
|
||||||
|
path, ok := f.params[BIP44Path]
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
return f.exportKey(kc, path.(string), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := f.pauseAndWait(EnterPath, ErrorExporting)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.exportBIP44Key(kc)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *KeycardFlow) changePIN(kc *keycardContext) error {
|
func (f *KeycardFlow) changePIN(kc *keycardContext) error {
|
||||||
if newPIN, ok := f.params[NewPIN]; ok {
|
if newPIN, ok := f.params[NewPIN]; ok {
|
||||||
err := kc.changePin(newPIN.(string))
|
err := kc.changePin(newPIN.(string))
|
||||||
@ -345,3 +361,48 @@ func (f *KeycardFlow) changePairing(kc *keycardContext) error {
|
|||||||
|
|
||||||
return f.changePairing(kc)
|
return f.changePairing(kc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *KeycardFlow) sign(kc *keycardContext) (*Signature, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
path, pathOK := f.params[BIP44Path]
|
||||||
|
|
||||||
|
if !pathOK {
|
||||||
|
err = f.pauseAndWait(EnterPath, ErrorSigning)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.sign(kc)
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, hashOK := f.params[TXHash]
|
||||||
|
|
||||||
|
var rawHash []byte
|
||||||
|
|
||||||
|
if hashOK {
|
||||||
|
rawHash, err = xtob(hash.(string))
|
||||||
|
if err != nil {
|
||||||
|
hashOK = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hashOK {
|
||||||
|
err := f.pauseAndWait(EnterTXHash, ErrorSigning)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.sign(kc)
|
||||||
|
}
|
||||||
|
|
||||||
|
signature, err := kc.signWithPath(rawHash, path.(string))
|
||||||
|
|
||||||
|
if isSCardError(err) {
|
||||||
|
return nil, restartErr()
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return toSignature(signature), nil
|
||||||
|
}
|
||||||
|
12
types.go
12
types.go
@ -1,7 +1,6 @@
|
|||||||
package statuskeycardgo
|
package statuskeycardgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -9,7 +8,7 @@ type hexString []byte
|
|||||||
|
|
||||||
// MarshalJSON serializes hexString to hex
|
// MarshalJSON serializes hexString to hex
|
||||||
func (s hexString) MarshalJSON() ([]byte, error) {
|
func (s hexString) MarshalJSON() ([]byte, error) {
|
||||||
bytes, err := json.Marshal(tox(s))
|
bytes, err := json.Marshal(btox(s))
|
||||||
return bytes, err
|
return bytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ func (s *hexString) UnmarshalJSON(data []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
str, err := hex.DecodeString(x)
|
str, err := xtob(x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -79,10 +78,9 @@ type unpairParams struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Signature struct {
|
type Signature struct {
|
||||||
PublicKey hexString `json:"publicKey"`
|
R hexString `json:"r"`
|
||||||
R hexString `json:"r"`
|
S hexString `json:"s"`
|
||||||
S hexString `json:"s"`
|
V byte `json:"v"`
|
||||||
V byte `json:"v"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Capability uint8
|
type Capability uint8
|
||||||
|
16
utils.go
16
utils.go
@ -29,7 +29,7 @@ func retValue(pairs ...interface{}) *C.char {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isSCardError(err error) bool {
|
func isSCardError(err error) bool {
|
||||||
_, ok := err.(*scard.Error)
|
_, ok := err.(scard.Error)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,10 +43,14 @@ func getRetries(err error) (int, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tox(bytes []byte) string {
|
func btox(bytes []byte) string {
|
||||||
return hex.EncodeToString(bytes)
|
return hex.EncodeToString(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func xtob(str string) ([]byte, error) {
|
||||||
|
return hex.DecodeString(str)
|
||||||
|
}
|
||||||
|
|
||||||
func bytesToInt(s []byte) int {
|
func bytesToInt(s []byte) int {
|
||||||
if len(s) > 4 {
|
if len(s) > 4 {
|
||||||
return 0
|
return 0
|
||||||
@ -73,3 +77,11 @@ func toPairInfo(r *ktypes.PairingInfo) *PairingInfo {
|
|||||||
Index: r.Index,
|
Index: r.Index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toSignature(r *ktypes.Signature) *Signature {
|
||||||
|
return &Signature{
|
||||||
|
R: r.R(),
|
||||||
|
S: r.S(),
|
||||||
|
V: r.V(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user