diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/Tox/Crypto/Handlers.hs | 39 |
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 | |||
9 | import Network.Tox.DHT.Transport (Cookie(..),CookieData(..), CookieRequest(..), NoSpam(..)) | 9 | import Network.Tox.DHT.Transport (Cookie(..),CookieData(..), CookieRequest(..), NoSpam(..)) |
10 | import Network.Tox.DHT.Handlers (Client, cookieRequest, createCookie ) | 10 | import Network.Tox.DHT.Handlers (Client, cookieRequest, createCookie ) |
11 | import Crypto.Tox | 11 | import Crypto.Tox |
12 | import Control.Arrow | ||
12 | import Control.Concurrent.STM | 13 | import Control.Concurrent.STM |
13 | import Control.Concurrent.STM.TMChan | 14 | import Control.Concurrent.STM.TMChan |
14 | import Network.Address | 15 | import Network.Address |
@@ -711,6 +712,44 @@ anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1) | |||
711 | anyRight e [] f = return $ Left e | 712 | anyRight e [] f = return $ Left e |
712 | anyRight e (x:xs) f = f x >>= either (const $ anyRight e xs f) (return . Right) | 713 | anyRight e (x:xs) f = f x >>= either (const $ anyRight e xs f) (return . Right) |
713 | 714 | ||
715 | decryptHandshake :: TransportCrypto -> Handshake Encrypted -> IO (Either String (Handshake Identity)) | ||
716 | decryptHandshake 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 | |||
714 | handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a) | 753 | handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a) |
715 | handshakeH sessions addr hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do | 754 | handshakeH 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) |