mirror of
https://github.com/status-im/status-keycard-go.git
synced 2025-03-03 07:20:56 +00:00
export flow interface
This commit is contained in:
parent
3727d89ae7
commit
7f072e33d4
@ -3,15 +3,32 @@ package main
|
||||
/*
|
||||
#cgo LDFLAGS: -L ../../build/libkeycard -lkeycard
|
||||
#include "../../build/libkeycard/libkeycard.h"
|
||||
extern char* HelloWorld();
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res := C.HelloWorld()
|
||||
dir, err := os.MkdirTemp("", "status-keycard-go")
|
||||
if err != nil {
|
||||
fmt.Printf("error: %+v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
pairingsFile := filepath.Join(dir, "keycard-pairings.json")
|
||||
|
||||
res := C.KeycardInitFlow(C.CString(pairingsFile))
|
||||
fmt.Printf("result: %+v\n", C.GoString(res))
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("error: %+v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ type keycardContext struct {
|
||||
}
|
||||
|
||||
func startKeycardContext() (*keycardContext, error) {
|
||||
kctx = &keycardContext{
|
||||
kctx := &keycardContext{
|
||||
connected: make(chan (struct{})),
|
||||
}
|
||||
err := kctx.start()
|
||||
|
358
main.go
358
main.go
@ -1,358 +0,0 @@
|
||||
package statuskeycardgo
|
||||
|
||||
var kctx *keycardContext
|
||||
|
||||
func HelloWorld() string {
|
||||
return "Hello World"
|
||||
}
|
||||
|
||||
////export Start
|
||||
//func Start() *C.char {
|
||||
// var err error
|
||||
// kctx, err = startKeycardContext()
|
||||
// if err != nil {
|
||||
// return retValue("err", err.Error())
|
||||
// }
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export Select
|
||||
//func Select() *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// info, err := kctx.selectApplet()
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "applicationInfo", ApplicationInfo{
|
||||
// Installed: info.Installed,
|
||||
// Initialized: info.Initialized,
|
||||
// InstanceUID: info.InstanceUID,
|
||||
// SecureChannelPublicKey: info.SecureChannelPublicKey,
|
||||
// Version: bytesToInt(info.Version),
|
||||
// AvailableSlots: bytesToInt(info.AvailableSlots),
|
||||
// KeyUID: info.KeyUID,
|
||||
// Capabilities: Capability(info.Capabilities),
|
||||
// })
|
||||
//}
|
||||
|
||||
////export Stop
|
||||
//func Stop() *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// if err := kctx.stop(); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export Pair
|
||||
//func Pair(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params pairParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// pairingInfo, err := kctx.pair(params.PairingPassword)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "pairingInfo", PairingInfo{
|
||||
// Key: pairingInfo.Key,
|
||||
// Index: pairingInfo.Index,
|
||||
// })
|
||||
//}
|
||||
|
||||
////export OpenSecureChannel
|
||||
//func OpenSecureChannel(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params openSecureChannelParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.openSecureChannel(params.Index, params.Key)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export VerifyPin
|
||||
//func VerifyPin(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params verifyPinParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.verifyPin(params.Pin)
|
||||
|
||||
// if wrongPing, ok := err.(*keycard.WrongPINError); ok {
|
||||
// return retValue("error", err.Error(), "remainingAttempts", wrongPing.RemainingAttempts)
|
||||
// }
|
||||
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export GenerateKey
|
||||
//func GenerateKey() *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// keyUID, err := kctx.generateKey()
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "keyUID", hexString(keyUID))
|
||||
//}
|
||||
|
||||
////export DeriveKey
|
||||
//func DeriveKey(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params deriveKeyParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.deriveKey(params.Path)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export SignWithPath
|
||||
//func SignWithPath(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params signWithPathParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// sig, err := kctx.signWithPath(params.Data, params.Path)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "signature", Signature{
|
||||
// PublicKey: hexString(sig.PubKey()),
|
||||
// R: hexString(sig.R()),
|
||||
// S: hexString(sig.S()),
|
||||
// V: sig.V(),
|
||||
// })
|
||||
//}
|
||||
|
||||
////export ExportKey
|
||||
//func ExportKey(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params exportKeyParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// privKey, pubKey, address, err := kctx.exportKey(params.Derive, params.MakeCurrent, params.OnlyPublic, params.Path)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "privateKey", hexString(privKey), "publicKey", hexString(pubKey), "address", address)
|
||||
//}
|
||||
|
||||
////export LoadSeed
|
||||
//func LoadSeed(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params loadSeedParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// pubKey, err := kctx.loadSeed(params.Seed)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "publicKey", hexString(pubKey))
|
||||
//}
|
||||
|
||||
////export Init
|
||||
//func Init(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params initSeedParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.init(params.Pin, params.Puk, params.PairingPassword)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export Unpair
|
||||
//func Unpair(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params unpairParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.unpair(params.Index)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export GetStatusApplication
|
||||
//func GetStatusApplication() *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// status, err := kctx.getStatusApplication()
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true, "status", ApplicationStatus{
|
||||
// PinRetryCount: status.PinRetryCount,
|
||||
// PUKRetryCount: status.PUKRetryCount,
|
||||
// KeyInitialized: status.KeyInitialized,
|
||||
// Path: status.Path,
|
||||
// })
|
||||
//}
|
||||
|
||||
////export ChangePin
|
||||
//func ChangePin(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params changeSecretsParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.changePin(params.Pin)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export ChangePuk
|
||||
//func ChangePuk(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params changeSecretsParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.changePuk(params.Puk)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export ChangePairingPassword
|
||||
//func ChangePairingPassword(jsonParams *C.char) *C.char {
|
||||
// if kctx == nil {
|
||||
// l("select: not started")
|
||||
// return retValue("error", "not started")
|
||||
// }
|
||||
|
||||
// var params changeSecretsParams
|
||||
// if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// err := kctx.changePairingPassword(params.PairingPassword)
|
||||
// if err != nil {
|
||||
// return retValue("error", err.Error())
|
||||
// }
|
||||
|
||||
// return retValue("ok", true)
|
||||
//}
|
||||
|
||||
////export KeycardSetSignalEventCallback
|
||||
//func KeycardSetSignalEventCallback(cb unsafe.Pointer) {
|
||||
// signal.KeycardSetSignalEventCallback(cb)
|
||||
//}
|
||||
|
||||
//func bytesToInt(s []byte) int {
|
||||
// if len(s) > 4 {
|
||||
// return 0
|
||||
// }
|
||||
|
||||
// var b [4]byte
|
||||
// copy(b[4-len(s):], s)
|
||||
// return int(binary.BigEndian.Uint32(b[:]))
|
||||
//}
|
@ -3,15 +3,67 @@ package main
|
||||
// #cgo LDFLAGS: -shared
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
|
||||
statuskeycardgo "github.com/status-im/status-keycard-go"
|
||||
skg "github.com/status-im/status-keycard-go"
|
||||
)
|
||||
|
||||
func main() {}
|
||||
|
||||
//export HelloWorld
|
||||
func HelloWorld() *C.char {
|
||||
res := statuskeycardgo.HelloWorld()
|
||||
return C.CString(fmt.Sprintf("shared lib: %s", res))
|
||||
var globalFlow *skg.KeycardFlow
|
||||
|
||||
func retErr(err error) *C.char {
|
||||
if err == nil {
|
||||
return C.CString("ok")
|
||||
} else {
|
||||
return C.CString(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func jsonToParams(jsonParams *C.char) (skg.FlowParams, error) {
|
||||
var params skg.FlowParams
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(jsonParams)), ¶ms); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
//export KeycardInitFlow
|
||||
func KeycardInitFlow(storageDir *C.char) *C.char {
|
||||
var err error
|
||||
globalFlow, err = skg.NewFlow(C.GoString(storageDir))
|
||||
|
||||
return retErr(err)
|
||||
}
|
||||
|
||||
//export KeycardStartFlow
|
||||
func KeycardStartFlow(flowType C.int, jsonParams *C.char) *C.char {
|
||||
params, err := jsonToParams(jsonParams)
|
||||
|
||||
if err != nil {
|
||||
return retErr(err)
|
||||
}
|
||||
|
||||
err = globalFlow.Start(skg.FlowType(flowType), params)
|
||||
return retErr(err)
|
||||
}
|
||||
|
||||
//export KeycardResumeFlow
|
||||
func KeycardResumeFlow(jsonParams *C.char) *C.char {
|
||||
params, err := jsonToParams(jsonParams)
|
||||
|
||||
if err != nil {
|
||||
return retErr(err)
|
||||
}
|
||||
|
||||
err = globalFlow.Resume(params)
|
||||
return retErr(err)
|
||||
}
|
||||
|
||||
//export KeycardCancelFlow
|
||||
func KeycardCancelFlow() *C.char {
|
||||
err := globalFlow.Cancel()
|
||||
return retErr(err)
|
||||
}
|
||||
|
58
types.go
58
types.go
@ -28,63 +28,12 @@ func (s *hexString) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type openSecureChannelParams struct {
|
||||
Index int `json:"index"`
|
||||
Key hexString `json:"key"`
|
||||
}
|
||||
|
||||
type verifyPinParams struct {
|
||||
Pin string `json:"pin"`
|
||||
}
|
||||
|
||||
type deriveKeyParams struct {
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type signWithPathParams struct {
|
||||
Data hexString `json:"data"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type exportKeyParams struct {
|
||||
Derive bool `json:"derive"`
|
||||
MakeCurrent bool `json:"makeCurrent"`
|
||||
OnlyPublic bool `json:"onlyPublic"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type loadSeedParams struct {
|
||||
Seed hexString `json:"seed"`
|
||||
}
|
||||
|
||||
type pairParams struct {
|
||||
PairingPassword string `json:"pairingPassword"`
|
||||
}
|
||||
|
||||
type initSeedParams struct {
|
||||
Pin string `json:"pin"`
|
||||
Puk string `json:"puk"`
|
||||
PairingPassword string `json:"pairingPassword"`
|
||||
}
|
||||
|
||||
type changeSecretsParams struct {
|
||||
Pin string `json:"pin"`
|
||||
Puk string `json:"puk"`
|
||||
PairingPassword string `json:"pairingPassword"`
|
||||
}
|
||||
|
||||
type unpairParams struct {
|
||||
Index uint8 `json:"index"`
|
||||
}
|
||||
|
||||
type Signature struct {
|
||||
R hexString `json:"r"`
|
||||
S hexString `json:"s"`
|
||||
V byte `json:"v"`
|
||||
}
|
||||
|
||||
type Capability uint8
|
||||
|
||||
type ApplicationInfo struct {
|
||||
Initialized bool `json:"initialized"`
|
||||
InstanceUID hexString `json:"instanceUID"`
|
||||
@ -100,13 +49,6 @@ type PairingInfo struct {
|
||||
Index int `json:"index"`
|
||||
}
|
||||
|
||||
type ApplicationStatus struct {
|
||||
PinRetryCount int `json:"pinRetryCount"`
|
||||
PUKRetryCount int `json:"pukRetryCount"`
|
||||
KeyInitialized bool `json:"keyInitialized"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type KeyPair struct {
|
||||
Address string `json:"address"`
|
||||
PublicKey hexString `json:"publicKey"`
|
||||
|
19
utils.go
19
utils.go
@ -1,33 +1,14 @@
|
||||
package statuskeycardgo
|
||||
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ebfe/scard"
|
||||
keycard "github.com/status-im/keycard-go"
|
||||
ktypes "github.com/status-im/keycard-go/types"
|
||||
)
|
||||
|
||||
func retValue(pairs ...interface{}) *C.char {
|
||||
obj := make(map[string]interface{})
|
||||
for i := 0; i < len(pairs)/2; i++ {
|
||||
key := pairs[i*2]
|
||||
value := pairs[(i*2)+1]
|
||||
obj[key.(string)] = value
|
||||
}
|
||||
|
||||
b, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return C.CString(err.Error())
|
||||
}
|
||||
|
||||
return C.CString(string(b))
|
||||
}
|
||||
|
||||
func isSCardError(err error) bool {
|
||||
_, ok := err.(scard.Error)
|
||||
return ok
|
||||
|
Loading…
x
Reference in New Issue
Block a user