parse sign response and calculate v

This commit is contained in:
Andrea Franz 2019-03-15 10:26:38 +01:00
parent 74895bb582
commit 572bbdc339
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
2 changed files with 83 additions and 1 deletions

View File

@ -199,7 +199,7 @@ func (cs *CommandSet) Sign(data []byte) (*types.Signature, error) {
return nil, err
}
return types.ParseSignature(resp.Data)
return types.ParseSignature(data, resp.Data)
}
func (cs *CommandSet) mutualAuthenticate() error {

82
types/signature.go Normal file
View File

@ -0,0 +1,82 @@
package types
import (
"bytes"
"github.com/ethereum/go-ethereum/crypto"
"github.com/status-im/keycard-go/apdu"
)
var (
TagSignatureTemplate = uint8(0xA0)
)
type Signature struct {
pubKey []byte
r []byte
s []byte
v byte
}
func ParseSignature(message, resp []byte) (*Signature, error) {
pubKey, err := apdu.FindTag(resp, TagSignatureTemplate, uint8(0x80))
if err != nil {
return nil, err
}
r, err := apdu.FindTagN(resp, 0, TagSignatureTemplate, uint8(0x30), uint8(0x02))
if err != nil {
return nil, err
}
if len(r) > 32 {
r = r[len(r)-32:]
}
s, err := apdu.FindTagN(resp, 1, TagSignatureTemplate, uint8(0x30), uint8(0x02))
if err != nil {
return nil, err
}
v, err := calculateV(message, pubKey, r, s)
if err != nil {
return nil, err
}
return &Signature{
pubKey: pubKey,
r: r,
s: s,
v: v,
}, nil
}
func (s *Signature) R() []byte {
return s.r
}
func (s *Signature) S() []byte {
return s.s
}
func (s *Signature) V() byte {
return s.v
}
func calculateV(message, pubKey, r, s []byte) (v byte, err error) {
rs := append(r, s...)
for i := 0; i < 2; i++ {
v = byte(i)
sig := append(rs, v)
rec, err := crypto.Ecrecover(message, sig)
if err != nil {
return v, err
}
if bytes.Equal(pubKey, rec) {
return v, nil
}
}
return v, err
}