diff --git a/types/certificate.go b/types/certificate.go index 8e3f8e6..359a4ce 100644 --- a/types/certificate.go +++ b/types/certificate.go @@ -4,7 +4,6 @@ import ( "crypto/sha256" "errors" - "github.com/ethereum/go-ethereum/crypto" "github.com/status-im/keycard-go/apdu" ) @@ -23,7 +22,7 @@ func ParseCertificate(data []byte) (*Certificate, error) { } identPub := data[0:33] - sigData := data[33:97] + sigData := data[33:98] msg := sha256.Sum256(identPub) sig, err := ParseRecoverableSignature(msg[:], sigData) @@ -58,25 +57,12 @@ func VerifyIdentity(challenge []byte, tlvData []byte) ([]byte, error) { return nil, err } - sig := append(r, s...) + // TODO: investigate why verify signature fails but recovery works + _, err = calculateV(challenge, cert.identPub, r, s) - if !crypto.VerifySignature(cert.identPub, challenge, sig) { + if err != nil { return nil, errors.New("invalid signature") } return compressPublicKey(cert.signature.pubKey), nil } - -func compressPublicKey(pubKey []byte) []byte { - if len(pubKey) == 33 { - return pubKey - } - - if (pubKey[63] & 1) == 1 { - pubKey[0] = 3 - } else { - pubKey[0] = 2 - } - - return pubKey[0:33] -} diff --git a/types/certificate_test.go b/types/certificate_test.go new file mode 100644 index 0000000..af473fd --- /dev/null +++ b/types/certificate_test.go @@ -0,0 +1,23 @@ +package types + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" +) + +func hexMustDecode(str string) []byte { + out, _ := hex.DecodeString(str) + return out +} + +func TestVerifyIdentity(t *testing.T) { + challenge := hexMustDecode("63acd6e02a8b5783551ff2836a9cbdf237c115c3ff018b943f044e6a69b19fe7") + response := hexMustDecode("a081ab8a620365c18485fe7018e11cb992011426803aa8e843c63aab9657aed7d3ee4b85a62a11188ada267db3312a84e1be27c01c736a89da7a1fe4f7e90ce297e74f00008e2bfdb06058374abfc1c026386d16ead7bbc19bc0645d2e7acf7b953169bbc1ac0130450220364c5ca937b7ca42861978f086d206cc569ef0bb2ea4c7de08929c2fcca7434d022100c87699ce4f977e6a7a4800343db9b6842b91ca873e56dfe3327d19a2d01af14e") + expectedKey := hexMustDecode("02fc929321aa94fea085b166994aa66590116252cf0235a03accaa2c8ab4595de5") + + pubkey, err := VerifyIdentity(challenge, response) + assert.NoError(t, err) + assert.Equal(t, expectedKey, pubkey) +} diff --git a/types/signature.go b/types/signature.go index 82a71d6..f9d551e 100644 --- a/types/signature.go +++ b/types/signature.go @@ -126,6 +126,10 @@ func calculateV(message, pubKey, r, s []byte) (v byte, err error) { return v, err } + if len(pubKey) == 33 { + rec = compressPublicKey(rec) + } + if bytes.Equal(pubKey, rec) { return v, nil } @@ -133,3 +137,17 @@ func calculateV(message, pubKey, r, s []byte) (v byte, err error) { return v, err } + +func compressPublicKey(pubKey []byte) []byte { + if len(pubKey) == 33 { + return pubKey + } + + if (pubKey[63] & 1) == 1 { + pubKey[0] = 3 + } else { + pubKey[0] = 2 + } + + return pubKey[0:33] +}