From 538edb705c9f3ffed25603f96ed118f9c41494aa Mon Sep 17 00:00:00 2001 From: joe Date: Wed, 30 Aug 2017 23:39:29 -0400 Subject: NetCrypto transport for remaining miscelaneous tox packets. --- ToxTransport.hs | 116 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 18 deletions(-) diff --git a/ToxTransport.hs b/ToxTransport.hs index a927e55a..855b0c7e 100644 --- a/ToxTransport.hs +++ b/ToxTransport.hs @@ -1,27 +1,40 @@ -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE DataKinds,KindSignatures #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeOperators #-} -{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE TupleSections #-} -module ToxTransport where +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE TypeOperators #-} +module ToxTransport + ( toxTransport + , TransportCrypto + , UDPTransport + , DirectMessage + , Encrypted8 + , OnionToOwner + , OnionMessage + , NetCrypto + ) where import Network.QueryResponse +import ToxAddress as Tox hiding (OnionToOwner, ReturnPath) import ToxCrypto -import ToxAddress as Tox hiding (ReturnPath,OnionToOwner) import ToxPacket +import Control.Applicative +import Control.Arrow import Control.Concurrent.STM +import Crypto.Hash +import Crypto.Hash.Algorithms import qualified Data.ByteString as B ;import Data.ByteString (ByteString) +import Data.Serialize as S (Get, Put, Serialize, decode, get, put, + runGet) +import Data.Typeable import Data.Word -import Network.Socket -import Data.Serialize as S (decode, Serialize, get, put, Get, Put, runGet) import GHC.TypeLits -import Data.Typeable -import Control.Applicative -import Control.Arrow +import Network.Socket newtype SymmetricKey = SymmetricKey ByteString @@ -65,11 +78,12 @@ toxTransport :: -> UDPTransport -> IO ( Transport String NodeInfo (DirectMessage Encrypted8) , Transport String OnionToOwner (OnionMessage Encrypted) - , Transport String SockAddr ByteString ) + , Transport String SockAddr NetCrypto ) toxTransport crypto udp = do (dht,udp1) <- partitionTransport parseDHTAddr encodeDHTAddr id $ handleOnion crypto udp (onion,udp2) <- partitionTransport parseOnionAddr encodeOnionAddr id udp1 - return (dht,onion,udp2) + let netcrypto = layerTransport parseNetCrypto encodeNetCrypto udp2 + return (dht,onion,netcrypto) type HandleHi a = Maybe (Either String (Message, Tox.Address)) -> IO a @@ -180,8 +194,62 @@ encodeOnionAddr :: (OnionMessage Encrypted,OnionToOwner) -> (ByteString, SockAdd encodeOnionAddr = _todo -data CookieAddress = WithoutCookie NodeInfo - | CookieAddress Cookie SockAddr +-- data CookieAddress = WithoutCookie NodeInfo | CookieAddress Cookie SockAddr + +data NetCrypto + = NetHandshake (Handshake Encrypted) + | NetCrypto (CryptoPacket Encrypted) + +parseNetCrypto :: ByteString -> SockAddr -> Either String (NetCrypto, SockAddr) +parseNetCrypto = _todo + +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) @@ -216,8 +284,20 @@ data CookieAddress = WithoutCookie NodeInfo -- 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). + + -- Byte value Packet Kind Return address --- :----------- :-------------------- +-- :----------- :-------------------- -- `0x00` Ping Request DHTNode -- `0x01` Ping Response - -- `0x02` Nodes Request DHTNode -- cgit v1.2.3