From 8b59a7a567d50dc996a3b98f223df45f3e6739ef Mon Sep 17 00:00:00 2001 From: joe Date: Fri, 15 Sep 2017 04:28:23 -0400 Subject: Moved CryptoTransport to its hierarchical location. --- src/Network/Tox/Crypto/Transport.hs | 121 ++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/Network/Tox/Crypto/Transport.hs (limited to 'src/Network/Tox/Crypto') diff --git a/src/Network/Tox/Crypto/Transport.hs b/src/Network/Tox/Crypto/Transport.hs new file mode 100644 index 00000000..09f7fda8 --- /dev/null +++ b/src/Network/Tox/Crypto/Transport.hs @@ -0,0 +1,121 @@ +{-# LANGUAGE KindSignatures #-} +module Network.Tox.Crypto.Transport + ( parseNetCrypto + , encodeNetCrypto + -- CryptoTransport + , NetCrypto(..) + , CryptoData(..) + , CryptoMessage(..) + , CryptoPacket(..) + , HandshakeData(..) + , Handshake(..) + ) where + +import Crypto.Tox +import Network.Tox.DHT.Transport (Cookie) + +import Network.Socket +import Data.ByteString +import Data.Word +import Crypto.Hash + +data NetCrypto + = NetHandshake (Handshake Encrypted) + | NetCrypto (CryptoPacket Encrypted) + +parseNetCrypto :: ByteString -> SockAddr -> Either String (NetCrypto, SockAddr) +parseNetCrypto _ _ = Left "TODO: parseNetCrypto" + +encodeNetCrypto :: NetCrypto -> SockAddr -> (ByteString, SockAddr) +encodeNetCrypto _ _ = _todo + +data Handshake (f :: * -> *) = Handshake + { handshakeCookie :: Cookie + , handshakeNonce :: Nonce24 + , hadshakeData :: f HandshakeData + } + +data HandshakeData = HandshakeData + { baseNonce :: Nonce24 + , sessionKey :: PublicKey + , cookieHash :: Digest SHA512 + , otherCookie :: Cookie + } + +data CryptoPacket (f :: * -> *) = CryptoPacket + { pktNonce :: Word16 + , pktData :: f CryptoData + } + +data CryptoData = CryptoData + { -- | [our recvbuffers buffer_start, (highest packet number handled + 1), (big endian)] + bufferStart :: Word32 + -- | [ uint32_t packet number if lossless + -- , sendbuffer buffer_end if lossy , (big endian)] + , bufferEnd :: Word32 + -- | [data] + , bufferData :: CryptoMessage + } + +-- TODO: Flesh this out. +data CryptoMessage -- First byte indicates data + = Padding -- ^ 0 padding (skipped until we hit a non zero (data id) byte) + | PacketRequest -- ^ 1 packet request packet (lossy packet) + | KillPacket -- ^ 2 connection kill packet (lossy packet) + | UnspecifiedPacket -- ^ 3+ unspecified + | MessengerLossless -- ^ 16+ reserved for Messenger usage (lossless packets) + | MessengerLossy -- ^ 192+ reserved for Messenger usage (lossy packets) + | Messenger255 -- ^ 255 reserved for Messenger usage (lossless packet) + + + +-- --> CookieRequest WithoutCookie +-- <-- CookieResponse CookieAddress +-- --> Handshake CookieAddress +-- <-- Handshake CookieAddress + +-- Handshake packet: +-- [uint8_t 26] (0x1a) +-- [Cookie] +-- [nonce (24 bytes)] +-- [Encrypted message containing: +-- [24 bytes base nonce] +-- [session public key of the peer (32 bytes)] +-- [sha512 hash of the entire Cookie sitting outside the encrypted part] +-- [Other Cookie (used by the other to respond to the handshake packet)] +-- ] + +-- cookie response packet (161 bytes): +-- +-- [uint8_t 25] +-- [Random nonce (24 bytes)] +-- [Encrypted message containing: +-- [Cookie] +-- [uint64_t echo id (that was sent in the request)] +-- ] +-- +-- Encrypted message is encrypted with the exact same symmetric key as the +-- cookie request packet it responds to but with a different nonce. +-- (Encrypted message is encrypted with reqesters's DHT private key, +-- responders's DHT public key and the nonce.) +-- +-- Since we don't receive the public key, we will need to lookup the key by +-- the SockAddr... I don't understand why the CookieResponse message is +-- special this way. TODO: implement a multimap (SockAddr -> SharedSecret) +-- and wrap cookie queries with store/delete. TODO: Should the entire +-- SharedScret cache be keyed on only SockAddr ? Perhaps the secret cache +-- should be (NodeId -> Secret) and the cookie-request map should be +-- (SockAddr -> NodeId) + +-- Encrypted packets: +-- +-- Length Contents +-- :---------:-------------------------------------------------------------- +-- `1` `uint8_t` (0x1b) +-- `2` `uint16_t` The last 2 bytes of the nonce used to encrypt this +-- variable  Payload +-- +-- The payload is encrypted with the session key and 'base nonce' set by the +-- receiver in their handshake + packet number (starting at 0, big endian math). + + -- cgit v1.2.3