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. --- CryptoTransport.hs | 121 ------------------------------------ Tox.hs | 2 +- ToxTransport.hs | 2 +- src/Network/Tox/Crypto/Transport.hs | 121 ++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 123 deletions(-) delete mode 100644 CryptoTransport.hs create mode 100644 src/Network/Tox/Crypto/Transport.hs diff --git a/CryptoTransport.hs b/CryptoTransport.hs deleted file mode 100644 index 9d4b3d84..00000000 --- a/CryptoTransport.hs +++ /dev/null @@ -1,121 +0,0 @@ -{-# LANGUAGE KindSignatures #-} -module CryptoTransport - ( 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). - - diff --git a/Tox.hs b/Tox.hs index 75cd9799..6dce9757 100644 --- a/Tox.hs +++ b/Tox.hs @@ -90,7 +90,7 @@ import qualified Network.Tox.DHT.Transport as DHT import qualified Network.Tox.DHT.Handlers as DHT import qualified Network.Tox.Onion.Transport as Onion import qualified Network.Tox.Onion.Handlers as Onion -import CryptoTransport (NetCrypto) +import Network.Tox.Crypto.Transport (NetCrypto) import Text.XXD newCrypto :: IO TransportCrypto diff --git a/ToxTransport.hs b/ToxTransport.hs index 434ca281..239000b0 100644 --- a/ToxTransport.hs +++ b/ToxTransport.hs @@ -12,7 +12,7 @@ import Network.QueryResponse import Crypto.Tox import Network.Tox.DHT.Transport import Network.Tox.Onion.Transport -import CryptoTransport +import Network.Tox.Crypto.Transport import Network.Socket 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