mirror of https://github.com/status-im/nim-eth.git
Add rlp_decode fuzz test + some corpus generate code
This commit is contained in:
parent
4e4836a0fe
commit
f0638eb3f1
|
@ -19,10 +19,10 @@ const
|
|||
type
|
||||
PacketTag* = array[tagSize, byte]
|
||||
|
||||
AuthResponse = object
|
||||
version: int
|
||||
signature: array[64, byte]
|
||||
record: Option[enr.Record]
|
||||
AuthResponse* = object
|
||||
version*: int
|
||||
signature*: array[64, byte]
|
||||
record*: Option[enr.Record]
|
||||
|
||||
Codec* = object
|
||||
localNode*: Node
|
||||
|
|
|
@ -230,7 +230,7 @@ proc `xor`[N: static[int], T](a, b: array[N, T]): array[N, T] =
|
|||
for i in 0 .. a.high:
|
||||
result[i] = a[i] xor b[i]
|
||||
|
||||
proc whoareyouMagic(toNode: NodeId): array[magicSize, byte] =
|
||||
proc whoareyouMagic*(toNode: NodeId): array[magicSize, byte] =
|
||||
const prefix = "WHOAREYOU"
|
||||
var data: array[prefix.len + sizeof(toNode), byte]
|
||||
data[0 .. sizeof(toNode) - 1] = toNode.toByteArrayBE()
|
||||
|
|
|
@ -8,7 +8,8 @@ var targetNode: protocol.Protocol
|
|||
init:
|
||||
let
|
||||
rng = newRng()
|
||||
privKey = PrivateKey.random(rng[])
|
||||
privKey = PrivateKey.fromHex(
|
||||
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
|
||||
ip = some(ValidIpAddress.init("127.0.0.1"))
|
||||
port = Port(20301)
|
||||
dbb = DiscoveryDB.init(newMemoryDB())
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import
|
||||
std/[os, strutils],
|
||||
stew/shims/net,
|
||||
eth/[rlp, keys], eth/p2p/discoveryv5/[encoding, enr, types],
|
||||
../fuzzing_helpers
|
||||
|
||||
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||
const inputsDir = sourceDir / "corpus" & DirSep
|
||||
|
||||
proc generate() =
|
||||
let
|
||||
rng = keys.newRng()
|
||||
privKey = PrivateKey.random(rng[])
|
||||
pubKey = PrivateKey.random(rng[]).toPublicKey()
|
||||
var idNonce: IdNonce
|
||||
brHmacDrbgGenerate(rng[], idNonce)
|
||||
|
||||
let
|
||||
ephKeys = KeyPair.random(rng[])
|
||||
signature = signIDNonce(privKey, idNonce, ephKeys.pubkey.toRaw)
|
||||
record = enr.Record.init(1, privKey, none(ValidIpAddress), Port(9000),
|
||||
Port(9000))[]
|
||||
authResponse =
|
||||
AuthResponse(version: 5, signature: signature.toRaw, record: some(record))
|
||||
authResponseNoRecord =
|
||||
AuthResponse(version: 5, signature: signature.toRaw, record: none(enr.Record))
|
||||
|
||||
rlp.encode(authResponse).toFile(inputsDir & "auth-response")
|
||||
rlp.encode(authResponseNoRecord).toFile(inputsDir & "auth-response-no-enr")
|
||||
|
||||
discard existsOrCreateDir(inputsDir)
|
||||
generate()
|
|
@ -0,0 +1,51 @@
|
|||
import
|
||||
std/[os, strutils],
|
||||
stew/shims/net,
|
||||
eth/[keys, rlp, trie/db],
|
||||
eth/p2p/discoveryv5/[protocol, discovery_db, enr, node, types, encoding],
|
||||
../fuzzing_helpers
|
||||
|
||||
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||
const inputsDir = sourceDir / "corpus" & DirSep
|
||||
|
||||
proc generate() =
|
||||
let
|
||||
rng = keys.newRng()
|
||||
privKey = PrivateKey.random(rng[])
|
||||
ip = some(ValidIpAddress.init("127.0.0.1"))
|
||||
port = Port(20301)
|
||||
dbb = DiscoveryDB.init(newMemoryDB())
|
||||
d = newProtocol(privKey, dbb, ip, port, port, rng = rng)
|
||||
|
||||
# Same as the on in the fuzz test to have at least one working packet for
|
||||
# the whoareyou-packet.
|
||||
toPrivKey = PrivateKey.fromHex(
|
||||
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
|
||||
toRecord = enr.Record.init(1, toPrivKey,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000), Port(9000))[]
|
||||
toNode = newNode(toRecord)[]
|
||||
|
||||
block: # random packet
|
||||
# No handshake done obviously so a new packet will be a random packet.
|
||||
let
|
||||
reqId = RequestId.init(d.rng[])
|
||||
message = encodeMessage(PingMessage(enrSeq: d.localNode.record.seqNum), reqId)
|
||||
(data, _) = encodePacket(d.rng[], d.codec, toNode.id, toNode.address.get(),
|
||||
message, challenge = nil)
|
||||
|
||||
data.toFile(inputsDir & "random-packet")
|
||||
|
||||
block: # whoareyou packet
|
||||
var authTag: AuthTag
|
||||
var idNonce: IdNonce
|
||||
brHmacDrbgGenerate(d.rng[], authTag)
|
||||
brHmacDrbgGenerate(d.rng[], idNonce)
|
||||
|
||||
let challenge = Whoareyou(authTag: authTag, idNonce: idNonce, recordSeq: 0)
|
||||
var data = @(whoareyouMagic(toNode.id))
|
||||
data.add(rlp.encode(challenge[]))
|
||||
|
||||
data.toFile(inputsDir & "whoareyou-packet")
|
||||
|
||||
discard existsOrCreateDir(inputsDir)
|
||||
generate()
|
|
@ -1,17 +1,12 @@
|
|||
import
|
||||
streams, os, strutils, options,
|
||||
std/[os, strutils, options],
|
||||
stew/shims/net,
|
||||
eth/keys, eth/p2p/discoveryv5/enr
|
||||
eth/keys, eth/p2p/discoveryv5/enr,
|
||||
../fuzzing_helpers
|
||||
|
||||
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||
const inputsDir = sourceDir / "corpus"
|
||||
|
||||
proc toFile(data: seq[byte], fn: string) =
|
||||
var s = newFileStream(fn, fmWrite)
|
||||
for x in data:
|
||||
s.write(x)
|
||||
s.close()
|
||||
|
||||
proc generate() =
|
||||
let
|
||||
rng = newRng()
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import
|
||||
std/streams
|
||||
|
||||
proc toFile*(data: seq[byte], fn: string) =
|
||||
var s = newFileStream(fn, fmWrite)
|
||||
for x in data:
|
||||
s.write(x)
|
||||
s.close()
|
|
@ -0,0 +1,32 @@
|
|||
import
|
||||
testutils/fuzzing, chronicles,
|
||||
eth/rlp
|
||||
|
||||
type
|
||||
TestEnum = enum
|
||||
one = 1
|
||||
two = 2
|
||||
TestObject* = object
|
||||
test1: uint32
|
||||
test2: string
|
||||
|
||||
template testDecode(payload: openarray, T: type) =
|
||||
try:
|
||||
discard rlp.decode(payload, T)
|
||||
except RlpError as e:
|
||||
debug "Decode failed", err = e.msg
|
||||
|
||||
test:
|
||||
testDecode(payload, string)
|
||||
testDecode(payload, uint)
|
||||
testDecode(payload, uint8)
|
||||
testDecode(payload, uint16)
|
||||
testDecode(payload, uint32)
|
||||
testDecode(payload, uint64)
|
||||
testDecode(payload, int)
|
||||
testDecode(payload, bool)
|
||||
testDecode(payload, float64)
|
||||
testDecode(payload, seq[byte])
|
||||
testDecode(payload, (string, int32))
|
||||
testDecode(payload, TestEnum)
|
||||
testDecode(payload, TestObject)
|
Loading…
Reference in New Issue