summaryrefslogtreecommitdiff
path: root/src/Network/Tox/Crypto/Handlers.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2018-06-18 21:04:20 -0400
committerjoe <joe@jerkface.net>2018-06-18 21:04:20 -0400
commit2051912a76c7b6aedbda60f58dd37c39344470ec (patch)
tree9fe1a8820f15e0a70176851f9181d7dff1528b96 /src/Network/Tox/Crypto/Handlers.hs
parent772f6547a40eb6a3a1dd76befb691f9160ed2d7a (diff)
Factored Network.Tox.Handshake out of *.Crypto.Handlers.
Diffstat (limited to 'src/Network/Tox/Crypto/Handlers.hs')
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs103
1 files changed, 5 insertions, 98 deletions
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index 58b2b09a..c5c17e4e 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -58,6 +58,7 @@ import Text.Printf
58import Data.Bool 58import Data.Bool
59import Connection (Status(..), Policy(..)) 59import Connection (Status(..), Policy(..))
60import Network.Tox.ContactInfo 60import Network.Tox.ContactInfo
61import Network.Tox.Handshake
61 62
62-- | This type indicates the progress of a tox encrypted friend link 63-- | This type indicates the progress of a tox encrypted friend link
63-- connection. Two scenarios are illustrated below. The parenthesis show the 64-- connection. Two scenarios are illustrated below. The parenthesis show the
@@ -465,37 +466,6 @@ newSessionsState crypto unrechook hooks = do
465 , listenerIDSupply = lsupplyVar 466 , listenerIDSupply = lsupplyVar
466 } 467 }
467 468
468data HandshakeParams
469 = HParam
470 { hpTheirBaseNonce :: Maybe Nonce24 -- ignore and generate your own
471 , hpOtherCookie :: Cookie Encrypted
472 , hpTheirSessionKeyPublic :: Maybe PublicKey
473 , hpMySecretKey :: SecretKey
474 , hpCookieRemotePubkey :: PublicKey
475 , hpCookieRemoteDhtkey :: PublicKey
476 }
477
478newHandShakeData :: POSIXTime -> TransportCrypto -> Nonce24 -> HandshakeParams -> SockAddr -> PublicKey -> STM (Maybe HandshakeData)
479newHandShakeData timestamp crypto basenonce (HParam {hpOtherCookie,hpMySecretKey,hpCookieRemotePubkey,hpCookieRemoteDhtkey}) addr mySessionPublic
480 = do
481 freshCookie
482 <- case nodeInfo (key2id hpCookieRemoteDhtkey) addr of
483 Right nodeinfo -> Just <$> createCookieSTM timestamp crypto nodeinfo hpCookieRemotePubkey
484 Left er -> return Nothing
485 let hinit = hashInit
486 Cookie n24 encrypted = hpOtherCookie
487 hctx = hashUpdate hinit n24
488 hctx' = hashUpdate hctx encrypted
489 digest = hashFinalize hctx'
490 return $
491 fmap (\freshCookie' ->
492 HandshakeData
493 { baseNonce = basenonce
494 , sessionKey = mySessionPublic
495 , cookieHash = digest
496 , otherCookie = freshCookie'
497 }) freshCookie
498
499type XMessage = CryptoMessage -- todo 469type XMessage = CryptoMessage -- todo
500 470
501-- THIS Would work if not for the IO shared secret cache... 471-- THIS Would work if not for the IO shared secret cache...
@@ -588,18 +558,11 @@ freshCryptoSession sessions
588 then InProgress AwaitingSessionPacket 558 then InProgress AwaitingSessionPacket
589 else InProgress AwaitingHandshake) 559 else InProgress AwaitingHandshake)
590 ncTheirBaseNonce0 <- newTVar (frmMaybe mbtheirBaseNonce) 560 ncTheirBaseNonce0 <- newTVar (frmMaybe mbtheirBaseNonce)
591 n24 <- transportNewNonce crypto
592 state <- ($ n24) <$> lookupNonceFunctionSTM timestamp crypto key remotePublicKey
593 newBaseNonce <- transportNewNonce crypto 561 newBaseNonce <- transportNewNonce crypto
594 mbMyhandshakeData <- newHandShakeData timestamp crypto newBaseNonce hp addr (toPublic newsession) 562 mbMyhandshakeData <- case nodeInfo (key2id $ hpCookieRemoteDhtkey hp) addr of
595 let encodeHandshake myhandshakeData = let plain = encodePlain myhandshakeData 563 Right nodeinfo -> Just <$> newHandShakeData timestamp crypto newBaseNonce hp nodeinfo (toPublic newsession)
596 -- state = computeSharedSecret key remoteDhtPublicKey n24 564 Left er -> return Nothing -- Unable to send handshake to non-internet socket!
597 encrypted = encrypt state plain 565 myhandshake <- mapM (encodeHandshake timestamp crypto key remotePublicKey otherCookie) mbMyhandshakeData
598 in Handshake { handshakeCookie = otherCookie
599 , handshakeNonce = n24
600 , handshakeData = encrypted
601 }
602 let myhandshake= encodeHandshake <$> mbMyhandshakeData
603 ncHandShake0 <- newTVar (frmMaybe myhandshake) 566 ncHandShake0 <- newTVar (frmMaybe myhandshake)
604 ncMyPacketNonce0 <- newTVar newBaseNonce 567 ncMyPacketNonce0 <- newTVar newBaseNonce
605 cookie0 <- newTVar (HaveCookie otherCookie) 568 cookie0 <- newTVar (HaveCookie otherCookie)
@@ -874,62 +837,6 @@ updateCryptoSession sessions addr newsession timestamp hp session handshake = do
874 writeTVar (ncState session) {-Accepted-}(InProgress AwaitingSessionPacket) 837 writeTVar (ncState session) {-Accepted-}(InProgress AwaitingSessionPacket)
875 return (Nothing,return ()) 838 return (Nothing,return ())
876 839
877anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1)
878anyRight e [] f = return $ Left e
879anyRight e (x:xs) f = f x >>= either (const $ anyRight e xs f) (return . Right)
880
881decryptHandshake :: TransportCrypto -> Handshake Encrypted -> IO (Either String (SecretKey,Handshake Identity))
882decryptHandshake crypto hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do
883 (ukeys,symkey) <- atomically $ (,) <$> userKeys crypto
884 <*> transportSymmetric crypto
885 let seckeys = map fst ukeys
886 dput XNetCrypto "decryptHandshake: trying the following keys:"
887 now <- getPOSIXTime
888 forM_ seckeys $ \k -> dput XNetCrypto $ " " ++ show (key2id . toPublic $ k)
889 fmap join . sequence $ do -- Either Monad
890 cd@(CookieData cookieTime remotePubkey remoteDhtkey) <- decodePlain =<< decryptSymmetric symkey n24 ecookie
891 Right $ do -- IO Monad
892 decrypted <- anyRight "missing key" seckeys $ \key -> do
893 dput XNetCrypto $ "(NetCrypto)handshakeH: remotePubkey = " ++ show (key2id $ remotePubkey)
894 dput XNetCrypto $ "(NetCrypto)handshakeH: nonce24 = " ++ show nonce24
895 secret <- lookupSharedSecret crypto key remotePubkey nonce24
896 let step1 = decrypt secret encrypted
897 case step1 of
898 Left s -> do
899 dput XNetCrypto $ "(NetCrypto)handshakeH: (decrypt) " ++ s
900 return (Left s)
901 Right pln -> do
902 case decodePlain pln of
903 Left s -> do
904 dput XNetCrypto $ "(NetCrypto)handshakeH: (decodePlain) " ++ s
905 return (Left s)
906 Right x -> return (Right (key,x))
907 return $ do -- Either Monad
908 (key,hsdata@HandshakeData { baseNonce, sessionKey, cookieHash, otherCookie }) <- decrypted
909 left (asTypeOf "cookie too old") $ guard (now - fromIntegral cookieTime < 15)
910 let hinit = hashInit
911 hctx = hashUpdate hinit n24
912 hctx' = hashUpdate hctx ecookie
913 digest = hashFinalize hctx'
914 left (asTypeOf "cookie digest mismatch") $ guard (cookieHash == digest)
915 return ( key
916 , hshake { handshakeCookie = Cookie n24 (pure cd)
917 , handshakeData = pure hsdata
918 } )
919
920toHandshakeParams :: (SecretKey, Handshake Identity) -> HandshakeParams
921toHandshakeParams (key,hs)
922 = let hd = runIdentity $ handshakeData hs
923 Cookie _ cd0 = handshakeCookie hs
924 CookieData _ remotePublicKey remoteDhtPublicKey = runIdentity cd0
925 in HParam { hpTheirBaseNonce = Just $ baseNonce hd
926 , hpOtherCookie = otherCookie hd
927 , hpTheirSessionKeyPublic = Just $ sessionKey hd
928 , hpMySecretKey = key
929 , hpCookieRemotePubkey = remotePublicKey
930 , hpCookieRemoteDhtkey = remoteDhtPublicKey
931 }
932
933handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a) 840handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a)
934handshakeH sessions addrRaw hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do 841handshakeH sessions addrRaw hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do
935 let addr = either id id $ either4or6 addrRaw 842 let addr = either id id $ either4or6 addrRaw