mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-07 13:55:17 +00:00
p2p: only allow ed25519 pubkeys when connecting
also, recover from any possible failures in acceptPeers Refs #4030
This commit is contained in:
@@ -7,21 +7,22 @@ import (
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
pool "github.com/libp2p/go-buffer-pool"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
|
||||
pool "github.com/libp2p/go-buffer-pool"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
)
|
||||
|
||||
// 4 + 1024 == 1028 total frame size
|
||||
@@ -107,11 +108,11 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (*
|
||||
|
||||
sendAead, err := chacha20poly1305.New(sendSecret[:])
|
||||
if err != nil {
|
||||
return nil, errors.New("Invalid send SecretConnection Key")
|
||||
return nil, errors.New("invalid send SecretConnection Key")
|
||||
}
|
||||
recvAead, err := chacha20poly1305.New(recvSecret[:])
|
||||
if err != nil {
|
||||
return nil, errors.New("Invalid receive SecretConnection Key")
|
||||
return nil, errors.New("invalid receive SecretConnection Key")
|
||||
}
|
||||
// Construct SecretConnection.
|
||||
sc := &SecretConnection{
|
||||
@@ -134,12 +135,12 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (*
|
||||
|
||||
remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig
|
||||
|
||||
if remPubKey == nil {
|
||||
return nil, errors.New("peer sent a nil public key")
|
||||
if _, ok := remPubKey.(ed25519.PubKeyEd25519); !ok {
|
||||
return nil, errors.Errorf("expected ed25519 pubkey, got %T", remPubKey)
|
||||
}
|
||||
|
||||
if !remPubKey.VerifyBytes(challenge[:], remSignature) {
|
||||
return nil, errors.New("Challenge verification failed")
|
||||
return nil, errors.New("challenge verification failed")
|
||||
}
|
||||
|
||||
// We've authorized.
|
||||
@@ -222,7 +223,7 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) {
|
||||
defer pool.Put(frame)
|
||||
_, err = sc.recvAead.Open(frame[:0], sc.recvNonce[:], sealedFrame, nil)
|
||||
if err != nil {
|
||||
return n, errors.New("Failed to decrypt SecretConnection")
|
||||
return n, errors.New("failed to decrypt SecretConnection")
|
||||
}
|
||||
incrNonce(sc.recvNonce)
|
||||
// end decryption
|
||||
|
||||
@@ -16,7 +16,9 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
@@ -365,6 +367,51 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type privKeyWithNilPubKey struct {
|
||||
orig crypto.PrivKey
|
||||
}
|
||||
|
||||
func (pk privKeyWithNilPubKey) Bytes() []byte { return pk.orig.Bytes() }
|
||||
func (pk privKeyWithNilPubKey) Sign(msg []byte) ([]byte, error) { return pk.orig.Sign(msg) }
|
||||
func (pk privKeyWithNilPubKey) PubKey() crypto.PubKey { return nil }
|
||||
func (pk privKeyWithNilPubKey) Equals(pk2 crypto.PrivKey) bool { return pk.orig.Equals(pk2) }
|
||||
|
||||
func TestNilPubkey(t *testing.T) {
|
||||
var fooConn, barConn = makeKVStoreConnPair()
|
||||
var fooPrvKey = ed25519.GenPrivKey()
|
||||
var barPrvKey = privKeyWithNilPubKey{ed25519.GenPrivKey()}
|
||||
|
||||
go func() {
|
||||
_, err := MakeSecretConnection(barConn, barPrvKey)
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
_, err := MakeSecretConnection(fooConn, fooPrvKey)
|
||||
if assert.Error(t, err) {
|
||||
assert.Equal(t, "expected ed25519 pubkey, got <nil>", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNonEd25519Pubkey(t *testing.T) {
|
||||
var fooConn, barConn = makeKVStoreConnPair()
|
||||
var fooPrvKey = ed25519.GenPrivKey()
|
||||
var barPrvKey = secp256k1.GenPrivKey()
|
||||
|
||||
go func() {
|
||||
_, err := MakeSecretConnection(barConn, barPrvKey)
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
_, err := MakeSecretConnection(fooConn, fooPrvKey)
|
||||
if assert.Error(t, err) {
|
||||
assert.Equal(t, "expected ed25519 pubkey, got secp256k1.PubKeySecp256k1", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Creates the data for a test vector file.
|
||||
// The file format is:
|
||||
// Hex(diffie_hellman_secret), loc_is_least, Hex(recvSecret), Hex(sendSecret), Hex(challenge)
|
||||
|
||||
Reference in New Issue
Block a user