summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index 56fb4dcf..2a1461f2 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -9,6 +9,7 @@ import Network.Tox.Crypto.Transport
9import Network.Tox.DHT.Transport (Cookie(..),CookieData(..), CookieRequest(..), NoSpam(..)) 9import Network.Tox.DHT.Transport (Cookie(..),CookieData(..), CookieRequest(..), NoSpam(..))
10import Network.Tox.DHT.Handlers (Client, cookieRequest, createCookie ) 10import Network.Tox.DHT.Handlers (Client, cookieRequest, createCookie )
11import Crypto.Tox 11import Crypto.Tox
12import Control.Arrow
12import Control.Concurrent.STM 13import Control.Concurrent.STM
13import Control.Concurrent.STM.TMChan 14import Control.Concurrent.STM.TMChan
14import Network.Address 15import Network.Address
@@ -711,6 +712,44 @@ anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1)
711anyRight e [] f = return $ Left e 712anyRight e [] f = return $ Left e
712anyRight e (x:xs) f = f x >>= either (const $ anyRight e xs f) (return . Right) 713anyRight e (x:xs) f = f x >>= either (const $ anyRight e xs f) (return . Right)
713 714
715decryptHandshake :: TransportCrypto -> Handshake Encrypted -> IO (Either String (Handshake Identity))
716decryptHandshake crypto hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do
717 (ukeys,symkey) <- atomically $ (,) <$> userKeys crypto
718 <*> transportSymmetric crypto
719 let seckeys = map fst ukeys
720 dput XNetCrypto "decryptHandshake: trying the following keys:"
721 now <- getPOSIXTime
722 forM_ seckeys $ \k -> dput XNetCrypto $ " " ++ show (key2id . toPublic $ k)
723 fmap join . sequence $ do -- Either Monad
724 cd@(CookieData cookieTime remotePubkey remoteDhtkey) <- decodePlain =<< decryptSymmetric symkey n24 ecookie
725 Right $ do -- IO Monad
726 decrypted <- anyRight "missing key" seckeys $ \key -> do
727 dput XNetCrypto $ "(NetCrypto)handshakeH: remotePubkey = " ++ show (key2id $ remotePubkey)
728 dput XNetCrypto $ "(NetCrypto)handshakeH: nonce24 = " ++ show nonce24
729 secret <- lookupSharedSecret crypto key remotePubkey nonce24
730 let step1 = decrypt secret encrypted
731 case step1 of
732 Left s -> do
733 dput XNetCrypto $ "(NetCrypto)handshakeH: (decrypt) " ++ s
734 return (Left s)
735 Right pln -> do
736 case decodePlain pln of
737 Left s -> do
738 dput XNetCrypto $ "(NetCrypto)handshakeH: (decodePlain) " ++ s
739 return (Left s)
740 Right x -> return (Right (key,x))
741 return $ do -- Either Monad
742 (key,hsdata@HandshakeData { baseNonce, sessionKey, cookieHash, otherCookie }) <- decrypted
743 left (asTypeOf "cookie too old") $ guard (now - fromIntegral cookieTime < 15)
744 let hinit = hashInit
745 hctx = hashUpdate hinit n24
746 hctx' = hashUpdate hctx ecookie
747 digest = hashFinalize hctx'
748 left (asTypeOf "cookie digest mismatch") $ guard (cookieHash == digest)
749 return hshake { handshakeCookie = Cookie n24 (pure cd)
750 , handshakeData = pure hsdata
751 }
752
714handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a) 753handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a)
715handshakeH sessions addr hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do 754handshakeH sessions addr hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do
716 dput XNetCrypto ("RECIEVED HANDSHAKE from " ++ show addr) 755 dput XNetCrypto ("RECIEVED HANDSHAKE from " ++ show addr)