summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-11-05 01:25:36 -0500
committerjoe <joe@jerkface.net>2017-11-05 01:25:36 -0500
commit8039d812b7ea8ae566f8873452ac34597336ddfc (patch)
tree2b28e0b1ea90a4eb1122c723b82e580873a33cde /src
parentcb7337dc453131864f2692ef202230f2e7ae740b (diff)
Adapted computeSharedSecret to a side-effecting interface.
This is to ready the tree for a memoizing cache of shared secrets.
Diffstat (limited to 'src')
-rw-r--r--src/Crypto/Tox.hs10
-rw-r--r--src/Network/Tox.hs2
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs21
-rw-r--r--src/Network/Tox/DHT/Transport.hs37
-rw-r--r--src/Network/Tox/Onion/Transport.hs178
-rw-r--r--src/Network/Tox/Transport.hs2
6 files changed, 147 insertions, 103 deletions
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs
index 307a5db5..37725aea 100644
--- a/src/Crypto/Tox.hs
+++ b/src/Crypto/Tox.hs
@@ -29,7 +29,8 @@ module Crypto.Tox
29 , Plain 29 , Plain
30 , encodePlain 30 , encodePlain
31 , decodePlain 31 , decodePlain
32 , computeSharedSecret 32 -- , computeSharedSecret
33 , lookupSharedSecret
33 , encrypt 34 , encrypt
34 , decrypt 35 , decrypt
35 , Nonce8(..) 36 , Nonce8(..)
@@ -98,6 +99,8 @@ newtype Encrypted8 a = E8 (Encrypted (a,Nonce8))
98 99
99newtype (f ∘ g) x = Composed { uncomposed :: f (g x) } 100newtype (f ∘ g) x = Composed { uncomposed :: f (g x) }
100 101
102infixr ∘
103
101newtype Auth = Auth Poly1305.Auth deriving (Eq, ByteArrayAccess) 104newtype Auth = Auth Poly1305.Auth deriving (Eq, ByteArrayAccess)
102instance Ord Auth where 105instance Ord Auth where
103 compare (Auth a) (Auth b) = comparing (BA.convert :: Poly1305.Auth -> Bytes) a b 106 compare (Auth a) (Auth b) = comparing (BA.convert :: Poly1305.Auth -> Bytes) a b
@@ -246,6 +249,11 @@ computeSharedSecret sk recipient nonce = State hash crypt
246 -- Since rs is 32 bytes, this pattern should never fail... 249 -- Since rs is 32 bytes, this pattern should never fail...
247 Cryptonite.CryptoPassed hash = Poly1305.initialize rs 250 Cryptonite.CryptoPassed hash = Poly1305.initialize rs
248 251
252lookupSharedSecret :: TransportCrypto -> SecretKey -> PublicKey -> Nonce24 -> IO State
253lookupSharedSecret crypto sk recipient nonce = do
254 -- TODO
255 return $ computeSharedSecret sk recipient nonce
256
249hsalsa20 :: (ByteArrayAccess t, ByteArrayAccess t1) => t1 -> t -> BA.ScrubbedBytes 257hsalsa20 :: (ByteArrayAccess t, ByteArrayAccess t1) => t1 -> t -> BA.ScrubbedBytes
250hsalsa20 k n = BA.append a b 258hsalsa20 k n = BA.append a b
251 where 259 where
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 7179e3c2..40d17a07 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -310,7 +310,7 @@ newTox keydb addr mbSessionsState suppliedDHTKey = do
310 let ignoreErrors _ = return () -- Set this to (hPutStrLn stderr) to debug onion route building. 310 let ignoreErrors _ = return () -- Set this to (hPutStrLn stderr) to debug onion route building.
311 orouter <- newOnionRouter ignoreErrors 311 orouter <- newOnionRouter ignoreErrors
312 (dhtcrypt,onioncrypt,dtacrypt,cryptonet) <- toxTransport crypto orouter lookupClose udp 312 (dhtcrypt,onioncrypt,dtacrypt,cryptonet) <- toxTransport crypto orouter lookupClose udp
313 let dhtnet0 = layerTransport (DHT.decrypt crypto) (DHT.encrypt crypto) dhtcrypt 313 let dhtnet0 = layerTransportM (DHT.decrypt crypto) (DHT.encrypt crypto) dhtcrypt
314 dhtclient <- newClient drg dhtnet0 DHT.classify (myAddr routing) (DHT.handlers crypto routing) id 314 dhtclient <- newClient drg dhtnet0 DHT.classify (myAddr routing) (DHT.handlers crypto routing) id
315 $ \client net -> onInbound (DHT.updateRouting client routing orouter) net 315 $ \client net -> onInbound (DHT.updateRouting client routing orouter) net
316 316
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index b8e99d2d..ac3d1ef0 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -94,9 +94,9 @@ freshCryptoSession sessions
94 ncState0 <- atomically $ newTVar Accepted 94 ncState0 <- atomically $ newTVar Accepted
95 ncTheirBaseNonce0 <- atomically $ newTVar theirBaseNonce 95 ncTheirBaseNonce0 <- atomically $ newTVar theirBaseNonce
96 n24 <- atomically $ transportNewNonce crypto 96 n24 <- atomically $ transportNewNonce crypto
97 state <- lookupSharedSecret crypto key remoteDhtPublicKey n24
97 let myhandshakeData = newHandShakeData crypto hp 98 let myhandshakeData = newHandShakeData crypto hp
98 plain = encodePlain myhandshakeData 99 plain = encodePlain myhandshakeData
99 state = computeSharedSecret key remoteDhtPublicKey n24
100 encrypted = encrypt state plain 100 encrypted = encrypt state plain
101 myhandshake = Handshake { handshakeCookie = otherCookie 101 myhandshake = Handshake { handshakeCookie = otherCookie
102 , handshakeNonce = n24 102 , handshakeNonce = n24
@@ -150,14 +150,19 @@ cryptoNetHandler sessions addr (NetHandshake (Handshake (Cookie n24 ecookie) non
150 -- Handle Handshake Message 150 -- Handle Handshake Message
151 let crypto = transportCrypto sessions 151 let crypto = transportCrypto sessions
152 allsessions = netCryptoSessions sessions 152 allsessions = netCryptoSessions sessions
153 anyRight xs f = foldr1 (<|>) $ map f xs 153 anyRight [] f = return $ Left "missing key"
154 anyRight (x:xs) f = f x >>= either (const $ anyRight xs f) (return . Right)
154 seckeys <- map fst <$> atomically (readTVar (userKeys crypto)) 155 seckeys <- map fst <$> atomically (readTVar (userKeys crypto))
155 symkey <- atomically $ transportSymmetric crypto 156 symkey <- atomically $ transportSymmetric crypto
156 now <- getPOSIXTime 157 now <- getPOSIXTime
157 let lr = do -- Either Monad 158 lr <- fmap join . sequence $ do -- Either Monad
158 (CookieData cookieTime remotePubkey remoteDhtkey) <- (decodePlain =<< decryptSymmetric symkey n24 ecookie) 159 (CookieData cookieTime remotePubkey remoteDhtkey) <- (decodePlain =<< decryptSymmetric symkey n24 ecookie)
159 (key,HandshakeData { baseNonce, sessionKey, cookieHash, otherCookie }) 160 Right $ do -- IO Monad
160 <- anyRight seckeys $ \key -> (key,) <$> (decodePlain =<< decrypt (computeSharedSecret key remotePubkey nonce24) encrypted) 161 decrypted <- anyRight seckeys $ \key -> do
162 secret <- lookupSharedSecret crypto key remotePubkey nonce24
163 return $ (key,) <$> (decodePlain =<< decrypt secret encrypted)
164 return $ do -- Either Monad
165 (key,HandshakeData { baseNonce, sessionKey, cookieHash, otherCookie }) <- decrypted
161 -- check cookie time < 15 seconds ago 166 -- check cookie time < 15 seconds ago
162 guard (now - fromIntegral cookieTime < 15) 167 guard (now - fromIntegral cookieTime < 15)
163 -- cookie hash is valid? sha512 of ecookie 168 -- cookie hash is valid? sha512 of ecookie
@@ -208,9 +213,11 @@ cryptoNetHandler sessions addr (NetCrypto (CryptoPacket nonce16 encrypted)) = do
208 let diff :: Word16 213 let diff :: Word16
209 diff = nonce16 - fromIntegral (last2Bytes theirBaseNonce) -- truncating to Word16 214 diff = nonce16 - fromIntegral (last2Bytes theirBaseNonce) -- truncating to Word16
210 tempNonce <- addtoNonce24 theirBaseNonce (fromIntegral diff) -- expanding to Word 215 tempNonce <- addtoNonce24 theirBaseNonce (fromIntegral diff) -- expanding to Word
211 let lr = do -- Either Monad -- 216 lr <- fmap join $ sequence $ do -- Either Monad --
212 pubkey <- maybeToEither ncTheirSessionPublic 217 pubkey <- maybeToEither ncTheirSessionPublic
213 decodePlain =<< decrypt (computeSharedSecret ncSessionSecret pubkey tempNonce) encrypted 218 Right $ do -- IO Monad
219 secret <- lookupSharedSecret crypto ncSessionSecret pubkey tempNonce
220 return $ decodePlain =<< decrypt secret encrypted
214 case lr of 221 case lr of
215 Left _ -> return Nothing -- decryption failed, ignore packet 222 Left _ -> return Nothing -- decryption failed, ignore packet
216 Right cd@(CryptoData {bufferStart, bufferEnd, bufferData=cm}) -> do -- decryption succeeded, 223 Right cd@(CryptoData {bufferStart, bufferEnd, bufferData=cm}) -> do -- decryption succeeded,
diff --git a/src/Network/Tox/DHT/Transport.hs b/src/Network/Tox/DHT/Transport.hs
index 736e84d1..bd108276 100644
--- a/src/Network/Tox/DHT/Transport.hs
+++ b/src/Network/Tox/DHT/Transport.hs
@@ -426,34 +426,37 @@ forwardDHTRequests crypto closeLookup dht = dht { awaitMessage = await' }
426 await' pass 426 await' pass
427 m -> pass m 427 m -> pass m
428 428
429encrypt :: TransportCrypto -> DHTMessage ((,) Nonce8) -> NodeInfo -> (DHTMessage Encrypted8, NodeInfo) 429encrypt :: TransportCrypto -> DHTMessage ((,) Nonce8) -> NodeInfo -> IO (DHTMessage Encrypted8, NodeInfo)
430encrypt crypto msg ni = ( transcode (encryptMessage crypto (id2key $ nodeId ni)) msg 430encrypt crypto msg ni = do
431 , ni ) 431 let cipher n plain = Composed $ encryptMessage crypto (id2key $ nodeId ni) n plain
432 m <- sequenceMessage $ transcode cipher msg
433 return (m, ni)
432 434
433encryptMessage :: Serialize a => 435encryptMessage :: Serialize a =>
434 TransportCrypto -> 436 TransportCrypto ->
435 PublicKey -> 437 PublicKey ->
436 Nonce24 -> Either (Nonce8,a) (Asymm (Nonce8,a)) -> Encrypted8 a 438 Nonce24 -> Either (Nonce8,a) (Asymm (Nonce8,a)) -> IO (Encrypted8 a)
437encryptMessage crypto destKey n arg = E8 $ ToxCrypto.encrypt secret plain 439encryptMessage crypto destKey n arg = do
438 where 440 let plain = encodePlain $ swap $ either id asymmData arg
439 secret = computeSharedSecret (transportSecret crypto) destKey n 441 secret <- lookupSharedSecret crypto (transportSecret crypto) destKey n
440 plain = encodePlain $ swap $ either id asymmData arg 442 return $ E8 $ ToxCrypto.encrypt secret plain
441 443
442decrypt :: TransportCrypto -> DHTMessage Encrypted8 -> NodeInfo -> Either String (DHTMessage ((,) Nonce8), NodeInfo) 444decrypt :: TransportCrypto -> DHTMessage Encrypted8 -> NodeInfo -> IO (Either String (DHTMessage ((,) Nonce8), NodeInfo))
443decrypt crypto msg ni = do 445decrypt crypto msg ni = do
444 msg' <- sequenceMessage $ transcode (\n -> decryptMessage crypto n . left ((,) $ id2key $ nodeId ni)) msg 446 let decipher n c = Composed $ decryptMessage crypto n . left ((,) $ id2key $ nodeId ni) $ c
445 return (msg', ni) 447 msg' <- sequenceMessage $ transcode decipher msg
448 return $ fmap (, ni) $ sequenceMessage msg'
446 449
447decryptMessage :: Serialize x => 450decryptMessage :: Serialize x =>
448 TransportCrypto 451 TransportCrypto
449 -> Nonce24 452 -> Nonce24
450 -> Either (PublicKey, Encrypted8 x) (Asymm (Encrypted8 x)) 453 -> Either (PublicKey, Encrypted8 x) (Asymm (Encrypted8 x))
451 -> (Either String ∘ ((,) Nonce8)) x 454 -> IO ((Either String ∘ ((,) Nonce8)) x)
452decryptMessage crypto n arg = plain8 $ ToxCrypto.decrypt secret e 455decryptMessage crypto n arg = do
453 where 456 let (remotekey,E8 e) = either id (senderKey &&& asymmData) arg
454 secret = computeSharedSecret (transportSecret crypto) remotekey n 457 plain8 = Composed . fmap swap . (>>= decodePlain)
455 (remotekey,E8 e) = either id (senderKey &&& asymmData) arg 458 secret <- lookupSharedSecret crypto (transportSecret crypto) remotekey n
456 plain8 = Composed . fmap swap . (>>= decodePlain) 459 return $ plain8 $ ToxCrypto.decrypt secret e
457 460
458sequenceMessage :: Applicative m => DHTMessage (m ∘ f) -> m (DHTMessage f) 461sequenceMessage :: Applicative m => DHTMessage (m ∘ f) -> m (DHTMessage f)
459sequenceMessage (DHTPing asym) = fmap DHTPing $ sequenceA $ fmap uncomposed asym 462sequenceMessage (DHTPing asym) = fmap DHTPing $ sequenceA $ fmap uncomposed asym
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index 5b7aad0b..539e7cee 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -231,19 +231,21 @@ routeId :: NodeId -> RouteId
231routeId nid = RouteId $ mod (hash nid) 12 231routeId nid = RouteId $ mod (hash nid) 12
232 232
233 233
234encodeOnionAddr :: (NodeInfo -> RouteId -> IO (Maybe OnionRoute)) 234encodeOnionAddr :: TransportCrypto
235 -> (NodeInfo -> RouteId -> IO (Maybe OnionRoute))
235 -> (OnionMessage Encrypted,OnionDestination RouteId) 236 -> (OnionMessage Encrypted,OnionDestination RouteId)
236 -> IO (Maybe (ByteString, SockAddr)) 237 -> IO (Maybe (ByteString, SockAddr))
237encodeOnionAddr _ (msg,OnionToOwner ni p) = 238encodeOnionAddr crypto _ (msg,OnionToOwner ni p) =
238 return $ Just ( runPut $ putResponse (OnionResponse p msg) 239 return $ Just ( runPut $ putResponse (OnionResponse p msg)
239 , nodeAddr ni ) 240 , nodeAddr ni )
240encodeOnionAddr getRoute (msg,OnionDestination x ni Nothing) = do 241encodeOnionAddr crypto getRoute (msg,OnionDestination x ni Nothing) = do
241 encodeOnionAddr getRoute (msg,OnionDestination x ni (Just $ routeId $ nodeId ni) ) 242 encodeOnionAddr crypto getRoute (msg,OnionDestination x ni (Just $ routeId $ nodeId ni) )
242 -- hPutStrLn stderr $ "ONION encode missing routeid" 243 -- hPutStrLn stderr $ "ONION encode missing routeid"
243 -- return Nothing 244 -- return Nothing
244encodeOnionAddr getRoute (msg,OnionDestination _ ni (Just rid)) = do 245encodeOnionAddr crypto getRoute (msg,OnionDestination _ ni (Just rid)) = do
245 let go route = do 246 let go route = do
246 return ( runPut $ putRequest $ wrapForRoute msg ni route 247 req <- wrapForRoute crypto msg ni route
248 return ( runPut $ putRequest req
247 , nodeAddr $ routeNodeA route) 249 , nodeAddr $ routeNodeA route)
248 mapM' f x = do 250 mapM' f x = do
249 let _ = x :: Maybe OnionRoute 251 let _ = x :: Maybe OnionRoute
@@ -482,7 +484,8 @@ handleOnionRequest proxy crypto saddr udp kont (OnionRequest nonce msg rpath) =
482 hPutStrLn stderr $ "handleOnionRequest " ++ show n 484 hPutStrLn stderr $ "handleOnionRequest " ++ show n
483 (sym, snonce) <- atomically ( (,) <$> transportSymmetric crypto 485 (sym, snonce) <- atomically ( (,) <$> transportSymmetric crypto
484 <*> transportNewNonce crypto ) 486 <*> transportNewNonce crypto )
485 case peelOnion crypto nonce msg of 487 peeled <- peelOnion crypto nonce msg
488 case peeled of
486 Left e -> do 489 Left e -> do
487 -- todo report encryption error 490 -- todo report encryption error
488 hPutStrLn stderr $ unwords [ "peelOnion:", show n, either show show (either4or6 saddr), e] 491 hPutStrLn stderr $ unwords [ "peelOnion:", show n, either show show (either4or6 saddr), e]
@@ -505,9 +508,9 @@ peelOnion :: Serialize (Addressed (Forwarding n t))
505 => TransportCrypto 508 => TransportCrypto
506 -> Nonce24 509 -> Nonce24
507 -> Forwarding (S n) t 510 -> Forwarding (S n) t
508 -> Either String (Addressed (Forwarding n t)) 511 -> IO (Either String (Addressed (Forwarding n t)))
509peelOnion crypto nonce (Forwarding k fwd) = 512peelOnion crypto nonce (Forwarding k fwd) = do
510 fmap runIdentity $ uncomposed $ decryptMessage (dhtKey crypto) nonce (Right $ Asymm k nonce fwd) 513 fmap runIdentity . uncomposed <$> decryptMessage crypto (dhtKey crypto) nonce (Right $ Asymm k nonce fwd)
511 514
512handleOnionResponse :: (KnownPeanoNat n, Sized (ReturnPath n), Serialize (ReturnPath n)) => proxy (S n) -> TransportCrypto -> SockAddr -> UDPTransport -> IO a -> OnionResponse (S n) -> IO a 515handleOnionResponse :: (KnownPeanoNat n, Sized (ReturnPath n), Serialize (ReturnPath n)) => proxy (S n) -> TransportCrypto -> SockAddr -> UDPTransport -> IO a -> OnionResponse (S n) -> IO a
513handleOnionResponse proxy crypto saddr udp kont (OnionResponse path msg) = do 516handleOnionResponse proxy crypto saddr udp kont (OnionResponse path msg) = do
@@ -662,27 +665,42 @@ selectKey crypto _ rpath@(OnionDestination (AnnouncingAlias skey pkey) _ _)
662 = return (skey, pkey) 665 = return (skey, pkey)
663selectKey crypto msg rpath = return $ aliasKey crypto rpath 666selectKey crypto msg rpath = return $ aliasKey crypto rpath
664 667
665encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (OnionMessage Encrypted, OnionDestination r) 668encrypt :: TransportCrypto
669 -> OnionMessage Identity
670 -> OnionDestination r
671 -> IO (OnionMessage Encrypted, OnionDestination r)
666encrypt crypto msg rpath = do 672encrypt crypto msg rpath = do
667 (skey,pkey) <- selectKey crypto msg rpath -- source key 673 (skey,pkey) <- selectKey crypto msg rpath -- source key
668 let okey = onionKey rpath -- destination key 674 let okey = onionKey rpath -- destination key
669 return ( transcode ( (. (runIdentity . either id asymmData)) 675 encipher1 :: Serialize a => SecretKey -> PublicKey -> Nonce24 -> a -> (IO ∘ Encrypted) a
670 . encryptMessage skey okey) 676 encipher1 sk pk n a = Composed $ do
671 msg 677 secret <- lookupSharedSecret crypto sk pk n
672 , rpath) 678 return $ ToxCrypto.encrypt secret $ encodePlain a
673 679 encipher :: Serialize a => Nonce24 -> Either (Identity a) (Asymm (Identity a)) -> (IO ∘ Encrypted) a
674encryptMessage :: Serialize a => 680 encipher n d = encipher1 skey okey n $ either runIdentity (runIdentity . asymmData) d
675 SecretKey -> PublicKey -> Nonce24 -> a -> Encrypted a 681 m <- sequenceMessage $ transcode encipher msg
676encryptMessage skey destKey n a = ToxCrypto.encrypt secret plain 682 return (m, rpath)
677 where
678 secret = computeSharedSecret skey destKey n
679 plain = encodePlain a
680 683
681decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r)) 684decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r))
682decrypt crypto msg addr = do 685decrypt crypto msg addr = do
683 (skey,pkey) <- selectKey crypto msg addr 686 (skey,pkey) <- selectKey crypto msg addr
687 let decipher1 :: Serialize a =>
688 TransportCrypto -> SecretKey -> PublicKey -> Nonce24
689 -> Either (PublicKey,Encrypted a) (Asymm (Encrypted a))
690 -> (IO ∘ Either String ∘ Identity) a
691 decipher1 crypto k pk n d = Composed $ do
692 secret <- lookupSharedSecret crypto k pk n
693 let ciphered = either snd asymmData d
694 return $ Composed $ do
695 plain <- ToxCrypto.decrypt secret ciphered
696 Identity <$> decodePlain plain
697 decipher :: Serialize a
698 => Nonce24 -> Either (Encrypted a) (Asymm (Encrypted a))
699 -> (IO ∘ Either String ∘ Identity) a
700 decipher = (\n -> decipher1 crypto skey pkey n . left (senderkey addr))
701 foo <- sequenceMessage $ transcode decipher msg
684 return $ do 702 return $ do
685 msg <- sequenceMessage $ transcode (\n -> decryptMessage (skey,pkey) n . left (senderkey addr)) msg 703 msg <- sequenceMessage foo
686 Right (msg, addr) 704 Right (msg, addr)
687 705
688senderkey :: OnionDestination r -> t -> (PublicKey, t) 706senderkey :: OnionDestination r -> t -> (PublicKey, t)
@@ -696,16 +714,17 @@ dhtKey :: TransportCrypto -> (SecretKey,PublicKey)
696dhtKey crypto = (transportSecret &&& transportPublic) crypto 714dhtKey crypto = (transportSecret &&& transportPublic) crypto
697 715
698decryptMessage :: Serialize x => 716decryptMessage :: Serialize x =>
699 (SecretKey,PublicKey) 717 TransportCrypto
718 -> (SecretKey,PublicKey)
700 -> Nonce24 719 -> Nonce24
701 -> Either (PublicKey, Encrypted x) 720 -> Either (PublicKey, Encrypted x)
702 (Asymm (Encrypted x)) 721 (Asymm (Encrypted x))
703 -> (Either String ∘ Identity) x 722 -> IO ((Either String ∘ Identity) x)
704decryptMessage crypto n arg = plain $ ToxCrypto.decrypt secret e 723decryptMessage crypto (sk,pk) n arg = do
705 where 724 let (sender,e) = either id (senderKey &&& asymmData) arg
706 secret = computeSharedSecret (fst crypto) sender n 725 plain = Composed . fmap Identity . (>>= decodePlain)
707 (sender,e) = either id (senderKey &&& asymmData) arg 726 secret <- lookupSharedSecret crypto sk sender n
708 plain = Composed . fmap Identity . (>>= decodePlain) 727 return $ plain $ ToxCrypto.decrypt secret e
709 728
710 729
711sequenceMessage :: Applicative m => OnionMessage (m ∘ f) -> m (OnionMessage f) 730sequenceMessage :: Applicative m => OnionMessage (m ∘ f) -> m (OnionMessage f)
@@ -732,37 +751,41 @@ data OnionRoute = OnionRoute
732 , routeNodeC :: NodeInfo 751 , routeNodeC :: NodeInfo
733 } 752 }
734 753
735wrapForRoute :: OnionMessage Encrypted -> NodeInfo -> OnionRoute -> OnionRequest N0 754wrapForRoute :: TransportCrypto -> OnionMessage Encrypted -> NodeInfo -> OnionRoute -> IO (OnionRequest N0)
736wrapForRoute msg ni r = 755wrapForRoute crypto msg ni r = do
737 -- We needn't use the same nonce value here, but I think it is safe to do so. 756 -- We needn't use the same nonce value here, but I think it is safe to do so.
738 let nonce = msgNonce msg 757 let nonce = msgNonce msg
739 in OnionRequest 758 fwd <- wrapOnion crypto (routeAliasA r)
740 { onionNonce = nonce 759 nonce
741 , onionForward = wrapOnion (routeAliasA r) 760 (id2key . nodeId $ routeNodeA r)
742 nonce 761 (nodeAddr $ routeNodeB r)
743 (id2key . nodeId $ routeNodeA r) 762 =<< wrapOnion crypto (routeAliasB r)
744 (nodeAddr $ routeNodeB r) 763 nonce
745 $ wrapOnion (routeAliasB r) 764 (id2key . nodeId $ routeNodeB r)
746 nonce 765 (nodeAddr $ routeNodeC r)
747 (id2key . nodeId $ routeNodeB r) 766 =<< wrapOnion crypto (routeAliasC r)
748 (nodeAddr $ routeNodeC r) 767 nonce
749 $ wrapOnion (routeAliasC r) 768 (id2key . nodeId $ routeNodeC r)
750 nonce 769 (nodeAddr ni)
751 (id2key . nodeId $ routeNodeC r) 770 (NotForwarded msg)
752 (nodeAddr ni) 771 return OnionRequest
753 $ NotForwarded msg 772 { onionNonce = nonce
754 , pathFromOwner = NoReturnPath 773 , onionForward = fwd
755 } 774 , pathFromOwner = NoReturnPath
775 }
756 776
757wrapOnion :: Serialize (Forwarding n msg) => 777wrapOnion :: Serialize (Forwarding n msg) =>
758 SecretKey 778 TransportCrypto
779 -> SecretKey
759 -> Nonce24 780 -> Nonce24
760 -> PublicKey 781 -> PublicKey
761 -> SockAddr 782 -> SockAddr
762 -> Forwarding n msg 783 -> Forwarding n msg
763 -> Forwarding (S n) msg 784 -> IO (Forwarding (S n) msg)
764wrapOnion skey nonce destkey saddr fwd = 785wrapOnion crypto skey nonce destkey saddr fwd = do
765 Forwarding (toPublic skey) $ encryptMessage skey destkey nonce (Addressed saddr fwd) 786 let plain = encodePlain $ Addressed saddr fwd
787 secret <- lookupSharedSecret crypto skey destkey nonce
788 return $ Forwarding (toPublic skey) $ ToxCrypto.encrypt secret plain
766 789
767 790
768-- TODO 791-- TODO
@@ -827,28 +850,29 @@ parseDataToRoute
827parseDataToRoute crypto (OnionToRouteResponse dta, od) = do 850parseDataToRoute crypto (OnionToRouteResponse dta, od) = do
828 ks <- atomically $ readTVar $ userKeys crypto 851 ks <- atomically $ readTVar $ userKeys crypto
829 852
830 let eOuter = do 853 omsg0 <- decryptMessage crypto (rendezvousSecret crypto,rendezvousPublic crypto)
831 fmap runIdentity 854 (asymmNonce dta)
832 $ uncomposed 855 (Right dta) -- using Asymm{senderKey} as remote key
833 $ decryptMessage (rendezvousSecret crypto,rendezvousPublic crypto) 856 let eOuter = fmap runIdentity $ uncomposed omsg0
834 (asymmNonce dta) 857
835 (Right dta) -- using Asymm{senderKey} as remote key 858 anyRight [] f = return $ Left "parseDataToRoute: no user key"
836 859 anyRight (x:xs) f = f x >>= either (const $ anyRight xs f) (return . Right)
837 -- TODO: We don't currently have a way to look up which user key we 860
838 -- announced using along this onion route. Therefore, for now, we will 861 -- TODO: We don't currently have a way to look up which user key we
839 -- try all our user keys to see if any can decrypt the packet. 862 -- announced using along this onion route. Therefore, for now, we will
840 eInners = flip map ks $ \(sk,pk) -> do 863 -- try all our user keys to see if any can decrypt the packet.
841 dtr <- eOuter 864 eInner <- case eOuter of
842 omsg <- fmap runIdentity 865 Left e -> return $ Left e
843 $ uncomposed 866 Right dtr -> anyRight ks $ \(sk,pk) -> do
844 $ decryptMessage (sk,pk) 867 omsg0 <- decryptMessage crypto
868 (sk,pk)
845 (asymmNonce dta) 869 (asymmNonce dta)
846 (Left (dataFromKey dtr, dataToRoute dtr)) 870 (Left (dataFromKey dtr, dataToRoute dtr))
847 return (pk,dtr,omsg) 871 return $ do
848 872 omsg <- fmap runIdentity . uncomposed $ omsg0
849 eInner = foldr (<|>) (Left "no user key") eInners 873 Right (pk,dtr,omsg)
850 874
851 e = do 875 let e = do
852 (pk,dtr,omsg) <- eInner 876 (pk,dtr,omsg) <- eInner
853 return ( (pk, omsg) 877 return ( (pk, omsg)
854 , AnnouncedRendezvous 878 , AnnouncedRendezvous
@@ -875,10 +899,12 @@ encodeDataToRoute crypto ((me,omsg), AnnouncedRendezvous toxid (Rendezvous pub n
875 let (sk,pk) = case asel of 899 let (sk,pk) = case asel of
876 AnnouncingAlias sk pk -> (sk,pk) 900 AnnouncingAlias sk pk -> (sk,pk)
877 _ -> (onionAliasSecret crypto, onionAliasPublic crypto) 901 _ -> (onionAliasSecret crypto, onionAliasPublic crypto)
878 let plain = DataToRoute { dataFromKey = pk 902 innerSecret <- lookupSharedSecret crypto sk toxid nonce
879 , dataToRoute = encryptMessage sk toxid nonce omsg 903 let plain = encodePlain $ DataToRoute { dataFromKey = pk
880 } 904 , dataToRoute = ToxCrypto.encrypt innerSecret $ encodePlain omsg
881 let dta = encryptMessage (onionAliasSecret crypto) pub nonce plain 905 }
906 outerSecret <- lookupSharedSecret crypto (onionAliasSecret crypto) pub nonce
907 let dta = ToxCrypto.encrypt outerSecret plain
882 hPutStrLn stderr $ unlines 908 hPutStrLn stderr $ unlines
883 [ "encodeDataToRoute me=" ++ show (key2id me) 909 [ "encodeDataToRoute me=" ++ show (key2id me)
884 , " dhtpk=" ++ case omsg of 910 , " dhtpk=" ++ case omsg of
diff --git a/src/Network/Tox/Transport.hs b/src/Network/Tox/Transport.hs
index 01928e56..30df93c8 100644
--- a/src/Network/Tox/Transport.hs
+++ b/src/Network/Tox/Transport.hs
@@ -29,7 +29,7 @@ toxTransport ::
29toxTransport crypto orouter closeLookup udp = do 29toxTransport crypto orouter closeLookup udp = do
30 (dht,udp1) <- partitionTransportM (parseDHTAddr crypto) (fmap Just . encodeDHTAddr) $ forwardOnions crypto udp 30 (dht,udp1) <- partitionTransportM (parseDHTAddr crypto) (fmap Just . encodeDHTAddr) $ forwardOnions crypto udp
31 (onion1,udp2) <- partitionTransportM (parseOnionAddr $ lookupSender orouter) 31 (onion1,udp2) <- partitionTransportM (parseOnionAddr $ lookupSender orouter)
32 (encodeOnionAddr $ lookupRoute orouter) 32 (encodeOnionAddr crypto $ lookupRoute orouter)
33 udp1 33 udp1
34 (dta,onion) <- partitionTransportM (parseDataToRoute crypto) (encodeDataToRoute crypto) onion1 34 (dta,onion) <- partitionTransportM (parseDataToRoute crypto) (encodeDataToRoute crypto) onion1
35 let netcrypto = layerTransport parseNetCrypto encodeNetCrypto udp2 35 let netcrypto = layerTransport parseNetCrypto encodeNetCrypto udp2