proxy connection through secio
This commit is contained in:
parent
2d00f6a6db
commit
ea142f0e6d
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
## Nim-LibP2P
|
## Nim-LibP2P
|
||||||
## Copyright (c) 2018 Status Research & Development GmbH
|
## Copyright (c) 2018 Status Research & Development GmbH
|
||||||
## Licensed under either of
|
## Licensed under either of
|
||||||
|
@ -13,8 +14,8 @@ import secure,
|
||||||
../../crypto/crypto,
|
../../crypto/crypto,
|
||||||
../../crypto/ecnist,
|
../../crypto/ecnist,
|
||||||
../../protobuf/minprotobuf,
|
../../protobuf/minprotobuf,
|
||||||
../../peer
|
../../peer,
|
||||||
|
../../stream/bufferstream
|
||||||
export hmac, sha2, sha, hash, rijndael, bcmode
|
export hmac, sha2, sha, hash, rijndael, bcmode
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
|
@ -59,7 +60,8 @@ type
|
||||||
of SecureMacType.Sha1:
|
of SecureMacType.Sha1:
|
||||||
ctxsha1: HMAC[sha1]
|
ctxsha1: HMAC[sha1]
|
||||||
|
|
||||||
SecureConnection* = ref object of BufferStream
|
SecureConnection* = ref object of Connection
|
||||||
|
conn*: Connection
|
||||||
writerMac: SecureMac
|
writerMac: SecureMac
|
||||||
readerMac: SecureMac
|
readerMac: SecureMac
|
||||||
writerCoder: SecureCipher
|
writerCoder: SecureCipher
|
||||||
|
@ -212,7 +214,7 @@ proc writeMessage*(sconn: SecureConnection, message: seq[byte]) {.async.} =
|
||||||
msg[3] = byte(length and 0xFF)
|
msg[3] = byte(length and 0xFF)
|
||||||
trace "Writing message", message = toHex(msg)
|
trace "Writing message", message = toHex(msg)
|
||||||
try:
|
try:
|
||||||
await sconn.pushTo(msg)
|
await sconn.conn.write(msg)
|
||||||
except AsyncStreamWriteError:
|
except AsyncStreamWriteError:
|
||||||
debug "Could not write to connection"
|
debug "Could not write to connection"
|
||||||
|
|
||||||
|
@ -265,7 +267,7 @@ proc transactMessage(conn: Connection,
|
||||||
except AsyncStreamWriteError:
|
except AsyncStreamWriteError:
|
||||||
trace "Could not write to connection", conn = conn
|
trace "Could not write to connection", conn = conn
|
||||||
|
|
||||||
proc handshake*(p: Secio, conn: Connection) {.async.} =
|
proc handshake*(s: Secio, conn: Connection): Future[SecureConnection] {.async.} =
|
||||||
var
|
var
|
||||||
localNonce: array[SecioNonceSize, byte]
|
localNonce: array[SecioNonceSize, byte]
|
||||||
remoteNonce: seq[byte]
|
remoteNonce: seq[byte]
|
||||||
|
@ -281,7 +283,7 @@ proc handshake*(p: Secio, conn: Connection) {.async.} =
|
||||||
remotePeerId: PeerID
|
remotePeerId: PeerID
|
||||||
localPeerId: PeerID
|
localPeerId: PeerID
|
||||||
ekey: PrivateKey
|
ekey: PrivateKey
|
||||||
localBytesPubkey = p.localPublicKey.getBytes()
|
localBytesPubkey = s.localPublicKey.getBytes()
|
||||||
|
|
||||||
if randomBytes(localNonce) != SecioNonceSize:
|
if randomBytes(localNonce) != SecioNonceSize:
|
||||||
raise newException(CatchableError, "Could not generate random data")
|
raise newException(CatchableError, "Could not generate random data")
|
||||||
|
@ -289,7 +291,7 @@ proc handshake*(p: Secio, conn: Connection) {.async.} =
|
||||||
var request = createProposal(localNonce, localBytesPubkey, SecioExchanges,
|
var request = createProposal(localNonce, localBytesPubkey, SecioExchanges,
|
||||||
SecioCiphers, SecioHashes)
|
SecioCiphers, SecioHashes)
|
||||||
|
|
||||||
localPeerId = PeerID.init(p.localPublicKey)
|
localPeerId = PeerID.init(s.localPublicKey)
|
||||||
|
|
||||||
debug "Local proposal", schemes = SecioExchanges, ciphers = SecioCiphers,
|
debug "Local proposal", schemes = SecioExchanges, ciphers = SecioCiphers,
|
||||||
hashes = SecioHashes,
|
hashes = SecioHashes,
|
||||||
|
@ -336,7 +338,7 @@ proc handshake*(p: Secio, conn: Connection) {.async.} =
|
||||||
# We need EC public key in raw binary form
|
# We need EC public key in raw binary form
|
||||||
var epubkey = ekeypair.pubkey.eckey.getRawBytes()
|
var epubkey = ekeypair.pubkey.eckey.getRawBytes()
|
||||||
var localCorpus = request[4..^1] & answer & epubkey
|
var localCorpus = request[4..^1] & answer & epubkey
|
||||||
var signature = p.localPrivateKey.sign(localCorpus)
|
var signature = s.localPrivateKey.sign(localCorpus)
|
||||||
|
|
||||||
var localExchange = createExchange(epubkey, signature.getBytes())
|
var localExchange = createExchange(epubkey, signature.getBytes())
|
||||||
|
|
||||||
|
@ -387,25 +389,37 @@ proc handshake*(p: Secio, conn: Connection) {.async.} =
|
||||||
|
|
||||||
# Perform Nonce exchange over encrypted channel.
|
# Perform Nonce exchange over encrypted channel.
|
||||||
|
|
||||||
var sconn = newSecureConnection(conn, hash, cipher, keys, order)
|
result = newSecureConnection(conn, hash, cipher, keys, order)
|
||||||
await sconn.writeMessage(remoteNonce)
|
await result.writeMessage(remoteNonce)
|
||||||
var res = await sconn.readMessage()
|
var res = await result.readMessage()
|
||||||
|
|
||||||
if res != @localNonce:
|
if res != @localNonce:
|
||||||
debug "Nonce verification failed", receivedNonce = toHex(res),
|
debug "Nonce verification failed", receivedNonce = toHex(res),
|
||||||
localNonce = toHex(localNonce)
|
localNonce = toHex(localNonce)
|
||||||
|
raise newException(CatchableError, "Nonce verification failed")
|
||||||
else:
|
else:
|
||||||
debug "Secure handshake succeeded"
|
debug "Secure handshake succeeded"
|
||||||
|
|
||||||
method init(p: Secio) {.gcsafe.} =
|
proc handleConn(s: Secio, conn: Connection): Future[Connection] {.async.} =
|
||||||
|
var sconn = await s.handshake(conn)
|
||||||
|
proc writeHandler(data: seq[byte]) {.async, gcsafe.} =
|
||||||
|
await sconn.writeMessage(data)
|
||||||
|
|
||||||
|
var stream = newBufferStream(writeHandler)
|
||||||
|
result = newConnection(stream)
|
||||||
|
while not conn.closed:
|
||||||
|
let msg = await sconn.readMessage()
|
||||||
|
await stream.pushTo(msg)
|
||||||
|
|
||||||
|
method init(s: Secio) {.gcsafe.} =
|
||||||
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
||||||
echo "HERE"
|
asyncCheck s.handleConn(conn)
|
||||||
|
|
||||||
p.codec = SecioCodec
|
s.codec = SecioCodec
|
||||||
p.handler = handle
|
s.handler = handle
|
||||||
|
|
||||||
method secure*(p: Secio, conn: Connection): Future[Connection] {.async, gcsafe.} =
|
method secure*(s: Secio, conn: Connection): Future[Connection] {.gcsafe.} =
|
||||||
await p.handshake(conn)
|
result = s.handleConn(conn)
|
||||||
|
|
||||||
proc newSecio*(localPrivateKey: PrivateKey): Secio =
|
proc newSecio*(localPrivateKey: PrivateKey): Secio =
|
||||||
new result
|
new result
|
||||||
|
|
Loading…
Reference in New Issue