2019-09-06 06:51:46 +00:00
|
|
|
## Nim-LibP2P
|
|
|
|
## Copyright (c) 2018 Status Research & Development GmbH
|
|
|
|
## Licensed under either of
|
|
|
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
|
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
|
|
## at your option.
|
|
|
|
## This file may not be copied, modified, or distributed except according to
|
|
|
|
## those terms.
|
|
|
|
|
2019-09-10 02:13:15 +00:00
|
|
|
import chronos, chronicles, nimcrypto/sysrand
|
|
|
|
import secure, ../../connection, ../../crypto/crypto
|
2019-09-06 06:51:46 +00:00
|
|
|
|
2019-09-10 02:13:15 +00:00
|
|
|
logScope:
|
|
|
|
topic = "secio"
|
|
|
|
|
|
|
|
const
|
|
|
|
SecioCodec* = "/secio/1.0.0"
|
|
|
|
SecioMaxMessageSize = 8 * 1024 * 1024 ## 8mb
|
|
|
|
SecioNonceSize = 16
|
|
|
|
SecioExchanges = "P-256,P-384,P-521"
|
|
|
|
SecioCiphers = "AES-256,AES-128"
|
|
|
|
SecioHashes = "SHA-256,SHA-512"
|
2019-09-06 06:51:46 +00:00
|
|
|
|
|
|
|
type
|
2019-09-09 17:33:51 +00:00
|
|
|
Secio = ref object of Secure
|
2019-09-10 02:13:15 +00:00
|
|
|
localPublicKey: PublicKey
|
|
|
|
|
|
|
|
proc transactMessage(conn: Connection,
|
|
|
|
msg: seq[byte]): Future[seq[byte]] {.async.} =
|
|
|
|
var buf = newSeq[byte](4)
|
|
|
|
try:
|
|
|
|
debug "Sending proposal", message = toHex(msg)
|
|
|
|
await conn.write(msg)
|
|
|
|
await conn.readExactly(addr buf[0], 4)
|
|
|
|
let length = (int(buf[0]) shl 24) or (int(buf[1]) shl 16) or
|
|
|
|
(int(buf[2]) shl 8) or (int(buf[3]))
|
|
|
|
debug "Recieved message header", header = toHex(buf), length = length
|
|
|
|
if length <= SecioMaxMessageSize:
|
|
|
|
buf.setLen(length)
|
|
|
|
await conn.readExactly(addr buf[0], length)
|
|
|
|
debug "Received message body", conn = conn, length = length
|
|
|
|
result = buf
|
|
|
|
else:
|
|
|
|
debug "Received size of message exceed limits", conn = conn,
|
|
|
|
length = length
|
|
|
|
except AsyncStreamIncompleteError:
|
|
|
|
debug "Connection dropped while reading", conn = conn
|
|
|
|
except AsyncStreamReadError:
|
|
|
|
debug "Error reading from connection", conn = conn
|
|
|
|
except AsyncStreamWriteError:
|
|
|
|
debug "Could not write to connection", conn = conn
|
|
|
|
|
|
|
|
proc handshake*(p: Secio, conn: Connection) {.async.} =
|
|
|
|
var nonce: array[SecioNonceSize, byte]
|
|
|
|
var pk = p.localPublicKey.getBytes()
|
|
|
|
echo toHex(pk)
|
|
|
|
if randomBytes(nonce) != SecioNonceSize:
|
|
|
|
raise newException(CatchableError, "Could not generate random data")
|
|
|
|
|
|
|
|
debug "Local proposal", schemes = SecioExchanges, ciphers = SecioCiphers,
|
|
|
|
hashes = SecioHashes, nonce = toHex(nonce),
|
|
|
|
pubkey = toHex(pk)
|
|
|
|
|
|
|
|
echo "local proposal"
|
2019-09-06 06:51:46 +00:00
|
|
|
|
2019-09-10 02:13:15 +00:00
|
|
|
var answer = await transactMessage(conn,
|
|
|
|
createProposal(nonce, pk, SecioExchanges, SecioCiphers, SecioHashes)
|
|
|
|
)
|
|
|
|
|
|
|
|
echo toHex(answer)
|
|
|
|
|
|
|
|
if len(answer) == 0:
|
|
|
|
debug "Proposal exchange failed", conn = conn
|
|
|
|
return
|
2019-09-06 06:51:46 +00:00
|
|
|
|
2019-09-09 17:33:51 +00:00
|
|
|
method init(p: Secio) {.gcsafe.} =
|
|
|
|
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
2019-09-10 02:13:15 +00:00
|
|
|
echo "HERE"
|
2019-09-06 06:51:46 +00:00
|
|
|
|
2019-09-09 17:33:51 +00:00
|
|
|
p.codec = SecioCodec
|
2019-09-06 06:51:46 +00:00
|
|
|
p.handler = handle
|
|
|
|
|
2019-09-10 02:13:15 +00:00
|
|
|
method secure*(p: Secio, conn: Connection): Future[Connection] {.async, gcsafe.} =
|
|
|
|
echo "handshaking"
|
|
|
|
await p.handshake(conn)
|
|
|
|
|
|
|
|
proc newSecio*(localPublicKey: PublicKey): Secio =
|
2019-09-06 06:51:46 +00:00
|
|
|
new result
|
2019-09-10 02:13:15 +00:00
|
|
|
result.localPublicKey = localPublicKey
|
2019-09-06 06:51:46 +00:00
|
|
|
result.init()
|
2019-09-09 17:33:51 +00:00
|
|
|
|