go-ethereum/p2p/rlpx/rlpx_oracle_poc_test.go
fengjian c974722dc0
Some checks are pending
/ Docker Image (push) Waiting to run
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
crypto/ecies: fix ECIES invalid-curve handling (#33669)
Fix ECIES invalid-curve handling in RLPx handshake (reject invalid
ephemeral pubkeys early)
- Add curve validation in crypto/ecies.GenerateShared to reject invalid
public keys before ECDH.
- Update RLPx PoC test to assert invalid curve points fail with
ErrInvalidPublicKey.
 
Motivation / Context
RLPx handshake uses ECIES decryption on unauthenticated network input.
Prior to this change, an invalid-curve ephemeral public key would
proceed into ECDH and only fail at MAC verification, returning
ErrInvalidMessage. This allows an oracle on decrypt success/failure and
leaves the code path vulnerable to invalid-curve/small-subgroup attacks.
The fix enforces IsOnCurve validation up front.
2026-01-29 10:56:12 +01:00

57 lines
1.2 KiB
Go

package rlpx
import (
"bytes"
"errors"
"testing"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/ecies"
)
func TestHandshakeECIESInvalidCurveOracle(t *testing.T) {
initKey, err := crypto.GenerateKey()
if err != nil {
t.Fatal(err)
}
respKey, err := crypto.GenerateKey()
if err != nil {
t.Fatal(err)
}
init := handshakeState{
initiator: true,
remote: ecies.ImportECDSAPublic(&respKey.PublicKey),
}
authMsg, err := init.makeAuthMsg(initKey)
if err != nil {
t.Fatal(err)
}
packet, err := init.sealEIP8(authMsg)
if err != nil {
t.Fatal(err)
}
var recv handshakeState
if _, err := recv.readMsg(new(authMsgV4), respKey, bytes.NewReader(packet)); err != nil {
t.Fatalf("expected valid packet to decrypt: %v", err)
}
tampered := append([]byte(nil), packet...)
if len(tampered) < 2+65 {
t.Fatalf("unexpected packet length %d", len(tampered))
}
tampered[2] = 0x04
for i := 1; i < 65; i++ {
tampered[2+i] = 0x00
}
var recv2 handshakeState
_, err = recv2.readMsg(new(authMsgV4), respKey, bytes.NewReader(tampered))
if err == nil {
t.Fatal("expected decryption failure for invalid curve point")
}
if !errors.Is(err, ecies.ErrInvalidPublicKey) {
t.Fatalf("unexpected error: %v", err)
}
}