add HashMessage to backend, lib, and mobile. (#1421)
* add HashMessage to backend, lib, and mobile. * move HashMessage out of the backend struct * fix comment typo
This commit is contained in:
parent
eeaf669006
commit
a61c0368bc
15
api/utils.go
15
api/utils.go
|
@ -1,5 +1,11 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
// RunAsync runs the specified function asynchronously.
|
||||
func RunAsync(f func() error) <-chan error {
|
||||
resp := make(chan error, 1)
|
||||
|
@ -10,3 +16,12 @@ func RunAsync(f func() error) <-chan error {
|
|||
}()
|
||||
return resp
|
||||
}
|
||||
|
||||
// HashMessage calculates the hash of a message to be safely signed by the keycard
|
||||
// The hash is calulcated as
|
||||
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
|
||||
// This gives context to the signed message and prevents signing of transactions.
|
||||
func HashMessage(data []byte) []byte {
|
||||
msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
|
||||
return crypto.Keccak256([]byte(msg))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/services/personal"
|
||||
"github.com/status-im/status-go/t/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHashMessage(t *testing.T) {
|
||||
backend := NewStatusBackend()
|
||||
config, err := utils.MakeTestNodeConfig(params.StatusChainNetworkID)
|
||||
require.NoError(t, err)
|
||||
err = backend.StartNode(config)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
require.NoError(t, backend.StopNode())
|
||||
}()
|
||||
|
||||
key, err := crypto.GenerateKey()
|
||||
require.NoError(t, err)
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
originalMessage := []byte{0x01, 0x02, 0x03}
|
||||
hash := HashMessage(originalMessage)
|
||||
|
||||
// simulate signature from external signer like a keycard
|
||||
sig, err := crypto.Sign(hash, key)
|
||||
require.NoError(t, err)
|
||||
sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
|
||||
|
||||
// check that the message was wrapped correctly before hashing it
|
||||
recParams := personal.RecoverParams{
|
||||
Message: fmt.Sprintf("0x%x", originalMessage),
|
||||
Signature: fmt.Sprintf("0x%x", sig),
|
||||
}
|
||||
recoveredAddr, err := backend.Recover(recParams)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, addr, recoveredAddr)
|
||||
}
|
|
@ -454,6 +454,21 @@ func HashTransaction(txArgsJSON *C.char) *C.char {
|
|||
return C.CString(prepareJSONResponseWithCode(result, err, code))
|
||||
}
|
||||
|
||||
// HashMessage calculates the hash of a message to be safely signed by the keycard
|
||||
// The hash is calulcated as
|
||||
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
|
||||
// This gives context to the signed message and prevents signing of transactions.
|
||||
//export HashMessage
|
||||
func HashMessage(messageString *C.char) *C.char {
|
||||
message, err := hex.DecodeString(C.GoString(messageString))
|
||||
if err != nil {
|
||||
return C.CString(prepareJSONResponseWithCode(nil, err, codeFailedParseParams))
|
||||
}
|
||||
|
||||
hash := api.HashMessage(message)
|
||||
return C.CString(prepareJSONResponseWithCode(fmt.Sprintf("0x%x", hash), err, codeUnknown))
|
||||
}
|
||||
|
||||
// SignTypedData unmarshall data into TypedData, validate it and signs with selected account,
|
||||
// if password matches selected account.
|
||||
//export SignTypedData
|
||||
|
|
|
@ -442,6 +442,20 @@ func HashTransaction(txArgsJSON string) string {
|
|||
return prepareJSONResponseWithCode(result, err, code)
|
||||
}
|
||||
|
||||
// HashMessage calculates the hash of a message to be safely signed by the keycard
|
||||
// The hash is calulcated as
|
||||
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
|
||||
// This gives context to the signed message and prevents signing of transactions.
|
||||
func HashMessage(messageString string) string {
|
||||
message, err := hex.DecodeString(messageString)
|
||||
if err != nil {
|
||||
return prepareJSONResponseWithCode(nil, err, codeFailedParseParams)
|
||||
}
|
||||
|
||||
hash := api.HashMessage(message)
|
||||
return prepareJSONResponseWithCode(fmt.Sprintf("0x%x", hash), err, codeUnknown)
|
||||
}
|
||||
|
||||
// StartCPUProfile runs pprof for CPU.
|
||||
func StartCPUProfile(dataDir string) string {
|
||||
err := profiling.StartCPUProfile(dataDir)
|
||||
|
|
Loading…
Reference in New Issue