implement sign flow

This commit is contained in:
Michele Balistreri 2021-10-27 08:46:00 +03:00
parent d45beefc14
commit e3c16d0e57
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
5 changed files with 103 additions and 22 deletions

View File

@ -94,5 +94,6 @@ func main() {
testFlow(skg.RecoverAccount, skg.FlowParams{skg.PIN: "234567"})
testFlow(skg.Login, 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})
}

31
flow.go
View File

@ -326,17 +326,8 @@ func (f *KeycardFlow) exportPublicFlow(kc *keycardContext) (FlowStatus, error) {
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 {
return nil, err
}
@ -349,7 +340,25 @@ func (f *KeycardFlow) loadKeysFlow(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) {

View File

@ -12,8 +12,8 @@ func (f *KeycardFlow) factoryReset(kc *keycardContext) error {
func (f *KeycardFlow) selectKeycard(kc *keycardContext) error {
appInfo, err := kc.selectApplet()
f.cardInfo.instanceUID = tox(appInfo.InstanceUID)
f.cardInfo.keyUID = tox(appInfo.KeyUID)
f.cardInfo.instanceUID = btox(appInfo.InstanceUID)
f.cardInfo.keyUID = btox(appInfo.KeyUID)
f.cardInfo.freeSlots = bytesToInt(appInfo.AvailableSlots)
if err != nil {
@ -280,6 +280,22 @@ func (f *KeycardFlow) exportKey(kc *keycardContext, path string, onlyPublic bool
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 {
if newPIN, ok := f.params[NewPIN]; ok {
err := kc.changePin(newPIN.(string))
@ -345,3 +361,48 @@ func (f *KeycardFlow) changePairing(kc *keycardContext) error {
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
}

View File

@ -1,7 +1,6 @@
package statuskeycardgo
import (
"encoding/hex"
"encoding/json"
)
@ -9,7 +8,7 @@ type hexString []byte
// MarshalJSON serializes hexString to hex
func (s hexString) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(tox(s))
bytes, err := json.Marshal(btox(s))
return bytes, err
}
@ -20,7 +19,7 @@ func (s *hexString) UnmarshalJSON(data []byte) error {
if err != nil {
return err
}
str, err := hex.DecodeString(x)
str, err := xtob(x)
if err != nil {
return err
}
@ -79,10 +78,9 @@ type unpairParams struct {
}
type Signature struct {
PublicKey hexString `json:"publicKey"`
R hexString `json:"r"`
S hexString `json:"s"`
V byte `json:"v"`
R hexString `json:"r"`
S hexString `json:"s"`
V byte `json:"v"`
}
type Capability uint8

View File

@ -29,7 +29,7 @@ func retValue(pairs ...interface{}) *C.char {
}
func isSCardError(err error) bool {
_, ok := err.(*scard.Error)
_, ok := err.(scard.Error)
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)
}
func xtob(str string) ([]byte, error) {
return hex.DecodeString(str)
}
func bytesToInt(s []byte) int {
if len(s) > 4 {
return 0
@ -73,3 +77,11 @@ func toPairInfo(r *ktypes.PairingInfo) *PairingInfo {
Index: r.Index,
}
}
func toSignature(r *ktypes.Signature) *Signature {
return &Signature{
R: r.R(),
S: r.S(),
V: r.V(),
}
}