diff --git a/dappauth.go b/dappauth.go index fd9b0ce..1b3e1b4 100644 --- a/dappauth.go +++ b/dappauth.go @@ -5,7 +5,9 @@ package dappauth import ( "bytes" "context" + "encoding/hex" "fmt" + "strings" "github.com/dapperlabs/dappauth/ERCs" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -83,9 +85,16 @@ func (a *Authenticator) IsAuthorizedSigner(challenge, signature, addrHex string) return magicValue == _ERC1271MagicValue, nil } +// See https://github.com/MetaMask/eth-sig-util/issues/60 func personalMessageHash(message string) []byte { - msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(message), message) - return ethCrypto.Keccak256([]byte(msg)) + b, err := hex.DecodeString(strings.TrimPrefix(message, "0x")) + // if hex decode was successful, then treat is as a hex string + if err == nil { + msgToHash := fmt.Sprintf("\x19Ethereum Signed Message:\n%d", len(b)) + return ethCrypto.Keccak256(append([]byte(msgToHash), b...)) + } + msgToHash := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(message), message) + return ethCrypto.Keccak256([]byte(msgToHash)) } func mergeErrors(errEOA error, errCA error) error { diff --git a/dappauth_test.go b/dappauth_test.go index 7b8355c..74dc1d9 100644 --- a/dappauth_test.go +++ b/dappauth_test.go @@ -3,6 +3,7 @@ package dappauth import ( "crypto/ecdsa" "encoding/hex" + "fmt" "testing" "github.com/ethereum/go-ethereum/common" @@ -172,6 +173,25 @@ func TestDappAuth(t *testing.T) { } +// It should decode challenge as utf8 by default when computing EOA personal messages hash +func TestPersonalMessageDecodeUTF8(t *testing.T) { + ethMsgHash := personalMessageHash("foo") + eoaHash := hex.EncodeToString(ethMsgHash) + + expectString(fmt.Sprintf("0x%s", eoaHash), "0x76b2e96714d3b5e6eb1d1c509265430b907b44f72b2a22b06fcd4d96372b8565", t) +} + +// It should decode challenge as hex if hex is detected when computing EOA personal messages hash +// See https://github.com/MetaMask/eth-sig-util/issues/60 +func TestPersonalMessageDecodeHex(t *testing.T) { + ethMsgHash := personalMessageHash("0xffff") + eoaHash := hex.EncodeToString(ethMsgHash) + + // result if 0xffff is decoded as hex: 13a6aa3102b2d639f36804a2d7c31469618fd7a7907c658a7b2aa91a06e31e47 + // result if 0xffff is decoded as utf8: 247aefb5d2e5b17fca61f786c779f7388485460c13e51308f88b2ff84ffa6851 + expectString(fmt.Sprintf("0x%s", eoaHash), "0x13a6aa3102b2d639f36804a2d7c31469618fd7a7907c658a7b2aa91a06e31e47", t) +} + func generateSignature(isEOA bool, msg string, key *ecdsa.PrivateKey, address common.Address, t *testing.T) string { if isEOA { return signEOAPersonalMessage(msg, key, t) @@ -212,3 +232,9 @@ func expectBool(actual, expected bool, t *testing.T) { t.Errorf("expected %v to be %v", actual, expected) } } + +func expectString(actual, expected string, t *testing.T) { + if actual != expected { + t.Errorf("expected %s to be %s", actual, expected) + } +}