From fec3b56f7f440b635787f740b527f15b818c0e1b Mon Sep 17 00:00:00 2001
From: Martin Holst Swende <martin@swende.se>
Date: Sun, 26 May 2019 00:07:10 +0200
Subject: [PATCH] accounts, p2p, rpc: make CGO_ENABLED=0 build again (#19593)

* p2p: remove direct import of cgo-library

* accounts, rpc: more nocgo alternatives

* rpc: move unix path constant into separate file

* accounts/scwallet: address review concerns, remove copy-pasta
---
 accounts/scwallet/wallet.go | 25 ++++++++-----------------
 p2p/discover/node.go        |  3 +--
 p2p/rlpx.go                 |  3 +--
 rpc/constants_unix.go       | 33 +++++++++++++++++++++++++++++++++
 rpc/constants_unix_nocgo.go | 25 +++++++++++++++++++++++++
 rpc/ipc_unix.go             | 16 +++-------------
 6 files changed, 71 insertions(+), 34 deletions(-)
 create mode 100644 rpc/constants_unix.go
 create mode 100644 rpc/constants_unix_nocgo.go

diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go
index 4c0824eb9..71b2c68af 100644
--- a/accounts/scwallet/wallet.go
+++ b/accounts/scwallet/wallet.go
@@ -37,7 +37,6 @@ import (
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/crypto/secp256k1"
 	"github.com/ethereum/go-ethereum/log"
 	pcsc "github.com/gballet/go-libpcsclite"
 	"github.com/status-im/keycard-go/derivationpath"
@@ -1050,33 +1049,25 @@ func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error
 // determinePublicKey uses a signature and the X component of a public key to
 // recover the entire public key.
 func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) {
-	for v := 0; v < 2; v++ {
-		sig[64] = byte(v)
-		pubkey, err := crypto.Ecrecover(DerivationSignatureHash[:], sig)
-		if err == nil {
-			if bytes.Equal(pubkey, pubkeyX) {
-				return pubkey, nil
-			}
-		} else if v == 1 || err != secp256k1.ErrRecoverFailed {
-			return nil, err
-		}
-	}
-	return nil, ErrPubkeyMismatch
+	return makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkeyX)
 }
 
 // makeRecoverableSignature uses a signature and an expected public key to
 // recover the v value and produce a recoverable signature.
 func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) {
+	var libraryError error
 	for v := 0; v < 2; v++ {
 		sig[64] = byte(v)
-		pubkey, err := crypto.Ecrecover(hash, sig)
-		if err == nil {
+		if pubkey, err := crypto.Ecrecover(hash, sig); err == nil {
 			if bytes.Equal(pubkey, expectedPubkey) {
 				return sig, nil
 			}
-		} else if v == 1 || err != secp256k1.ErrRecoverFailed {
-			return nil, err
+		} else {
+			libraryError = err
 		}
 	}
+	if libraryError != nil {
+		return nil, libraryError
+	}
 	return nil, ErrPubkeyMismatch
 }
diff --git a/p2p/discover/node.go b/p2p/discover/node.go
index 8d4af166b..a7d9ce736 100644
--- a/p2p/discover/node.go
+++ b/p2p/discover/node.go
@@ -25,7 +25,6 @@ import (
 
 	"github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/crypto/secp256k1"
 	"github.com/ethereum/go-ethereum/p2p/enode"
 )
 
@@ -64,7 +63,7 @@ func (e encPubkey) id() enode.ID {
 // recoverNodeKey computes the public key used to sign the
 // given hash from the signature.
 func recoverNodeKey(hash, sig []byte) (key encPubkey, err error) {
-	pubkey, err := secp256k1.RecoverPubkey(hash, sig)
+	pubkey, err := crypto.Ecrecover(hash, sig)
 	if err != nil {
 		return key, err
 	}
diff --git a/p2p/rlpx.go b/p2p/rlpx.go
index 0697ef3b0..0636431f5 100644
--- a/p2p/rlpx.go
+++ b/p2p/rlpx.go
@@ -38,7 +38,6 @@ import (
 	"github.com/ethereum/go-ethereum/common/bitutil"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/crypto/ecies"
-	"github.com/ethereum/go-ethereum/crypto/secp256k1"
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/golang/snappy"
 	"golang.org/x/crypto/sha3"
@@ -400,7 +399,7 @@ func (h *encHandshake) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) erro
 		return err
 	}
 	signedMsg := xor(token, h.initNonce)
-	remoteRandomPub, err := secp256k1.RecoverPubkey(signedMsg, msg.Signature[:])
+	remoteRandomPub, err := crypto.Ecrecover(signedMsg, msg.Signature[:])
 	if err != nil {
 		return err
 	}
diff --git a/rpc/constants_unix.go b/rpc/constants_unix.go
new file mode 100644
index 000000000..2f98d6499
--- /dev/null
+++ b/rpc/constants_unix.go
@@ -0,0 +1,33 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package rpc
+
+/*
+#include <sys/un.h>
+
+int max_socket_path_size() {
+struct sockaddr_un s;
+return sizeof(s.sun_path);
+}
+*/
+import "C"
+
+var (
+	max_path_size = C.max_socket_path_size()
+)
diff --git a/rpc/constants_unix_nocgo.go b/rpc/constants_unix_nocgo.go
new file mode 100644
index 000000000..ecb231f92
--- /dev/null
+++ b/rpc/constants_unix_nocgo.go
@@ -0,0 +1,25 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// +build !cgo,!windows
+
+package rpc
+
+var (
+	//  On Linux, sun_path is 108 bytes in size
+	// see http://man7.org/linux/man-pages/man7/unix.7.html
+	max_path_size = 108
+)
diff --git a/rpc/ipc_unix.go b/rpc/ipc_unix.go
index 707b47fd7..da6ce294d 100644
--- a/rpc/ipc_unix.go
+++ b/rpc/ipc_unix.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The go-ethereum Authors
+// Copyright 2019 The go-ethereum Authors
 // This file is part of the go-ethereum library.
 //
 // The go-ethereum library is free software: you can redistribute it and/or modify
@@ -28,20 +28,10 @@ import (
 	"github.com/ethereum/go-ethereum/log"
 )
 
-/*
-#include <sys/un.h>
-
-int max_socket_path_size() {
-struct sockaddr_un s;
-return sizeof(s.sun_path);
-}
-*/
-import "C"
-
 // ipcListen will create a Unix socket on the given endpoint.
 func ipcListen(endpoint string) (net.Listener, error) {
-	if len(endpoint) > int(C.max_socket_path_size()) {
-		log.Warn(fmt.Sprintf("The ipc endpoint is longer than %d characters. ", C.max_socket_path_size()),
+	if len(endpoint) > int(max_path_size) {
+		log.Warn(fmt.Sprintf("The ipc endpoint is longer than %d characters. ", max_path_size),
 			"endpoint", endpoint)
 	}
 
-- 
GitLab