parse sign response and calculate v
This commit is contained in:
parent
74895bb582
commit
572bbdc339
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue