Fix MultiAddress Onion and P2P address validation and encoding/decoding.

Enabled Onion/P2P tests.
Add nimcrypto dependency to nimble file.
This commit is contained in:
cheatfate 2018-12-05 02:30:50 +02:00
parent 2e1b5b0fbf
commit 53fc4cce41
4 changed files with 68 additions and 31 deletions

View File

@ -8,6 +8,7 @@ license = "MIT"
skipDirs = @["tests", "examples", "Nim"] skipDirs = @["tests", "examples", "Nim"]
requires "nim > 0.18.0", requires "nim > 0.18.0",
"nimcrypto",
"https://github.com/status-im/nim-asyncdispatch2" "https://github.com/status-im/nim-asyncdispatch2"
task test, "Runs the test suite": task test, "Runs the test suite":

View File

@ -9,7 +9,7 @@
## This module implements MultiAddress. ## This module implements MultiAddress.
import tables, strutils, net import tables, strutils, net
import transcoder, base58, vbuffer import multihash, transcoder, base58, base32, vbuffer
{.deadCodeElim:on.} {.deadCodeElim:on.}
@ -124,7 +124,7 @@ proc portStB(s: string, vb: var VBuffer): bool =
var port: array[2, byte] var port: array[2, byte]
try: try:
var nport = parseInt(s) var nport = parseInt(s)
if nport < 65536: if (nport >= 0) and (nport < 65536):
port[0] = cast[byte]((nport shr 8) and 0xFF) port[0] = cast[byte]((nport shr 8) and 0xFF)
port[1] = cast[byte](nport and 0xFF) port[1] = cast[byte](nport and 0xFF)
vb.writeArray(port) vb.writeArray(port)
@ -150,6 +150,8 @@ proc p2pStB(s: string, vb: var VBuffer): bool =
## P2P address stringToBuffer() implementation. ## P2P address stringToBuffer() implementation.
try: try:
var data = Base58.decode(s) var data = Base58.decode(s)
var mh: MultiHash
if MultiHash.decode(data, mh) >= 0:
vb.writeSeq(data) vb.writeSeq(data)
result = true result = true
except: except:
@ -159,27 +161,52 @@ proc p2pBtS(vb: var VBuffer, s: var string): bool =
## P2P address bufferToString() implementation. ## P2P address bufferToString() implementation.
var address = newSeq[byte]() var address = newSeq[byte]()
if vb.readSeq(address) > 0: if vb.readSeq(address) > 0:
var mh: MultiHash
if MultiHash.decode(address, mh) >= 0:
s = Base58.encode(address) s = Base58.encode(address)
result = true result = true
proc p2pVB(vb: var VBuffer): bool = proc p2pVB(vb: var VBuffer): bool =
## P2P address validateBuffer() implementation. ## P2P address validateBuffer() implementation.
## TODO (multihash required)
var address = newSeq[byte]() var address = newSeq[byte]()
if vb.readSeq(address) > 0: if vb.readSeq(address) > 0:
var mh: MultiHash
if MultiHash.decode(address, mh) >= 0:
result = true result = true
proc onionStB(s: string, vb: var VBuffer): bool = proc onionStB(s: string, vb: var VBuffer): bool =
# TODO (base32, multihash required) 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 discard
proc onionBtS(vb: var VBuffer, s: var string): bool = proc onionBtS(vb: var VBuffer, s: var string): bool =
# TODO (base32, multihash required) ## ONION address bufferToString() implementation.
discard 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 = proc onionVB(vb: var VBuffer): bool =
# TODO (base32, multihash required) ## ONION address validateBuffer() implementation.
discard var buf: array[12, byte]
if vb.readArray(buf) == 12:
result = true
proc unixStB(s: string, vb: var VBuffer): bool = proc unixStB(s: string, vb: var VBuffer): bool =
## Unix socket name stringToBuffer() implementation. ## Unix socket name stringToBuffer() implementation.

View File

@ -462,6 +462,12 @@ proc init*(mhtype: typedesc[MultiHash], data: string): MultiHash {.inline.} =
if MultiHash.decode(fromHex(data), result) == -1: if MultiHash.decode(fromHex(data), result) == -1:
raise newException(MultihashError, "Incorrect MultiHash binary format") 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.} = proc cmp(a: openarray[byte], b: openarray[byte]): bool {.inline.} =
if len(a) != len(b): if len(a) != len(b):
return false return false
@ -513,3 +519,6 @@ proc `$`*(value: MultiHash): string =
let digest = toHex(value.data.buffer.toOpenArray(value.dpos, let digest = toHex(value.data.buffer.toOpenArray(value.dpos,
value.dpos + value.size - 1)) value.dpos + value.size - 1))
result = multihashName(value.code) & "/" & digest result = multihashName(value.code) & "/" & digest
when isMainModule:
echo MultiHash.init58("QmPGqitiRv1TPuCNtcwsMNRPEhx9SZP5qANPNcQBA53BgM")

View File

@ -12,8 +12,8 @@ const
"/ip6zone/x%y/ip6/fe80::1", "/ip6zone/x%y/ip6/fe80::1",
"/ip6zone/x%y/ip6/::", "/ip6zone/x%y/ip6/::",
"/ip6zone/x/ip6/fe80::1/udp/1234/quic", "/ip6zone/x/ip6/fe80::1/udp/1234/quic",
# "/onion/timaq4ygg2iegci7:1234", "/onion/timaq4ygg2iegci7:1234",
# "/onion/timaq4ygg2iegci7:80/http", "/onion/timaq4ygg2iegci7:80/http",
"/udp/0", "/udp/0",
"/tcp/0", "/tcp/0",
"/sctp/0", "/sctp/0",
@ -61,12 +61,12 @@ const
"/udp/65536", "/udp/65536",
"/tcp/65536", "/tcp/65536",
"/quic/65536", "/quic/65536",
# "/onion/9imaq4ygg2iegci7:80", # TODO: Requires ONION validate "/onion/9imaq4ygg2iegci7:80",
# "/onion/aaimaq4ygg2iegci7:80", "/onion/aaimaq4ygg2iegci7:80",
# "/onion/timaq4ygg2iegci7:0", "/onion/timaq4ygg2iegci7:0",
# "/onion/timaq4ygg2iegci7:-1", "/onion/timaq4ygg2iegci7:-1",
# "/onion/timaq4ygg2iegci7", "/onion/timaq4ygg2iegci7",
# "/onion/timaq4ygg2iegci@:666", "/onion/timaq4ygg2iegci@:666",
"/udp/1234/sctp", "/udp/1234/sctp",
"/udp/1234/udt/1234", "/udp/1234/udt/1234",
"/udp/1234/utp/1234", "/udp/1234/utp/1234",
@ -76,9 +76,9 @@ const
"/ip4/127.0.0.1/tcp", "/ip4/127.0.0.1/tcp",
"/ip4/127.0.0.1/quic/1234", "/ip4/127.0.0.1/quic/1234",
"/ip4/127.0.0.1/ipfs", "/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",
# "/ip4/127.0.0.1/p2p/tcp", # TODO: Requires P2P/IPFS validate "/ip4/127.0.0.1/p2p/tcp",
"/unix" "/unix"
] ]
@ -152,12 +152,12 @@ const
"/sctp", "/sctp",
"/udp/65536", "/udp/65536",
"/tcp/65536", "/tcp/65536",
# "/onion/9imaq4ygg2iegci7:80", # TODO: Requires ONION validate "/onion/9imaq4ygg2iegci7:80",
# "/onion/aaimaq4ygg2iegci7:80", "/onion/aaimaq4ygg2iegci7:80",
# "/onion/timaq4ygg2iegci7:0", "/onion/timaq4ygg2iegci7:0",
# "/onion/timaq4ygg2iegci7:-1", "/onion/timaq4ygg2iegci7:-1",
# "/onion/timaq4ygg2iegci7", "/onion/timaq4ygg2iegci7",
# "/onion/timaq4ygg2iegci@:666", "/onion/timaq4ygg2iegci@:666",
"/udp/1234/sctp", "/udp/1234/sctp",
"/udp/1234/udt/1234", "/udp/1234/udt/1234",
"/udp/1234/utp/1234", "/udp/1234/utp/1234",
@ -166,7 +166,7 @@ const
"/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa", "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa",
"/ip4/127.0.0.1/tcp", "/ip4/127.0.0.1/tcp",
"/ip4/127.0.0.1/ipfs", "/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" "/p2p-circuit/50"
] ]