diff options
author | joe <joe@jerkface.net> | 2017-08-11 01:08:30 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-08-11 01:08:30 -0400 |
commit | cd5091c4a3ab1c05b48ff3ad2fea666d77b8e39c (patch) | |
tree | 45bd1073d40830e6311bbaf8021899fec236abbc /ToxMessage.hs | |
parent | 85a004ac92cac382a8c2824ca6b584764ab7782d (diff) |
Reply to Announce with AnnounceResponse.
Diffstat (limited to 'ToxMessage.hs')
-rw-r--r-- | ToxMessage.hs | 124 |
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 #-} | ||
5 | module ToxMessage where | 10 | module ToxMessage where |
6 | 11 | ||
12 | import Debug.Trace | ||
7 | import Data.ByteString (ByteString) | 13 | import Data.ByteString (ByteString) |
8 | import qualified Crypto.MAC.Poly1305 as Poly1305 (Auth(..)) | 14 | import qualified Crypto.MAC.Poly1305 as Poly1305 (Auth(..)) |
9 | import qualified Crypto.PubKey.Curve25519 as Curve25519 | 15 | import qualified Crypto.PubKey.Curve25519 as Curve25519 |
@@ -23,6 +29,8 @@ import Foreign.Ptr | |||
23 | import Foreign.Marshal.Alloc | 29 | import Foreign.Marshal.Alloc |
24 | import System.Endian | 30 | import System.Endian |
25 | import Foreign.Storable | 31 | import Foreign.Storable |
32 | import GHC.TypeLits | ||
33 | import Data.Tuple | ||
26 | 34 | ||
27 | newtype Auth = Auth Poly1305.Auth | 35 | newtype Auth = Auth Poly1305.Auth |
28 | deriving (Eq, ByteArrayAccess) | 36 | deriving (Eq, ByteArrayAccess) |
@@ -165,6 +173,17 @@ instance Serialize (Aliased Assymetric) where | |||
165 | newtype Cookie = Cookie UnclaimedAssymetric | 173 | newtype Cookie = Cookie UnclaimedAssymetric |
166 | deriving (Eq, Ord,Data) | 174 | deriving (Eq, Ord,Data) |
167 | 175 | ||
176 | newtype ReturnPath (n::Nat) = ReturnPath ByteString | ||
177 | deriving (Eq, Ord,Data) | ||
178 | |||
179 | emptyReturnPath :: ReturnPath 0 | ||
180 | emptyReturnPath = ReturnPath B.empty | ||
181 | |||
182 | instance 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 | |||
168 | data Symmetric = Symmetric | 187 | data 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 | ||
244 | class KnownNat n => OnionPacket n where | ||
245 | mkOnion :: ReturnPath n -> Packet -> Packet | ||
246 | |||
247 | instance OnionPacket 0 where mkOnion _ = id | ||
248 | instance OnionPacket 3 where mkOnion = OnionResponse3 | ||
249 | |||
225 | newtype PacketKind = PacketKind Word8 | 250 | newtype PacketKind = PacketKind Word8 |
226 | deriving (Eq, Ord, Serialize) | 251 | deriving (Eq, Ord, Serialize) |
227 | 252 | ||
253 | -- TODO: Auth fail: | ||
254 | pattern OnionRequest0Type = PacketKind 128 -- 0x80 Onion Request 0 | ||
255 | pattern OnionRequest1Type = PacketKind 129 -- 0x81 Onion Request 1 | ||
256 | pattern OnionRequest2Type = PacketKind 130 -- 0x82 Onion Request 2 | ||
257 | pattern AnnounceType = PacketKind 131 -- 0x83 Announce Request | ||
258 | pattern 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 | ||
263 | pattern OnionResponse3Type = PacketKind 140 -- 0x8c Onion Response 3 | ||
264 | pattern OnionResponse2Type = PacketKind 141 -- 0x8d Onion Response 2 | ||
265 | pattern 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: | ||
277 | pattern DHTRequestType = PacketKind 32 -- 0x20 DHT Request | ||
278 | |||
279 | pattern PingType = PacketKind 0 -- 0x00 Ping Request | ||
280 | pattern PongType = PacketKind 1 -- 0x01 Ping Response | ||
281 | pattern GetNodesType = PacketKind 2 -- 0x02 Nodes Request | ||
282 | pattern SendNodesType = PacketKind 4 -- 0x04 Nodes Response | ||
283 | |||
284 | |||
285 | instance 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 | |||
228 | pktKind :: Packet -> PacketKind | 297 | pktKind :: 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 | ||
287 | data PacketClass = | 356 | data 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 | {- | ||
364 | data 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 | ||
294 | pktClass :: PacketKind -> PacketClass | 378 | pktClass :: PacketKind -> PacketClass |
295 | pktClass (PacketKind 0) = AssymetricClass Ping (\(Ping a) -> a) | 379 | pktClass (PacketKind 0) = AssymetricClass Ping (\(Ping a) -> a) |
@@ -301,9 +385,11 @@ pktClass (PacketKind 0x18) = AssymetricClass CookieRequest (\(CookieRequest a) - | |||
301 | pktClass (PacketKind 0x80) = AssymetricClass OnionRequest0 (\(OnionRequest0 a) -> a) | 385 | pktClass (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 | ||
304 | pktClass (PacketKind 0x83) = AliasedClass Announce (\(Announce a)-> a) | 388 | pktClass (PacketKind 0x83) = AliasedClass (uncurry Announce) (\(Announce a r)-> (a,r)) |
305 | pktClass (PacketKind 0x84) = NoncedUnclaimedClass AnnounceResponse (\(AnnounceResponse n8 uncl)-> (n8,uncl)) | 389 | pktClass (PacketKind 0x84) = NoncedUnclaimedClass AnnounceResponse (\(AnnounceResponse n8 uncl)-> (n8,uncl)) |
306 | 390 | ||
391 | pktClass (PacketKind 0x8c) = OnionClass (uncurry OnionResponse3 . swap) (\(OnionResponse3 r a)-> (a,r)) | ||
392 | |||
307 | pktClass _ = Unclassified | 393 | pktClass _ = 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 | ||
321 | putPacket p = do | 419 | putPacket 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 | {- | ||
329 | data 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 | -} | ||