diff options
author | joe <joe@jerkface.net> | 2017-09-03 21:12:47 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-09-03 21:12:47 -0400 |
commit | 4a2b7b113cb68cf39584f34437b6b7ddc5633874 (patch) | |
tree | 0fe735fc05c79678b2cc78ba8725949f682588cf /OnionTransport.hs | |
parent | a1a56ca53dc9346365d182b28be0aea7a93c465a (diff) |
Progress on OnionTransport.
Diffstat (limited to 'OnionTransport.hs')
-rw-r--r-- | OnionTransport.hs | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/OnionTransport.hs b/OnionTransport.hs index aa4bae1e..d6f6671e 100644 --- a/OnionTransport.hs +++ b/OnionTransport.hs | |||
@@ -1,12 +1,16 @@ | |||
1 | {-# LANGUAGE DataKinds #-} | 1 | {-# LANGUAGE DataKinds #-} |
2 | {-# LANGUAGE FlexibleContexts #-} | ||
3 | {-# LANGUAGE FlexibleInstances #-} | ||
2 | {-# LANGUAGE GADTs #-} | 4 | {-# LANGUAGE GADTs #-} |
3 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 5 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
4 | {-# LANGUAGE KindSignatures #-} | 6 | {-# LANGUAGE KindSignatures #-} |
7 | {-# LANGUAGE StandaloneDeriving #-} | ||
5 | {-# LANGUAGE LambdaCase #-} | 8 | {-# LANGUAGE LambdaCase #-} |
6 | {-# LANGUAGE RankNTypes #-} | 9 | {-# LANGUAGE RankNTypes #-} |
7 | {-# LANGUAGE ScopedTypeVariables #-} | 10 | {-# LANGUAGE ScopedTypeVariables #-} |
8 | {-# LANGUAGE TupleSections #-} | 11 | {-# LANGUAGE TupleSections #-} |
9 | {-# LANGUAGE TypeOperators #-} | 12 | {-# LANGUAGE TypeOperators #-} |
13 | {-# LANGUAGE UndecidableInstances #-} | ||
10 | module OnionTransport | 14 | module OnionTransport |
11 | ( parseOnionAddr | 15 | ( parseOnionAddr |
12 | , encodeOnionAddr | 16 | , encodeOnionAddr |
@@ -29,6 +33,7 @@ module OnionTransport | |||
29 | 33 | ||
30 | import Network.QueryResponse | 34 | import Network.QueryResponse |
31 | import ToxCrypto hiding (encrypt,decrypt) | 35 | import ToxCrypto hiding (encrypt,decrypt) |
36 | import ToxAddress | ||
32 | import qualified ToxCrypto | 37 | import qualified ToxCrypto |
33 | import DHTTransport (NodeInfo(..),NodeId(..),SendNodes,nodeInfo) | 38 | import DHTTransport (NodeInfo(..),NodeId(..),SendNodes,nodeInfo) |
34 | 39 | ||
@@ -36,11 +41,12 @@ import Control.Arrow | |||
36 | import qualified Data.ByteString as B | 41 | import qualified Data.ByteString as B |
37 | ;import Data.ByteString (ByteString) | 42 | ;import Data.ByteString (ByteString) |
38 | import Data.Functor.Identity | 43 | import Data.Functor.Identity |
39 | import Data.Serialize as S (Get, Put, Serialize, get, put, runGet) | 44 | import Data.Serialize as S |
40 | import Data.Typeable | 45 | import Data.Typeable |
41 | import Data.Word | 46 | import Data.Word |
42 | import GHC.TypeLits | 47 | import GHC.TypeLits |
43 | import Network.Socket | 48 | import Network.Socket |
49 | import GHC.Generics | ||
44 | 50 | ||
45 | type HandleLo a = Maybe (Either String (ByteString, SockAddr)) -> IO a | 51 | type HandleLo a = Maybe (Either String (ByteString, SockAddr)) -> IO a |
46 | 52 | ||
@@ -48,7 +54,10 @@ type UDPTransport = Transport String SockAddr ByteString | |||
48 | 54 | ||
49 | 55 | ||
50 | getOnionAssym :: Get (Assym (Encrypted DataToRoute)) | 56 | getOnionAssym :: Get (Assym (Encrypted DataToRoute)) |
51 | getOnionAssym = _todo | 57 | getOnionAssym = getAliasedAssym |
58 | |||
59 | putOnionAssym :: Serialize a => Word8 -> Put -> Assym a -> Put | ||
60 | putOnionAssym typ p a = put typ >> p >> putAliasedAssym a | ||
52 | 61 | ||
53 | data OnionMessage (f :: * -> *) | 62 | data OnionMessage (f :: * -> *) |
54 | = OnionAnnounce (Assym (f (AnnounceRequest,Nonce8))) | 63 | = OnionAnnounce (Assym (f (AnnounceRequest,Nonce8))) |
@@ -61,12 +70,18 @@ data OnionToOwner = OnionToOwner NodeInfo (ReturnPath 3) | |||
61 | deriving Show | 70 | deriving Show |
62 | 71 | ||
63 | 72 | ||
73 | onionToOwner :: Assym a -> ReturnPath 3 -> SockAddr -> Either String OnionToOwner | ||
64 | onionToOwner assym ret3 saddr = do | 74 | onionToOwner assym ret3 saddr = do |
65 | ni <- nodeInfo (NodeId $ senderKey assym) saddr | 75 | ni <- nodeInfo (NodeId $ senderKey assym) saddr |
66 | return $ OnionToOwner ni ret3 | 76 | return $ OnionToOwner ni ret3 |
67 | -- data CookieAddress = WithoutCookie NodeInfo | CookieAddress Cookie SockAddr | 77 | -- data CookieAddress = WithoutCookie NodeInfo | CookieAddress Cookie SockAddr |
68 | 78 | ||
69 | 79 | ||
80 | onion :: Sized msg => | ||
81 | ByteString | ||
82 | -> SockAddr | ||
83 | -> Get (Assym (Encrypted msg) -> t) | ||
84 | -> Either String (t, OnionToOwner) | ||
70 | onion bs saddr getf = do (f,(assym,ret3)) <- runGet ((,) <$> getf <*> getOnionRequest) bs | 85 | onion bs saddr getf = do (f,(assym,ret3)) <- runGet ((,) <$> getf <*> getOnionRequest) bs |
71 | oaddr <- onionToOwner assym ret3 saddr | 86 | oaddr <- onionToOwner assym ret3 saddr |
72 | return (f assym, oaddr) | 87 | return (f assym, oaddr) |
@@ -86,7 +101,15 @@ parseOnionAddr (msg,saddr) | |||
86 | _ -> right | 101 | _ -> right |
87 | 102 | ||
88 | encodeOnionAddr :: (OnionMessage Encrypted,OnionToOwner) -> (ByteString, SockAddr) | 103 | encodeOnionAddr :: (OnionMessage Encrypted,OnionToOwner) -> (ByteString, SockAddr) |
89 | encodeOnionAddr = _todo | 104 | encodeOnionAddr (msg,addr) = ( runPut (putmsg >> putpath), saddr ) |
105 | where | ||
106 | (saddr,putpath) | OnionToOwner ni p <- addr = (nodeAddr ni, put p) | ||
107 | | OnionToMe a <- addr = (a, return ()) | ||
108 | |||
109 | putmsg | OnionAnnounce a <- msg = putOnionAssym 0x83 (return ()) a | ||
110 | | OnionToRoute pubkey a <- msg = putOnionAssym 0x85 (putPublicKey pubkey) a | ||
111 | | OnionToRouteResponse a <- msg = putOnionAssym 0x86 (return ()) a | ||
112 | | OnionAnnounceResponse n8 n24 x <- msg = put (0x84 :: Word8) >> put n8 >> put n24 >> put x | ||
90 | 113 | ||
91 | forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a | 114 | forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a |
92 | forwardOnions crypto udp = udp { awaitMessage = await' } | 115 | forwardOnions crypto udp = udp { awaitMessage = await' } |
@@ -117,8 +140,11 @@ data OnionRequest (n :: Nat) = OnionRequest | |||
117 | , pathFromOwner :: ReturnPath n | 140 | , pathFromOwner :: ReturnPath n |
118 | } | 141 | } |
119 | 142 | ||
120 | instance Serialize (OnionRequest n) where { get = _todo; put = _todo } | 143 | instance ( Serialize (Forwarding (3 - n) (OnionMessage Encrypted)) |
121 | instance Serialize (OnionResponse n) where { get = _todo; put = _todo } | 144 | , Serialize (ReturnPath n) |
145 | ) => Serialize (OnionRequest n) where | ||
146 | get = OnionRequest <$> get <*> get <*> get | ||
147 | put (OnionRequest n f p) = put n >> put f >> put p | ||
122 | 148 | ||
123 | -- n = 1, 2, 3 | 149 | -- n = 1, 2, 3 |
124 | -- Attributed (Encrypted ( | 150 | -- Attributed (Encrypted ( |
@@ -128,11 +154,23 @@ data OnionResponse (n :: Nat) = OnionResponse | |||
128 | , msgToOwner :: OnionMessage Encrypted | 154 | , msgToOwner :: OnionMessage Encrypted |
129 | } | 155 | } |
130 | 156 | ||
157 | instance ( KnownNat n, Serialize (ReturnPath n) ) => Serialize (OnionResponse n) where | ||
158 | get = OnionResponse <$> get <*> get | ||
159 | put (OnionResponse p m) = put p >> put m | ||
160 | |||
161 | |||
131 | data Addressed a = Addressed { sockAddr :: SockAddr, unaddressed :: a } | 162 | data Addressed a = Addressed { sockAddr :: SockAddr, unaddressed :: a } |
132 | 163 | ||
133 | data ReturnPath (n :: Nat) where | 164 | data ReturnPath (n :: Nat) where |
134 | NoReturnPath :: ReturnPath 0 | 165 | NoReturnPath :: ReturnPath 0 |
135 | ReturnPath :: Nonce24 -> Encrypted (Addressed (ReturnPath n)) -> ReturnPath (n + 1) | 166 | ReturnPath :: Nonce24 -> Encrypted (Addressed (ReturnPath (n - 1))) -> ReturnPath n |
167 | |||
168 | instance KnownNat n => Sized (Addressed (ReturnPath n)) where size = _todo | ||
169 | -- -- Size: 59 = 1(family) + 16(ip) + 2(port) +16(mac) + 24(nonce) | ||
170 | |||
171 | instance (Serialize (Encrypted (Addressed (ReturnPath (n - 1))))) => Serialize (ReturnPath n) where | ||
172 | get = ReturnPath <$> get <*> get | ||
173 | put (ReturnPath n24 p) = put n24 >> put p | ||
136 | 174 | ||
137 | instance KnownNat n => Show (ReturnPath n) where | 175 | instance KnownNat n => Show (ReturnPath n) where |
138 | show rpath = "ReturnPath" ++ show (natVal rpath) | 176 | show rpath = "ReturnPath" ++ show (natVal rpath) |
@@ -146,7 +184,14 @@ instance KnownNat n => Show (ReturnPath n) where | |||
146 | 184 | ||
147 | data Forwarding (n :: Nat) msg where | 185 | data Forwarding (n :: Nat) msg where |
148 | NotForwarded :: msg -> Forwarding 0 msg | 186 | NotForwarded :: msg -> Forwarding 0 msg |
149 | Forwarding :: Assym (Encrypted (Addressed (Forwarding n msg))) -> Forwarding (n + 1) msg | 187 | Forwarding :: Assym (Encrypted (Addressed (Forwarding (n - 1) msg))) -> Forwarding n msg |
188 | |||
189 | instance (KnownNat n, Sized msg) => Sized (Addressed (Forwarding n msg)) where size = _todo | ||
190 | |||
191 | instance (Serialize msg, Serialize (Encrypted (Addressed (Forwarding (n - 1) msg)))) => Serialize (Forwarding n msg) where | ||
192 | get = Forwarding <$> getAliasedAssym | ||
193 | put (Forwarding x) = putAliasedAssym x | ||
194 | |||
150 | 195 | ||
151 | handleOnionRequest :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionRequest n -> IO a | 196 | handleOnionRequest :: KnownNat n => proxy n -> TransportCrypto -> SockAddr -> IO a -> OnionRequest n -> IO a |
152 | handleOnionRequest = _todo | 197 | handleOnionRequest = _todo |
@@ -160,23 +205,19 @@ data AnnounceRequest = AnnounceRequest | |||
160 | , announceKey :: NodeId -- Public key that we want those sending back data packets to use | 205 | , announceKey :: NodeId -- Public key that we want those sending back data packets to use |
161 | } | 206 | } |
162 | 207 | ||
208 | instance Sized AnnounceRequest where size = _todo | ||
209 | |||
163 | instance S.Serialize AnnounceRequest where | 210 | instance S.Serialize AnnounceRequest where |
164 | get = AnnounceRequest <$> S.get <*> S.get <*> S.get | 211 | get = AnnounceRequest <$> S.get <*> S.get <*> S.get |
165 | put (AnnounceRequest p s k) = S.put (p,s,k) | 212 | put (AnnounceRequest p s k) = S.put (p,s,k) |
166 | 213 | ||
167 | getOnionRequest :: Get (Assym (Encrypted msg), ReturnPath 3) | 214 | getOnionRequest :: Sized msg => Get (Assym (Encrypted msg), ReturnPath 3) |
168 | getOnionRequest = _todo | 215 | getOnionRequest = (,) <$> getAliasedAssym <*> _todo |
169 | 216 | ||
170 | data KeyRecord = NotStored Nonce32 | 217 | data KeyRecord = NotStored Nonce32 |
171 | | SendBackKey PublicKey | 218 | | SendBackKey PublicKey |
172 | | Acknowledged Nonce32 | 219 | | Acknowledged Nonce32 |
173 | 220 | ||
174 | getPublicKey :: Get PublicKey | ||
175 | getPublicKey = _todo | ||
176 | |||
177 | putPublicKey :: PublicKey -> Put | ||
178 | putPublicKey = _todo | ||
179 | |||
180 | instance S.Serialize KeyRecord where | 221 | instance S.Serialize KeyRecord where |
181 | get = do | 222 | get = do |
182 | is_stored <- S.get :: S.Get Word8 | 223 | is_stored <- S.get :: S.Get Word8 |
@@ -205,6 +246,9 @@ data DataToRoute = DataToRoute | |||
205 | , dataToRoute :: Encrypted (Word8,ByteString) | 246 | , dataToRoute :: Encrypted (Word8,ByteString) |
206 | } | 247 | } |
207 | 248 | ||
249 | instance Sized DataToRoute where | ||
250 | size = VarSize $ \DataToRoute {} -> _todo | ||
251 | |||
208 | instance Serialize DataToRoute where | 252 | instance Serialize DataToRoute where |
209 | get = return $ DataToRoute _todo _todo | 253 | get = return $ DataToRoute _todo _todo |
210 | put _ = return () -- todo | 254 | put _ = return () -- todo |