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.hs85
1 files changed, 44 insertions, 41 deletions
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index 34ba23f6..e52c8faa 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -20,6 +20,7 @@ module Network.Tox.Onion.Transport
20 , parseDataToRoute 20 , parseDataToRoute
21 , encodeDataToRoute 21 , encodeDataToRoute
22 , forwardOnions 22 , forwardOnions
23 , AliasSelector(..)
23 , OnionDestination(..) 24 , OnionDestination(..)
24 , OnionMessage(..) 25 , OnionMessage(..)
25 , Rendezvous(..) 26 , Rendezvous(..)
@@ -39,7 +40,7 @@ module Network.Tox.Onion.Transport
39 , OnionRoute(..) 40 , OnionRoute(..)
40 , N3 41 , N3
41 , onionKey 42 , onionKey
42 , onionNodeInfo 43 , onionAliasSelector
43 ) where 44 ) where
44 45
45import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort) 46import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort)
@@ -100,17 +101,27 @@ msgNonce (OnionAnnounceResponse _ n24 _) = n24
100msgNonce (OnionToRoute _ a) = assymNonce a 101msgNonce (OnionToRoute _ a) = assymNonce a
101msgNonce (OnionToRouteResponse a) = assymNonce a 102msgNonce (OnionToRouteResponse a) = assymNonce a
102 103
104data AliasSelector = SearchingAlias | AnnouncingAlias NodeId
105 deriving (Eq,Ord,Show)
106
103data OnionDestination r 107data OnionDestination r
104 = OnionToOwner NodeInfo (ReturnPath N3) -- ^ Somebody else's path to us. 108 = OnionToOwner
105 | OnionDestination NodeInfo (Maybe r) -- ^ Our own onion-path. 109 { onionNodeInfo :: NodeInfo
110 , onionReturnPath :: ReturnPath N3 -- ^ Somebody else's path to us.
111 }
112 | OnionDestination
113 { onionAliasSelector' :: AliasSelector
114 , onionNodeInfo :: NodeInfo
115 , onionRouteSpec :: Maybe r -- ^ Our own onion-path.
116 }
106 deriving Show 117 deriving Show
107 118
108onionNodeInfo :: OnionDestination r -> NodeInfo 119onionAliasSelector :: OnionDestination r -> AliasSelector
109onionNodeInfo (OnionToOwner ni _) = ni 120onionAliasSelector (OnionToOwner {} ) = SearchingAlias
110onionNodeInfo (OnionDestination ni _) = ni 121onionAliasSelector (OnionDestination{onionAliasSelector' = sel}) = sel
111 122
112onionKey :: OnionDestination r -> Maybe PublicKey 123onionKey :: OnionDestination r -> PublicKey
113onionKey od = Just $ id2key . nodeId $ onionNodeInfo od 124onionKey od = id2key . nodeId $ onionNodeInfo od
114 125
115instance Sized (OnionMessage Encrypted) where 126instance Sized (OnionMessage Encrypted) where
116 size = VarSize $ \case 127 size = VarSize $ \case
@@ -152,7 +163,7 @@ onion bs saddr getf = do (f,(assym,ret3)) <- runGet ((,) <$> getf <*> getOnionRe
152 oaddr <- onionToOwner assym ret3 saddr 163 oaddr <- onionToOwner assym ret3 saddr
153 return (f assym, oaddr) 164 return (f assym, oaddr)
154 165
155parseOnionAddr :: (SockAddr -> Nonce8 -> IO (Maybe (NodeInfo,r))) 166parseOnionAddr :: (SockAddr -> Nonce8 -> IO (Maybe (OnionDestination r)))
156 -> (ByteString, SockAddr) 167 -> (ByteString, SockAddr)
157 -> IO (Either (OnionMessage Encrypted,OnionDestination r) 168 -> IO (Either (OnionMessage Encrypted,OnionDestination r)
158 (ByteString,SockAddr)) 169 (ByteString,SockAddr))
@@ -167,11 +178,11 @@ parseOnionAddr lookupSender (msg,saddr)
167 Just (Right msg@(OnionAnnounceResponse n8 _ _)) -> do 178 Just (Right msg@(OnionAnnounceResponse n8 _ _)) -> do
168 maddr <- lookupSender saddr n8 179 maddr <- lookupSender saddr n8
169 maybe (return right) -- Response unsolicited or too late. 180 maybe (return right) -- Response unsolicited or too late.
170 (return . Left . \(ni,r) -> (msg,OnionDestination ni (Just r))) 181 (return . Left . \od -> (msg,od))
171 maddr 182 maddr
172 Just (Right msg@(OnionToRouteResponse asym)) -> do 183 Just (Right msg@(OnionToRouteResponse asym)) -> do
173 let ni = asymNodeInfo saddr asym 184 let ni = asymNodeInfo saddr asym
174 return $ Left (msg, OnionDestination ni Nothing) 185 return $ Left (msg, OnionDestination SearchingAlias ni Nothing)
175 _ -> return right 186 _ -> return right
176 187
177getOnionReply :: Word8 -> Maybe (Get (OnionMessage Encrypted)) 188getOnionReply :: Word8 -> Maybe (Get (OnionMessage Encrypted))
@@ -191,10 +202,10 @@ encodeOnionAddr :: (NodeInfo -> r -> IO (Maybe OnionRoute))
191encodeOnionAddr _ (msg,OnionToOwner ni p) = 202encodeOnionAddr _ (msg,OnionToOwner ni p) =
192 return $ Just ( runPut $ putResponse (OnionResponse p msg) 203 return $ Just ( runPut $ putResponse (OnionResponse p msg)
193 , nodeAddr ni ) 204 , nodeAddr ni )
194encodeOnionAddr _ (msg,OnionDestination _ Nothing ) = do 205encodeOnionAddr _ (msg,OnionDestination _ _ Nothing) = do
195 hPutStrLn stderr $ "ONION encode missing routeid" 206 hPutStrLn stderr $ "ONION encode missing routeid"
196 return Nothing 207 return Nothing
197encodeOnionAddr getRoute (msg,OnionDestination ni (Just rid)) = do 208encodeOnionAddr getRoute (msg,OnionDestination _ ni (Just rid)) = do
198 let go route = do 209 let go route = do
199 return ( runPut $ putRequest $ wrapForRoute msg ni route 210 return ( runPut $ putRequest $ wrapForRoute msg ni route
200 , nodeAddr $ routeNodeA route) 211 , nodeAddr $ routeNodeA route)
@@ -599,26 +610,19 @@ instance Sized OnionData where
599 VarSize f -> f req 610 VarSize f -> f req
600 611
601 612
602selectKey :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (SecretKey, PublicKey) 613selectKey :: TransportCrypto -> OnionMessage f -> OnionDestination r -> IO (SecretKey, PublicKey)
603selectKey crypto 614selectKey crypto _ rpath@(OnionDestination (AnnouncingAlias pkey) _ _)
604 (OnionAnnounce a@Assym { assymData = Identity (AnnounceRequest _ pkey akey, _) }) 615 = atomically $ do ks <- filter (\(sk,pk) -> pk == id2key pkey)
605 rpath 616 <$> readTVar (userKeys crypto)
606 | (akey /= zeroID) = atomically $ do 617 maybe (return $ aliasKey crypto rpath)
607 ks <- filter (\(sk,pk) -> pk == id2key pkey) 618 return
608 <$> readTVar (userKeys crypto) 619 (listToMaybe ks)
609 maybe (return $ aliasKey crypto rpath)
610 return
611 (listToMaybe ks)
612selectKey crypto msg rpath = return $ aliasKey crypto rpath 620selectKey crypto msg rpath = return $ aliasKey crypto rpath
613 621
614encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (OnionMessage Encrypted, OnionDestination r) 622encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (OnionMessage Encrypted, OnionDestination r)
615encrypt crypto msg rpath = do 623encrypt crypto msg rpath = do
616 (skey,pkey) <- selectKey crypto msg rpath 624 (skey,pkey) <- selectKey crypto msg rpath -- source key
617 let skey = fst $ aliasKey crypto rpath 625 let okey = onionKey rpath -- destination key
618
619 -- The OnionToMe case shouldn't happen, but we'll use our own public
620 -- key in this situation.
621 okey = fromMaybe (transportPublic crypto) $ onionKey rpath
622 return ( transcode ( (. (runIdentity . either id assymData)) 626 return ( transcode ( (. (runIdentity . either id assymData))
623 . encryptMessage skey okey) 627 . encryptMessage skey okey)
624 msg 628 msg
@@ -632,11 +636,13 @@ encryptMessage skey destKey n a = ToxCrypto.encrypt secret plain
632 plain = encodePlain a 636 plain = encodePlain a
633 637
634decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r)) 638decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r))
635decrypt crypto msg addr = return $ do 639decrypt crypto msg addr = do
636 msg <- sequenceMessage $ transcode (\n -> decryptMessage (aliasKey crypto addr) n . left (senderkey addr)) msg 640 (skey,pkey) <- selectKey crypto msg addr
641 return $ do
642 msg <- sequenceMessage $ transcode (\n -> decryptMessage (skey,pkey) n . left (senderkey addr)) msg
637 Right (msg, addr) 643 Right (msg, addr)
638 644
639senderkey :: OnionDestination r -> t -> (Maybe PublicKey, t) 645senderkey :: OnionDestination r -> t -> (PublicKey, t)
640senderkey addr e = (onionKey addr, e) 646senderkey addr e = (onionKey addr, e)
641 647
642aliasKey :: TransportCrypto -> OnionDestination r -> (SecretKey,PublicKey) 648aliasKey :: TransportCrypto -> OnionDestination r -> (SecretKey,PublicKey)
@@ -649,17 +655,14 @@ dhtKey crypto = (transportSecret &&& transportPublic) crypto
649decryptMessage :: Serialize x => 655decryptMessage :: Serialize x =>
650 (SecretKey,PublicKey) 656 (SecretKey,PublicKey)
651 -> Nonce24 657 -> Nonce24
652 -> Either (Maybe PublicKey, Encrypted x) 658 -> Either (PublicKey, Encrypted x)
653 (Assym (Encrypted x)) 659 (Assym (Encrypted x))
654 -> (Either String ∘ Identity) x 660 -> (Either String ∘ Identity) x
655decryptMessage crypto n arg 661decryptMessage crypto n arg = plain $ ToxCrypto.decrypt secret e
656 | Just secret <- msecret = plain $ ToxCrypto.decrypt secret e
657 | otherwise = Composed $ Left "decryptMessage: Unknown sender"
658 where 662 where
659 msecret = do sender <- mkey 663 secret = computeSharedSecret (fst crypto) sender n
660 Just $ computeSharedSecret (fst crypto) sender n 664 (sender,e) = either id (senderKey &&& assymData) arg
661 (mkey,e) = either id (Just . senderKey &&& assymData) arg 665 plain = Composed . fmap Identity . (>>= decodePlain)
662 plain = Composed . fmap Identity . (>>= decodePlain)
663 666
664 667
665sequenceMessage :: Applicative m => OnionMessage (m ∘ f) -> m (OnionMessage f) 668sequenceMessage :: Applicative m => OnionMessage (m ∘ f) -> m (OnionMessage f)
@@ -751,4 +754,4 @@ encodeDataToRoute :: TransportCrypto
751encodeDataToRoute crypto (dta, Rendezvous pub ni) 754encodeDataToRoute crypto (dta, Rendezvous pub ni)
752 = Just ( OnionToRoute pub -- Public key of destination node 755 = Just ( OnionToRoute pub -- Public key of destination node
753 dta 756 dta
754 , OnionDestination ni Nothing ) 757 , OnionDestination SearchingAlias ni Nothing )