internal/ethapi: fix hex handling for eth_sign, personal_{sign,recover}
This commit is contained in:
		| @@ -28,6 +28,7 @@ import ( | |||||||
| 	"github.com/ethereum/ethash" | 	"github.com/ethereum/ethash" | ||||||
| 	"github.com/ethereum/go-ethereum/accounts" | 	"github.com/ethereum/go-ethereum/accounts" | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | 	"github.com/ethereum/go-ethereum/common/hexutil" | ||||||
| 	"github.com/ethereum/go-ethereum/core" | 	"github.com/ethereum/go-ethereum/core" | ||||||
| 	"github.com/ethereum/go-ethereum/core/types" | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
| 	"github.com/ethereum/go-ethereum/core/vm" | 	"github.com/ethereum/go-ethereum/core/vm" | ||||||
| @@ -289,14 +290,14 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs | |||||||
| } | } | ||||||
|  |  | ||||||
| // signHash is a helper function that calculates a hash for the given message that can be | // signHash is a helper function that calculates a hash for the given message that can be | ||||||
| // safely used to calculate a signature from. The hash is calulcated with: | // safely used to calculate a signature from. | ||||||
|  | // | ||||||
|  | // The hash is calulcated as | ||||||
| //   keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). | //   keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). | ||||||
| func signHash(message string) []byte { | // | ||||||
| 	data := common.FromHex(message) | // This gives context to the signed message and prevents signing of transactions. | ||||||
| 	// Give context to the signed message. This prevents an adversery to sign a tx. | func signHash(data []byte) []byte { | ||||||
| 	// It has no cryptographic purpose. |  | ||||||
| 	msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) | 	msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) | ||||||
| 	// Always hash, this prevents choosen plaintext attacks that can extract key information |  | ||||||
| 	return crypto.Keccak256([]byte(msg)) | 	return crypto.Keccak256([]byte(msg)) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -306,13 +307,8 @@ func signHash(message string) []byte { | |||||||
| // The key used to calculate the signature is decrypted with the given password. | // The key used to calculate the signature is decrypted with the given password. | ||||||
| // | // | ||||||
| // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign | // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign | ||||||
| func (s *PrivateAccountAPI) Sign(ctx context.Context, message string, addr common.Address, passwd string) (string, error) { | func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { | ||||||
| 	hash := signHash(message) | 	return s.b.AccountManager().SignWithPassphrase(addr, passwd, signHash(data)) | ||||||
| 	signature, err := s.b.AccountManager().SignWithPassphrase(addr, passwd, hash) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "0x", err |  | ||||||
| 	} |  | ||||||
| 	return common.ToHex(signature), nil |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // EcRecover returns the address for the account that was used to create the signature. | // EcRecover returns the address for the account that was used to create the signature. | ||||||
| @@ -322,29 +318,20 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, message string, addr commo | |||||||
| // addr = ecrecover(hash, signature) | // addr = ecrecover(hash, signature) | ||||||
| // | // | ||||||
| // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover | // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover | ||||||
| func (s *PrivateAccountAPI) EcRecover(ctx context.Context, message string, signature string) (common.Address, error) { | func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { | ||||||
| 	var ( |  | ||||||
| 		hash = signHash(message) |  | ||||||
| 		sig  = common.FromHex(signature) |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	if len(sig) != 65 { | 	if len(sig) != 65 { | ||||||
| 		return common.Address{}, fmt.Errorf("signature must be 65 bytes long") | 		return common.Address{}, fmt.Errorf("signature must be 65 bytes long") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// see crypto.Ecrecover description | 	// see crypto.Ecrecover description | ||||||
| 	if sig[64] == 27 || sig[64] == 28 { | 	if sig[64] == 27 || sig[64] == 28 { | ||||||
| 		sig[64] -= 27 | 		sig[64] -= 27 | ||||||
| 	} | 	} | ||||||
|  | 	rpk, err := crypto.Ecrecover(signHash(data), sig) | ||||||
| 	rpk, err := crypto.Ecrecover(hash, sig) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return common.Address{}, err | 		return common.Address{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pubKey := crypto.ToECDSAPub(rpk) | 	pubKey := crypto.ToECDSAPub(rpk) | ||||||
| 	recoveredAddr := crypto.PubkeyToAddress(*pubKey) | 	recoveredAddr := crypto.PubkeyToAddress(*pubKey) | ||||||
|  |  | ||||||
| 	return recoveredAddr, nil | 	return recoveredAddr, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1116,10 +1103,8 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod | |||||||
| // The account associated with addr must be unlocked. | // The account associated with addr must be unlocked. | ||||||
| // | // | ||||||
| // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign | // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign | ||||||
| func (s *PublicTransactionPoolAPI) Sign(addr common.Address, message string) (string, error) { | func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { | ||||||
| 	hash := signHash(message) | 	return s.b.AccountManager().SignEthereum(addr, signHash(data)) | ||||||
| 	signature, err := s.b.AccountManager().SignEthereum(addr, hash) |  | ||||||
| 	return common.ToHex(signature), err |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // SignTransactionArgs represents the arguments to sign a transaction. | // SignTransactionArgs represents the arguments to sign a transaction. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user