summaryrefslogtreecommitdiff
path: root/src/Network/Tox/Onion/Transport.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/Tox/Onion/Transport.hs')
-rw-r--r--src/Network/Tox/Onion/Transport.hs57
1 files changed, 32 insertions, 25 deletions
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index 8c4df694..a521c39e 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -19,7 +19,7 @@ module Network.Tox.Onion.Transport
19 ( parseOnionAddr 19 ( parseOnionAddr
20 , encodeOnionAddr 20 , encodeOnionAddr
21 , forwardOnions 21 , forwardOnions
22 , OnionToOwner(..) 22 , OnionDestination(..)
23 , OnionMessage(..) 23 , OnionMessage(..)
24 , DataToRoute(..) 24 , DataToRoute(..)
25 , AnnounceResponse(..) 25 , AnnounceResponse(..)
@@ -41,7 +41,7 @@ import Network.QueryResponse
41import Crypto.Tox hiding (encrypt,decrypt) 41import Crypto.Tox hiding (encrypt,decrypt)
42import Network.Tox.NodeId 42import Network.Tox.NodeId
43import qualified Crypto.Tox as ToxCrypto 43import qualified Crypto.Tox as ToxCrypto
44import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes,nodeInfo,DHTPublicKey) 44import Network.Tox.DHT.Transport (NodeInfo(..),NodeId(..),SendNodes,nodeInfo,DHTPublicKey,asymNodeInfo)
45 45
46import Debug.Trace 46import Debug.Trace
47import Control.Arrow 47import Control.Arrow
@@ -87,11 +87,11 @@ deriving instance ( Show (f (AnnounceRequest, Nonce8))
87 , Show (f DataToRoute) 87 , Show (f DataToRoute)
88 ) => Show (OnionMessage f) 88 ) => Show (OnionMessage f)
89 89
90data OnionToOwner = OnionToOwner NodeInfo (ReturnPath N3) 90data OnionDestination = OnionToOwner NodeInfo (ReturnPath N3) -- ^ Somebody else's path to us.
91 | OnionToMe SockAddr -- SockAddr is immediate peer in route 91 | OnionDestination NodeInfo -- ^ Our own onion-path.
92 deriving Show 92 deriving Show
93 93
94onionKey :: OnionToOwner -> Maybe PublicKey 94onionKey :: OnionDestination -> Maybe PublicKey
95onionKey (OnionToOwner ni _) = Just $ id2key (nodeId ni) 95onionKey (OnionToOwner ni _) = Just $ id2key (nodeId ni)
96onionKey _ = Nothing 96onionKey _ = Nothing
97 97
@@ -120,7 +120,7 @@ instance Serialize (OnionMessage Encrypted) where
120 put (OnionAnnounceResponse n8 n24 x) = putWord8 0x84 >> put n8 >> put n24 >> put x 120 put (OnionAnnounceResponse n8 n24 x) = putWord8 0x84 >> put n8 >> put n24 >> put x
121 put (OnionToRouteResponse a) = putWord8 0x86 >> putAliasedAssym a 121 put (OnionToRouteResponse a) = putWord8 0x86 >> putAliasedAssym a
122 122
123onionToOwner :: Assym a -> ReturnPath N3 -> SockAddr -> Either String OnionToOwner 123onionToOwner :: Assym a -> ReturnPath N3 -> SockAddr -> Either String OnionDestination
124onionToOwner assym ret3 saddr = do 124onionToOwner assym ret3 saddr = do
125 ni <- nodeInfo (key2id $ senderKey assym) saddr 125 ni <- nodeInfo (key2id $ senderKey assym) saddr
126 return $ OnionToOwner ni ret3 126 return $ OnionToOwner ni ret3
@@ -131,18 +131,18 @@ onion :: Sized msg =>
131 ByteString 131 ByteString
132 -> SockAddr 132 -> SockAddr
133 -> Get (Assym (Encrypted msg) -> t) 133 -> Get (Assym (Encrypted msg) -> t)
134 -> Either String (t, OnionToOwner) 134 -> Either String (t, OnionDestination)
135onion bs saddr getf = do (f,(assym,ret3)) <- runGet ((,) <$> getf <*> getOnionRequest) bs 135onion bs saddr getf = do (f,(assym,ret3)) <- runGet ((,) <$> getf <*> getOnionRequest) bs
136 oaddr <- onionToOwner assym ret3 saddr 136 oaddr <- onionToOwner assym ret3 saddr
137 return (f assym, oaddr) 137 return (f assym, oaddr)
138 138
139 139
140parseOnionAddr :: (ByteString, SockAddr) -> Either (OnionMessage Encrypted,OnionToOwner) (ByteString,SockAddr) 140parseOnionAddr :: (ByteString, SockAddr) -> Either (OnionMessage Encrypted,OnionDestination) (ByteString,SockAddr)
141parseOnionAddr (msg,saddr) 141parseOnionAddr (msg,saddr)
142 | Just (typ,bs) <- B.uncons msg 142 | Just (typ,bs) <- B.uncons msg
143 , let right = Right (msg,saddr) 143 , let right = Right (msg,saddr)
144 query = either (const right) Left 144 query = either (const right) Left
145 response = either (const right) (Left . (, OnionToMe saddr)) 145 response = either (const right) (Left . \msg -> ( msg , replyAlias saddr msg ))
146 = case typ of 146 = case typ of
147 0x83 -> query $ onion bs saddr (pure OnionAnnounce) -- Announce Request 147 0x83 -> query $ onion bs saddr (pure OnionAnnounce) -- Announce Request
148 0x85 -> query $ onion bs saddr (OnionToRoute <$> getPublicKey) -- Onion Data Request 148 0x85 -> query $ onion bs saddr (OnionToRoute <$> getPublicKey) -- Onion Data Request
@@ -154,22 +154,28 @@ getOnionReply :: Word8 -> Get (OnionMessage Encrypted)
154getOnionReply 0x84 = OnionAnnounceResponse <$> get <*> get <*> get 154getOnionReply 0x84 = OnionAnnounceResponse <$> get <*> get <*> get
155getOnionReply 0x86 = OnionToRouteResponse <$> getOnionAssym 155getOnionReply 0x86 = OnionToRouteResponse <$> getOnionAssym
156 156
157replyAlias :: SockAddr -> OnionMessage Encrypted -> OnionDestination
158replyAlias saddr (OnionAnnounceResponse _ _ _)
159 = OnionDestination
160 $ either (error "replyAlias: bad protocol") id
161 $ nodeInfo zeroID saddr -- TODO OnionAnnounceResponse has no sender key
162replyAlias saddr (OnionToRouteResponse asym)
163 = OnionDestination $ asymNodeInfo saddr asym
164
157putOnionMsg :: OnionMessage Encrypted -> Put 165putOnionMsg :: OnionMessage Encrypted -> Put
158putOnionMsg (OnionAnnounce a) = putOnionAssym 0x83 (return ()) a 166putOnionMsg (OnionAnnounce a) = putOnionAssym 0x83 (return ()) a
159putOnionMsg (OnionToRoute pubkey a) = putOnionAssym 0x85 (putPublicKey pubkey) a 167putOnionMsg (OnionToRoute pubkey a) = putOnionAssym 0x85 (putPublicKey pubkey) a
160putOnionMsg (OnionAnnounceResponse n8 n24 x) = put (0x84 :: Word8) >> put n8 >> put n24 >> put x 168putOnionMsg (OnionAnnounceResponse n8 n24 x) = put (0x84 :: Word8) >> put n8 >> put n24 >> put x
161putOnionMsg (OnionToRouteResponse a) = putOnionAssym 0x86 (return ()) a 169putOnionMsg (OnionToRouteResponse a) = putOnionAssym 0x86 (return ()) a
162 170
163encodeOnionAddr :: (OnionMessage Encrypted,OnionToOwner) -> (ByteString, SockAddr) 171encodeOnionAddr :: (OnionMessage Encrypted,OnionDestination) -> (ByteString, SockAddr)
164encodeOnionAddr (msg,OnionToOwner ni p) = ( runPut $ putResponse (OnionResponse p msg) 172encodeOnionAddr (msg,OnionToOwner ni p) = ( runPut $ putResponse (OnionResponse p msg)
165 , nodeAddr ni ) 173 , nodeAddr ni )
166encodeOnionAddr (msg,OnionToMe a) = ( runPut (putOnionMsg msg), a) 174encodeOnionAddr (msg,OnionDestination a) = ( runPut (putOnionMsg msg), nodeAddr a) -- TODO: Construct (OnionRequest N0)?
167 175
168forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport -- HandleHi a -> IO a -> HandleLo a 176forwardOnions :: TransportCrypto -> UDPTransport -> UDPTransport
169forwardOnions crypto udp = udp { awaitMessage = forwardAwait crypto udp } 177forwardOnions crypto udp = udp { awaitMessage = forwardAwait crypto udp }
170 178
171-- forMe :: HandleHi
172-- forThem :: handleLo
173forwardAwait :: TransportCrypto -> UDPTransport -> HandleLo a -> IO a 179forwardAwait :: TransportCrypto -> UDPTransport -> HandleLo a -> IO a
174forwardAwait crypto udp kont = do 180forwardAwait crypto udp kont = do
175 fix $ \another -> do 181 fix $ \another -> do
@@ -520,26 +526,27 @@ instance Sized OnionData where
520 -- should be treated as variable sized. 526 -- should be treated as variable sized.
521 VarSize f -> f dhtpk 527 VarSize f -> f dhtpk
522 528
523encrypt :: TransportCrypto -> OnionMessage Identity -> OnionToOwner -> (OnionMessage Encrypted, OnionToOwner) 529encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination -> (OnionMessage Encrypted, OnionDestination)
524encrypt crypto msg rpath = ( transcode (encryptMessage crypto okey) msg 530encrypt crypto msg rpath = ( transcode ( (. (runIdentity . either id assymData))
531 . encryptMessage skey okey)
532 msg
525 , rpath) 533 , rpath)
526 where 534 where
535 skey = transportSecret crypto
536
527 -- The OnionToMe case shouldn't happen, but we'll use our own public 537 -- The OnionToMe case shouldn't happen, but we'll use our own public
528 -- key in this situation. 538 -- key in this situation.
529 okey = fromMaybe (transportPublic crypto) $ onionKey rpath 539 okey = fromMaybe (transportPublic crypto) $ onionKey rpath
530 540
541
531encryptMessage :: Serialize a => 542encryptMessage :: Serialize a =>
532 TransportCrypto -> PublicKey -> Nonce24 -> Either (Identity a) (Assym (Identity a)) -> Encrypted a 543 SecretKey -> PublicKey -> Nonce24 -> a -> Encrypted a
533encryptMessage crypto destKey n (Right a) = ToxCrypto.encrypt secret plain 544encryptMessage skey destKey n a = ToxCrypto.encrypt secret plain
534 where
535 secret = computeSharedSecret (transportSecret crypto) destKey n
536 plain = encodePlain $ runIdentity $ assymData a
537encryptMessage crypto destKey n (Left x) = ToxCrypto.encrypt secret plain
538 where 545 where
539 secret = computeSharedSecret (transportSecret crypto) destKey n 546 secret = computeSharedSecret skey destKey n
540 plain = encodePlain $ runIdentity $ x 547 plain = encodePlain a
541 548
542decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionToOwner -> Either String (OnionMessage Identity, OnionToOwner) 549decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination -> Either String (OnionMessage Identity, OnionDestination)
543decrypt crypto msg addr = (, addr) <$> (sequenceMessage $ transcode (decryptMessage crypto) msg) 550decrypt crypto msg addr = (, addr) <$> (sequenceMessage $ transcode (decryptMessage crypto) msg)
544 551
545decryptMessage :: Serialize x => 552decryptMessage :: Serialize x =>