summaryrefslogtreecommitdiff
path: root/ToxMessage.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-08-11 01:08:30 -0400
committerjoe <joe@jerkface.net>2017-08-11 01:08:30 -0400
commitcd5091c4a3ab1c05b48ff3ad2fea666d77b8e39c (patch)
tree45bd1073d40830e6311bbaf8021899fec236abbc /ToxMessage.hs
parent85a004ac92cac382a8c2824ca6b584764ab7782d (diff)
Reply to Announce with AnnounceResponse.
Diffstat (limited to 'ToxMessage.hs')
-rw-r--r--ToxMessage.hs124
1 files changed, 105 insertions, 19 deletions
diff --git a/ToxMessage.hs b/ToxMessage.hs
index 9ea57d27..06026b49 100644
--- a/ToxMessage.hs
+++ b/ToxMessage.hs
@@ -1,9 +1,15 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving #-} 2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE DeriveFunctor, DeriveTraversable,DeriveDataTypeable #-} 3{-# LANGUAGE DeriveFunctor, DeriveTraversable,DeriveDataTypeable #-}
3{-# LANGUAGE GADTs #-} 4{-# LANGUAGE GADTs #-}
4{-# LANGUAGE FlexibleInstances #-} 5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE TypeApplications #-}
8{-# LANGUAGE ExistentialQuantification #-}
9{-# LANGUAGE DataKinds, KindSignatures #-}
5module ToxMessage where 10module ToxMessage where
6 11
12import Debug.Trace
7import Data.ByteString (ByteString) 13import Data.ByteString (ByteString)
8import qualified Crypto.MAC.Poly1305 as Poly1305 (Auth(..)) 14import qualified Crypto.MAC.Poly1305 as Poly1305 (Auth(..))
9import qualified Crypto.PubKey.Curve25519 as Curve25519 15import qualified Crypto.PubKey.Curve25519 as Curve25519
@@ -23,6 +29,8 @@ import Foreign.Ptr
23import Foreign.Marshal.Alloc 29import Foreign.Marshal.Alloc
24import System.Endian 30import System.Endian
25import Foreign.Storable 31import Foreign.Storable
32import GHC.TypeLits
33import Data.Tuple
26 34
27newtype Auth = Auth Poly1305.Auth 35newtype Auth = Auth Poly1305.Auth
28 deriving (Eq, ByteArrayAccess) 36 deriving (Eq, ByteArrayAccess)
@@ -165,6 +173,17 @@ instance Serialize (Aliased Assymetric) where
165newtype Cookie = Cookie UnclaimedAssymetric 173newtype Cookie = Cookie UnclaimedAssymetric
166 deriving (Eq, Ord,Data) 174 deriving (Eq, Ord,Data)
167 175
176newtype ReturnPath (n::Nat) = ReturnPath ByteString
177 deriving (Eq, Ord,Data)
178
179emptyReturnPath :: ReturnPath 0
180emptyReturnPath = ReturnPath B.empty
181
182instance KnownNat n => Serialize (ReturnPath n) where
183 -- Size: 59 = 1(family) + 16(ip) + 2(port) +16(mac) + 24(nonce)
184 get = ReturnPath <$> getBytes ( 59 * (fromIntegral $ natVal $ Proxy @n) )
185 put (ReturnPath bs) = putByteString bs
186
168data Symmetric = Symmetric 187data Symmetric = Symmetric
169 { symmetricNonce :: Nonce24 188 { symmetricNonce :: Nonce24
170 , symmetricAuth :: Auth 189 , symmetricAuth :: Auth
@@ -209,10 +228,10 @@ data Packet where
209 -- 228 --
210 -- If the return path is non empty, we should respond with OnionResponse3 229 -- If the return path is non empty, we should respond with OnionResponse3
211 -- rather than AnnounceResponse directly. 230 -- rather than AnnounceResponse directly.
212 Announce :: Aliased Assymetric -> Packet --0x83 231 Announce :: Aliased Assymetric -> ReturnPath 3 -> Packet --0x83
213 AnnounceResponse :: Nonce8 -> UnclaimedAssymetric -> Packet -- 0x84 232 AnnounceResponse :: Nonce8 -> UnclaimedAssymetric -> Packet -- 0x84
214 233
215 OnionResponse3 :: Symmetric -> ByteString -> Packet -- 0x8c 234 OnionResponse3 :: ReturnPath 3 -> Packet -> Packet -- 0x8c
216 OnionResponse2 :: Symmetric -> ByteString -> Packet -- 0x8d 235 OnionResponse2 :: Symmetric -> ByteString -> Packet -- 0x8d
217 OnionResponse1 :: Symmetric -> ByteString -> Packet -- 0x8e 236 OnionResponse1 :: Symmetric -> ByteString -> Packet -- 0x8e
218 237
@@ -222,9 +241,59 @@ data Packet where
222 241
223 deriving (Eq, Ord,Data) 242 deriving (Eq, Ord,Data)
224 243
244class KnownNat n => OnionPacket n where
245 mkOnion :: ReturnPath n -> Packet -> Packet
246
247instance OnionPacket 0 where mkOnion _ = id
248instance OnionPacket 3 where mkOnion = OnionResponse3
249
225newtype PacketKind = PacketKind Word8 250newtype PacketKind = PacketKind Word8
226 deriving (Eq, Ord, Serialize) 251 deriving (Eq, Ord, Serialize)
227 252
253-- TODO: Auth fail:
254pattern OnionRequest0Type = PacketKind 128 -- 0x80 Onion Request 0
255pattern OnionRequest1Type = PacketKind 129 -- 0x81 Onion Request 1
256pattern OnionRequest2Type = PacketKind 130 -- 0x82 Onion Request 2
257pattern AnnounceType = PacketKind 131 -- 0x83 Announce Request
258pattern AnnounceResponseType = PacketKind 132 -- 0x84 Announce Response
259-- 0x85 Onion Data Request (data to route request packet)
260-- 0x86 Onion Data Response (data to route response packet)
261-- 0x8c Onion Response 3
262-- 0x8d Onion Response 2
263pattern OnionResponse3Type = PacketKind 140 -- 0x8c Onion Response 3
264pattern OnionResponse2Type = PacketKind 141 -- 0x8d Onion Response 2
265pattern OnionResponse1Type = PacketKind 142 -- 0x8e Onion Response 1
266-- 0xf0 Bootstrap Info
267
268-- TODO Fix these fails...
269-- GetNodesType decipherAndAuth: auth fail
270-- MessageType 128 decipherAndAuth: auth fail
271-- MessageType 129 decipherAndAuth: auth fail
272-- MessageType 130 decipherAndAuth: auth fail
273-- MessageType 131 decipherAndAuth: auth fail
274-- MessageType 32 decipherAndAuth: auth fail
275
276-- TODO: Auth fail:
277pattern DHTRequestType = PacketKind 32 -- 0x20 DHT Request
278
279pattern PingType = PacketKind 0 -- 0x00 Ping Request
280pattern PongType = PacketKind 1 -- 0x01 Ping Response
281pattern GetNodesType = PacketKind 2 -- 0x02 Nodes Request
282pattern SendNodesType = PacketKind 4 -- 0x04 Nodes Response
283
284
285instance Show PacketKind where
286 showsPrec d PingType = mappend "PingType"
287 showsPrec d PongType = mappend "PongType"
288 showsPrec d GetNodesType = mappend "GetNodesType"
289 showsPrec d SendNodesType = mappend "SendNodesType"
290 showsPrec d DHTRequestType = mappend "DHTRequestType"
291 showsPrec d OnionRequest0Type = mappend "OnionRequest0"
292 showsPrec d OnionResponse1Type = mappend "OnionResponse1"
293 showsPrec d OnionResponse3Type = mappend "OnionResponse3"
294 showsPrec d AnnounceType = mappend "AnnounceType"
295 showsPrec d (PacketKind x) = mappend "PacketKind " . showsPrec (d+1) x
296
228pktKind :: Packet -> PacketKind 297pktKind :: Packet -> PacketKind
229 298
230-- These are (Assymetric -> Assymetric) queries. 299-- These are (Assymetric -> Assymetric) queries.
@@ -286,10 +355,25 @@ pktKind OnionResponse3 {} = PacketKind 0x8c
286 355
287data PacketClass = 356data PacketClass =
288 AssymetricClass (Assymetric -> Packet) (Packet -> Assymetric) 357 AssymetricClass (Assymetric -> Packet) (Packet -> Assymetric)
289 | AliasedClass (Aliased Assymetric -> Packet) (Packet -> Aliased Assymetric) 358 | forall n. OnionPacket n => AliasedClass ((Aliased Assymetric,ReturnPath n) -> Packet) (Packet -> (Aliased Assymetric,ReturnPath n))
359 | forall n. OnionPacket n => OnionClass ((Packet,ReturnPath n) -> Packet) (Packet -> (Packet,ReturnPath n))
290 | NoncedUnclaimedClass (Nonce8 -> UnclaimedAssymetric -> Packet) 360 | NoncedUnclaimedClass (Nonce8 -> UnclaimedAssymetric -> Packet)
291 (Packet -> (Nonce8, UnclaimedAssymetric)) 361 (Packet -> (Nonce8, UnclaimedAssymetric))
292 | Unclassified 362 | Unclassified
363{-
364data Packet' where
365 :: Assymetric -> Packet
366 :: UnclaimedAssymetric -> Packet
367 :: Word16 -> ImplicitAssymetric -> Packet
368 :: PubKey -> Assymetric -> Packet
369 :: PubKey -> Packet
370 :: Aliased Assymetric -> Symmetric -> Packet
371 :: ByteString -> Symmetric -> Packet
372 :: Aliased Assymetric -> Packet
373 :: Symmetric -> ByteString -> Packet
374 :: ByteString -> Packet
375 :: Word32 -> ByteString -> Packet
376-}
293 377
294pktClass :: PacketKind -> PacketClass 378pktClass :: PacketKind -> PacketClass
295pktClass (PacketKind 0) = AssymetricClass Ping (\(Ping a) -> a) 379pktClass (PacketKind 0) = AssymetricClass Ping (\(Ping a) -> a)
@@ -301,9 +385,11 @@ pktClass (PacketKind 0x18) = AssymetricClass CookieRequest (\(CookieRequest a) -
301pktClass (PacketKind 0x80) = AssymetricClass OnionRequest0 (\(OnionRequest0 a) -> a) 385pktClass (PacketKind 0x80) = AssymetricClass OnionRequest0 (\(OnionRequest0 a) -> a)
302-- pktClass (PacketKind 0x86) = AssymetricClass (DataToRouteResponse . Aliased) (\(DataToRouteResponse (Aliased a)) -> a) 386-- pktClass (PacketKind 0x86) = AssymetricClass (DataToRouteResponse . Aliased) (\(DataToRouteResponse (Aliased a)) -> a)
303 387
304pktClass (PacketKind 0x83) = AliasedClass Announce (\(Announce a)-> a) 388pktClass (PacketKind 0x83) = AliasedClass (uncurry Announce) (\(Announce a r)-> (a,r))
305pktClass (PacketKind 0x84) = NoncedUnclaimedClass AnnounceResponse (\(AnnounceResponse n8 uncl)-> (n8,uncl)) 389pktClass (PacketKind 0x84) = NoncedUnclaimedClass AnnounceResponse (\(AnnounceResponse n8 uncl)-> (n8,uncl))
306 390
391pktClass (PacketKind 0x8c) = OnionClass (uncurry OnionResponse3 . swap) (\(OnionResponse3 r a)-> (a,r))
392
307pktClass _ = Unclassified 393pktClass _ = Unclassified
308 394
309 395
@@ -315,27 +401,27 @@ getPacket = do
315 typ <- get 401 typ <- get
316 case pktClass typ of 402 case pktClass typ of
317 AssymetricClass toPacket _ -> toPacket <$> get 403 AssymetricClass toPacket _ -> toPacket <$> get
318 AliasedClass toPacket _ -> toPacket <$> get 404 AliasedClass toPacket _ -> do
405 trace ("PARSE "++show typ) $ return ()
406 cnt <- remaining
407 a <- isolate (cnt - 59*3) get
408 r <- get
409 trace ("PARSED "++show typ) $ return ()
410 return $ toPacket (a,r)
411 OnionClass toPacket _ -> do
412 trace ("ONION-PARSE "++show typ) $ return ()
413 p <- get
414 trace ("ONION-PARSED "++show typ) $ return ()
415 return $ toPacket p
319 NoncedUnclaimedClass toPacket _ -> toPacket <$> get <*> get 416 NoncedUnclaimedClass toPacket _ -> toPacket <$> get <*> get
417 Unclassified -> fail $ "todo: unserialize packet "++show typ
320 418
321putPacket p = do 419putPacket p = do
322 put $ pktKind p 420 put $ pktKind p
323 case pktClass (pktKind p) of 421 case pktClass (pktKind p) of
324 AssymetricClass _ fromPacket -> put $ fromPacket p 422 AssymetricClass _ fromPacket -> put $ fromPacket p
325 AliasedClass _ fromPacket -> put $ fromPacket p 423 AliasedClass _ fromPacket -> put $ fromPacket p
424 OnionClass _ fromPacket -> put $ swap $ fromPacket p
326 NoncedUnclaimedClass _ fromPacket -> put $ fromPacket p -- putting a pair. 425 NoncedUnclaimedClass _ fromPacket -> put $ fromPacket p -- putting a pair.
426 Unclassified -> fail $ "todo: serialize packet "++show (pktKind p)
327 427
328{-
329data Packet' where
330 :: Assymetric -> Packet
331 :: UnclaimedAssymetric -> Packet
332 :: Word16 -> ImplicitAssymetric -> Packet
333 :: PubKey -> Assymetric -> Packet
334 :: PubKey -> Packet
335 :: Aliased Assymetric -> Symmetric -> Packet
336 :: ByteString -> Symmetric -> Packet
337 :: Aliased Assymetric -> Packet
338 :: Symmetric -> ByteString -> Packet
339 :: ByteString -> Packet
340 :: Word32 -> ByteString -> Packet
341-}