From 53fc4cce416b19b94002712e37bc976787fc168b Mon Sep 17 00:00:00 2001 From: cheatfate Date: Wed, 5 Dec 2018 02:30:50 +0200 Subject: [PATCH] Fix MultiAddress Onion and P2P address validation and encoding/decoding. Enabled Onion/P2P tests. Add nimcrypto dependency to nimble file. --- libp2p.nimble | 1 + libp2p/multiaddress.nim | 55 ++++++++++++++++++++++++++++---------- libp2p/multihash.nim | 9 +++++++ tests/testmultiaddress.nim | 34 +++++++++++------------ 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/libp2p.nimble b/libp2p.nimble index 444f34c6c..21f75a2da 100644 --- a/libp2p.nimble +++ b/libp2p.nimble @@ -8,6 +8,7 @@ license = "MIT" skipDirs = @["tests", "examples", "Nim"] requires "nim > 0.18.0", + "nimcrypto", "https://github.com/status-im/nim-asyncdispatch2" task test, "Runs the test suite": diff --git a/libp2p/multiaddress.nim b/libp2p/multiaddress.nim index f51f38a1b..3020ee612 100644 --- a/libp2p/multiaddress.nim +++ b/libp2p/multiaddress.nim @@ -9,7 +9,7 @@ ## This module implements MultiAddress. import tables, strutils, net -import transcoder, base58, vbuffer +import multihash, transcoder, base58, base32, vbuffer {.deadCodeElim:on.} @@ -124,7 +124,7 @@ proc portStB(s: string, vb: var VBuffer): bool = var port: array[2, byte] try: var nport = parseInt(s) - if nport < 65536: + if (nport >= 0) and (nport < 65536): port[0] = cast[byte]((nport shr 8) and 0xFF) port[1] = cast[byte](nport and 0xFF) vb.writeArray(port) @@ -150,8 +150,10 @@ proc p2pStB(s: string, vb: var VBuffer): bool = ## P2P address stringToBuffer() implementation. try: var data = Base58.decode(s) - vb.writeSeq(data) - result = true + var mh: MultiHash + if MultiHash.decode(data, mh) >= 0: + vb.writeSeq(data) + result = true except: discard @@ -159,27 +161,52 @@ proc p2pBtS(vb: var VBuffer, s: var string): bool = ## P2P address bufferToString() implementation. var address = newSeq[byte]() if vb.readSeq(address) > 0: - s = Base58.encode(address) - result = true + var mh: MultiHash + if MultiHash.decode(address, mh) >= 0: + s = Base58.encode(address) + result = true proc p2pVB(vb: var VBuffer): bool = ## P2P address validateBuffer() implementation. - ## TODO (multihash required) var address = newSeq[byte]() if vb.readSeq(address) > 0: - result = true + var mh: MultiHash + if MultiHash.decode(address, mh) >= 0: + result = true proc onionStB(s: string, vb: var VBuffer): bool = - # TODO (base32, multihash required) - discard + try: + var parts = s.split(':') + if len(parts) != 2: + return false + if len(parts[0]) != 16: + return false + var address = Base32Lower.decode(parts[0].toLowerAscii()) + var nport = parseInt(parts[1]) + if (nport > 0 and nport < 65536) and len(address) == 10: + address.setLen(12) + address[10] = cast[byte]((nport shr 8) and 0xFF) + address[11] = cast[byte](nport and 0xFF) + vb.writeArray(address) + result = true + except: + discard proc onionBtS(vb: var VBuffer, s: var string): bool = - # TODO (base32, multihash required) - discard + ## ONION address bufferToString() implementation. + var buf: array[12, byte] + if vb.readArray(buf) == 12: + var nport = (cast[uint16](buf[10]) shl 8) or cast[uint16](buf[11]) + s = Base32Lower.encode(buf.toOpenArray(0, 9)) + s.add(":") + s.add($nport) + result = true proc onionVB(vb: var VBuffer): bool = - # TODO (base32, multihash required) - discard + ## ONION address validateBuffer() implementation. + var buf: array[12, byte] + if vb.readArray(buf) == 12: + result = true proc unixStB(s: string, vb: var VBuffer): bool = ## Unix socket name stringToBuffer() implementation. diff --git a/libp2p/multihash.nim b/libp2p/multihash.nim index 078abc050..13d67dcd1 100644 --- a/libp2p/multihash.nim +++ b/libp2p/multihash.nim @@ -462,6 +462,12 @@ proc init*(mhtype: typedesc[MultiHash], data: string): MultiHash {.inline.} = if MultiHash.decode(fromHex(data), result) == -1: raise newException(MultihashError, "Incorrect MultiHash binary format") +proc init58*(mhtype: typedesc[MultiHash], + data: string): MultiHash {.inline.} = + ## Create MultiHash from BASE58 encoded string representation ``data``. + if MultiHash.decode(Base58.decode(data), result) == -1: + raise newException(MultihashError, "Incorrect MultiHash binary format") + proc cmp(a: openarray[byte], b: openarray[byte]): bool {.inline.} = if len(a) != len(b): return false @@ -513,3 +519,6 @@ proc `$`*(value: MultiHash): string = let digest = toHex(value.data.buffer.toOpenArray(value.dpos, value.dpos + value.size - 1)) result = multihashName(value.code) & "/" & digest + +when isMainModule: + echo MultiHash.init58("QmPGqitiRv1TPuCNtcwsMNRPEhx9SZP5qANPNcQBA53BgM") \ No newline at end of file diff --git a/tests/testmultiaddress.nim b/tests/testmultiaddress.nim index 0916d9c0a..0f6611b82 100644 --- a/tests/testmultiaddress.nim +++ b/tests/testmultiaddress.nim @@ -12,8 +12,8 @@ const "/ip6zone/x%y/ip6/fe80::1", "/ip6zone/x%y/ip6/::", "/ip6zone/x/ip6/fe80::1/udp/1234/quic", - # "/onion/timaq4ygg2iegci7:1234", - # "/onion/timaq4ygg2iegci7:80/http", + "/onion/timaq4ygg2iegci7:1234", + "/onion/timaq4ygg2iegci7:80/http", "/udp/0", "/tcp/0", "/sctp/0", @@ -61,12 +61,12 @@ const "/udp/65536", "/tcp/65536", "/quic/65536", - # "/onion/9imaq4ygg2iegci7:80", # TODO: Requires ONION validate - # "/onion/aaimaq4ygg2iegci7:80", - # "/onion/timaq4ygg2iegci7:0", - # "/onion/timaq4ygg2iegci7:-1", - # "/onion/timaq4ygg2iegci7", - # "/onion/timaq4ygg2iegci@:666", + "/onion/9imaq4ygg2iegci7:80", + "/onion/aaimaq4ygg2iegci7:80", + "/onion/timaq4ygg2iegci7:0", + "/onion/timaq4ygg2iegci7:-1", + "/onion/timaq4ygg2iegci7", + "/onion/timaq4ygg2iegci@:666", "/udp/1234/sctp", "/udp/1234/udt/1234", "/udp/1234/utp/1234", @@ -76,9 +76,9 @@ const "/ip4/127.0.0.1/tcp", "/ip4/127.0.0.1/quic/1234", "/ip4/127.0.0.1/ipfs", - # "/ip4/127.0.0.1/ipfs/tcp", # TODO: Requires P2P/IPFS validate + "/ip4/127.0.0.1/ipfs/tcp", "/ip4/127.0.0.1/p2p", - # "/ip4/127.0.0.1/p2p/tcp", # TODO: Requires P2P/IPFS validate + "/ip4/127.0.0.1/p2p/tcp", "/unix" ] @@ -152,12 +152,12 @@ const "/sctp", "/udp/65536", "/tcp/65536", - # "/onion/9imaq4ygg2iegci7:80", # TODO: Requires ONION validate - # "/onion/aaimaq4ygg2iegci7:80", - # "/onion/timaq4ygg2iegci7:0", - # "/onion/timaq4ygg2iegci7:-1", - # "/onion/timaq4ygg2iegci7", - # "/onion/timaq4ygg2iegci@:666", + "/onion/9imaq4ygg2iegci7:80", + "/onion/aaimaq4ygg2iegci7:80", + "/onion/timaq4ygg2iegci7:0", + "/onion/timaq4ygg2iegci7:-1", + "/onion/timaq4ygg2iegci7", + "/onion/timaq4ygg2iegci@:666", "/udp/1234/sctp", "/udp/1234/udt/1234", "/udp/1234/utp/1234", @@ -166,7 +166,7 @@ const "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa", "/ip4/127.0.0.1/tcp", "/ip4/127.0.0.1/ipfs", - # "/ip4/127.0.0.1/ipfs/tcp", # TODO: Requires P2P/IPFS validate + "/ip4/127.0.0.1/ipfs/tcp", "/p2p-circuit/50" ]