nim-libp2p/libp2p/protocols/secure/secio.nim

92 lines
2.9 KiB
Nim
Raw Normal View History

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