summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames Crayne <jim.crayne@gmail.com>2018-05-31 15:54:51 +0000
committerJames Crayne <jim.crayne@gmail.com>2018-05-31 15:54:51 +0000
commit5edbd08b22598310839bb2ad4a779fc70c5c54b8 (patch)
tree050c8bc589f539f73c3107271ec2c11996d73dd2 /src
parent9045835b429e88e8cbcca2b41c126f664b53d471 (diff)
{fresh,update}CryptoSession are now in STM
Diffstat (limited to 'src')
-rw-r--r--src/Crypto/Tox.hs1
-rw-r--r--src/Network/Tox.hs23
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs210
-rw-r--r--src/Network/Tox/DHT/Handlers.hs18
4 files changed, 129 insertions, 123 deletions
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs
index 864e17df..71aa99c4 100644
--- a/src/Crypto/Tox.hs
+++ b/src/Crypto/Tox.hs
@@ -35,6 +35,7 @@ module Crypto.Tox
35 -- , computeSharedSecret 35 -- , computeSharedSecret
36 , lookupSharedSecret 36 , lookupSharedSecret
37 , lookupNonceFunction 37 , lookupNonceFunction
38 , lookupNonceFunctionSTM
38 , encrypt 39 , encrypt
39 , decrypt 40 , decrypt
40 , Nonce8(..) 41 , Nonce8(..)
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 66a19097..c3e559d7 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -323,22 +323,13 @@ netCryptoWithBackoff millisecs tox myseckey theirpubkey = do
323 , hpTheirBaseNonce = Nothing 323 , hpTheirBaseNonce = Nothing
324 , hpTheirSessionKeyPublic = Nothing 324 , hpTheirSessionKeyPublic = Nothing
325 } 325 }
326 freshCryptoSession (toxCryptoSessions tox) saddr hp 326 newsession <- generateSecretKey
327-- myhandshake <- do 327 timestamp <- getPOSIXTime
328-- n24' <- atomically $ transportNewNonce crypto 328 -- (myhandshakeData,launchThreads) <-
329-- dput XNetCrypto ("Handshake Nonce24: " <> show n24') 329 _ <- atomically $ freshCryptoSession (toxCryptoSessions tox) saddr newsession timestamp hp
330-- newBaseNonce <- atomically $ transportNewNonce crypto 330 -- launchThreads
331-- mbMyhandshakeData <- newHandShakeData crypto newBaseNonce hp saddr 331 -- forM myhandshake $ \response_handshake -> do
332-- forM mbMyhandshakeData $ \hsdata -> do 332 -- sendHandshake sessions addr response_handshake
333-- state <- lookupSharedSecret crypto myseckey theirpubkey n24'
334-- return Handshake { handshakeCookie = cookie
335-- , handshakeNonce = n24'
336-- , handshakeData = encrypt state $ encodePlain hsdata
337-- }
338-- case myhandshake of
339-- Nothing -> hPutStrLn stderr "netCrypto: failed to create HandshakeData." >> return []
340-- Just handshake -> do
341-- sendMessage (toxCrypto tox) saddr (NetHandshake handshake)
342 let secnum :: Double 333 let secnum :: Double
343 secnum = fromIntegral millisecs / 1000000 334 secnum = fromIntegral millisecs / 1000000
344 delay = (millisecs * 5 `div` 4) 335 delay = (millisecs * 5 `div` 4)
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index eabbc9b0..722d8507 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -7,7 +7,7 @@ module Network.Tox.Crypto.Handlers where
7import Network.Tox.NodeId 7import Network.Tox.NodeId
8import Network.Tox.Crypto.Transport 8import 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, createCookieSTM )
11import Crypto.Tox 11import Crypto.Tox
12import Control.Arrow 12import Control.Arrow
13import Control.Concurrent.STM 13import Control.Concurrent.STM
@@ -395,25 +395,18 @@ data HandshakeParams
395 , hpCookieRemoteDhtkey :: PublicKey 395 , hpCookieRemoteDhtkey :: PublicKey
396 } 396 }
397 397
398newHandShakeData :: TransportCrypto -> Nonce24 -> HandshakeParams -> SockAddr -> PublicKey -> IO (Maybe HandshakeData) 398newHandShakeData :: POSIXTime -> TransportCrypto -> Nonce24 -> HandshakeParams -> SockAddr -> PublicKey -> STM (Maybe HandshakeData)
399newHandShakeData crypto basenonce (HParam {hpOtherCookie,hpMySecretKey,hpCookieRemotePubkey,hpCookieRemoteDhtkey}) addr mySessionPublic 399newHandShakeData timestamp crypto basenonce (HParam {hpOtherCookie,hpMySecretKey,hpCookieRemotePubkey,hpCookieRemoteDhtkey}) addr mySessionPublic
400 = do 400 = do
401 freshCookie 401 freshCookie
402 <- case nodeInfo (key2id hpCookieRemoteDhtkey) addr of 402 <- case nodeInfo (key2id hpCookieRemoteDhtkey) addr of
403 Right nodeinfo -> Just <$> createCookie crypto nodeinfo hpCookieRemotePubkey 403 Right nodeinfo -> Just <$> createCookieSTM timestamp crypto nodeinfo hpCookieRemotePubkey
404 Left er -> return Nothing 404 Left er -> return Nothing
405 let hinit = hashInit 405 let hinit = hashInit
406 Cookie n24 encrypted = hpOtherCookie 406 Cookie n24 encrypted = hpOtherCookie
407 hctx = hashUpdate hinit n24 407 hctx = hashUpdate hinit n24
408 hctx' = hashUpdate hctx encrypted 408 hctx' = hashUpdate hctx encrypted
409 digest = hashFinalize hctx' 409 digest = hashFinalize hctx'
410-- parameters addr {--> SockAddr -}
411-- mbcookie <- case hpOtherCookie of
412-- Nothing -> case (nodeInfo hpCookieRemoteDhtkey addr) of
413-- Right nodeinfo -> cookieRequest crypto netCryptoDHTClient (toPublic hpMySecretKey) nodeinfo
414-- Left er -> return Nothing
415-- Just c -> return (Just c)
416
417 return $ 410 return $
418 fmap (\freshCookie' -> 411 fmap (\freshCookie' ->
419 HandshakeData 412 HandshakeData
@@ -489,9 +482,11 @@ ncToWire getState seqno bufend pktno msg = do
489-- then increment it regardless. (Keep addr in MinMaxPSQ in Roster.Contact) 482-- then increment it regardless. (Keep addr in MinMaxPSQ in Roster.Contact)
490-- 483--
491-- This function sends a handshake response packet. 484-- This function sends a handshake response packet.
492freshCryptoSession :: NetCryptoSessions -> SockAddr -> HandshakeParams -> IO () 485freshCryptoSession :: NetCryptoSessions -> SockAddr -> SecretKey -> POSIXTime -> HandshakeParams -> STM (Maybe (Handshake Encrypted),IO ())
493freshCryptoSession sessions 486freshCryptoSession sessions
494 addr 487 addr
488 newsession
489 timestamp
495 hp@(HParam 490 hp@(HParam
496 { hpTheirBaseNonce = mbtheirBaseNonce 491 { hpTheirBaseNonce = mbtheirBaseNonce
497 , hpOtherCookie = otherCookie 492 , hpOtherCookie = otherCookie
@@ -503,20 +498,20 @@ freshCryptoSession sessions
503 let crypto = transportCrypto sessions 498 let crypto = transportCrypto sessions
504 allsessions = netCryptoSessions sessions 499 allsessions = netCryptoSessions sessions
505 allsessionsByKey = netCryptoSessionsByKey sessions 500 allsessionsByKey = netCryptoSessionsByKey sessions
506 sessionId <- atomically $ do 501 dmsg msg = trace msg (return ())
502 sessionId <- do
507 x <- readTVar (nextSessionId sessions) 503 x <- readTVar (nextSessionId sessions)
508 modifyTVar (nextSessionId sessions) (+1) 504 modifyTVar (nextSessionId sessions) (+1)
509 return x 505 return x
510 -- ncState0 <- atomically $ newTVar Accepted -- (InProgress AwaitingSessionPacket) 506 -- ncState0 <- newTVar Accepted -- (InProgress AwaitingSessionPacket)
511 ncState0 <- atomically $ newTVar (if isJust mbtheirBaseNonce 507 ncState0 <- newTVar (if isJust mbtheirBaseNonce
512 then InProgress AwaitingSessionPacket 508 then InProgress AwaitingSessionPacket
513 else InProgress AwaitingHandshake) 509 else InProgress AwaitingHandshake)
514 ncTheirBaseNonce0 <- atomically $ newTVar (frmMaybe mbtheirBaseNonce) 510 ncTheirBaseNonce0 <- newTVar (frmMaybe mbtheirBaseNonce)
515 n24 <- atomically $ transportNewNonce crypto 511 n24 <- transportNewNonce crypto
516 state <- lookupSharedSecret crypto key remotePublicKey n24 512 state <- ($ n24) <$> lookupNonceFunctionSTM timestamp crypto key remotePublicKey
517 newBaseNonce <- atomically $ transportNewNonce crypto 513 newBaseNonce <- transportNewNonce crypto
518 newsession <- generateSecretKey 514 mbMyhandshakeData <- newHandShakeData timestamp crypto newBaseNonce hp addr (toPublic newsession)
519 mbMyhandshakeData <- newHandShakeData crypto newBaseNonce hp addr (toPublic newsession)
520 let encodeHandshake myhandshakeData = let plain = encodePlain myhandshakeData 515 let encodeHandshake myhandshakeData = let plain = encodePlain myhandshakeData
521 -- state = computeSharedSecret key remoteDhtPublicKey n24 516 -- state = computeSharedSecret key remoteDhtPublicKey n24
522 encrypted = encrypt state plain 517 encrypted = encrypt state plain
@@ -525,16 +520,14 @@ freshCryptoSession sessions
525 , handshakeData = encrypted 520 , handshakeData = encrypted
526 } 521 }
527 let myhandshake= encodeHandshake <$> mbMyhandshakeData 522 let myhandshake= encodeHandshake <$> mbMyhandshakeData
528 ncHandShake0 <- atomically $ newTVar (frmMaybe myhandshake) 523 ncHandShake0 <- newTVar (frmMaybe myhandshake)
529 forM myhandshake $ \response_handshake -> do 524 ncMyPacketNonce0 <- newTVar newBaseNonce
530 sendHandshake sessions addr response_handshake 525 cookie0 <- newTVar (HaveCookie otherCookie)
531 ncMyPacketNonce0 <- atomically $ newTVar newBaseNonce 526 ncHooks0 <- newTVar (defaultHooks sessions)
532 cookie0 <- atomically $ newTVar (HaveCookie otherCookie) 527 ncUnrecognizedHook0 <- newTVar (defaultUnrecognizedHook sessions)
533 ncHooks0 <- atomically $ newTVar (defaultHooks sessions) 528 ncIncomingTypeArray0 <- newTVar (msgTypeArray sessions)
534 ncUnrecognizedHook0 <- atomically $ newTVar (defaultUnrecognizedHook sessions)
535 ncIncomingTypeArray0 <- atomically $ newTVar (msgTypeArray sessions)
536 let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255]) 529 let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255])
537 (ncOutgoingIdMap0,lossyEscapeIdMap,losslessEscapeIdMap) <- atomically $ do 530 (ncOutgoingIdMap0,lossyEscapeIdMap,losslessEscapeIdMap) <- do
538 idmap <- emptySTMRangeMap 531 idmap <- emptySTMRangeMap
539 insertArrayAt idmap 0 (A.listArray (0,255) [0 .. 255]) 532 insertArrayAt idmap 0 (A.listArray (0,255) [0 .. 255])
540 -- the 2 escape ranges are adjacent, so put them in one array: 533 -- the 2 escape ranges are adjacent, so put them in one array:
@@ -546,21 +539,21 @@ freshCryptoSession sessions
546 lossyEsc <- newTVar $ A.listArray (0,255) [0 .. 255] 539 lossyEsc <- newTVar $ A.listArray (0,255) [0 .. 255]
547 losslessEsc <- newTVar $ A.listArray (0,255) [0 .. 255] 540 losslessEsc <- newTVar $ A.listArray (0,255) [0 .. 255]
548 return (idmap,lossyEsc,losslessEsc) 541 return (idmap,lossyEsc,losslessEsc)
549 ncView0 <- atomically $ newTVar (sessionView sessions) 542 ncView0 <- newTVar (sessionView sessions)
550 pktq <- atomically $ PQ.new (inboundQueueCapacity sessions) 0 543 pktq <- PQ.new (inboundQueueCapacity sessions) 0
551 bufstart <- atomically $ newTVar 0 544 bufstart <- newTVar 0
552 mbpktoq 545 mbpktoq
553 <- case mbtheirSessionKey of 546 <- case mbtheirSessionKey of
554 Nothing -> return NeedHandshake 547 Nothing -> return NeedHandshake
555 Just theirSessionKey -> createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 548 Just theirSessionKey -> createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0
556 lastNQ <- atomically (CB.new 10 0 :: STM (CyclicBuffer (Bool,(ViewSnapshot,InOrOut CryptoMessage)))) 549 lastNQ <- CB.new 10 0 :: STM (CyclicBuffer (Bool,(ViewSnapshot,InOrOut CryptoMessage)))
557 listeners <- atomically $ newTVar IntMap.empty 550 listeners <- newTVar IntMap.empty
558 msgNum <- atomically $ newTVar 0 551 msgNum <- newTVar 0
559 dropNum <- atomically $ newTVar 0 552 dropNum <- newTVar 0
560 theirbasenonce <- atomically $ readTVar ncTheirBaseNonce0 553 theirbasenonce <- readTVar ncTheirBaseNonce0
561 dput XNetCrypto $ "freshCryptoSession: Session ncTheirBaseNonce=" ++ show theirbasenonce 554 dmsg $ "freshCryptoSession: Session ncTheirBaseNonce=" ++ show theirbasenonce
562 dput XNetCrypto $ "freshCryptoSession: My Session Public =" ++ show (key2id $ toPublic newsession) 555 dmsg $ "freshCryptoSession: My Session Public =" ++ show (key2id $ toPublic newsession)
563 ncTheirSessionPublic0 <- atomically $ newTVar (frmMaybe mbtheirSessionKey) 556 ncTheirSessionPublic0 <- newTVar (frmMaybe mbtheirSessionKey)
564 let netCryptoSession0 = 557 let netCryptoSession0 =
565 NCrypto { ncState = ncState0 558 NCrypto { ncState = ncState0
566 , ncMyPublicKey = toPublic key 559 , ncMyPublicKey = toPublic key
@@ -590,9 +583,11 @@ freshCryptoSession sessions
590 , ncListeners = listeners 583 , ncListeners = listeners
591 } 584 }
592 addSessionToMapIfNotThere sessions addr netCryptoSession0 585 addSessionToMapIfNotThere sessions addr netCryptoSession0
593 case mbpktoq of 586 maybeLaunchMissles
594 NeedHandshake -> return () 587 <- case mbpktoq of
595 HaveHandshake pktoq -> runUponHandshake netCryptoSession0 addr pktoq 588 NeedHandshake -> return (return ())
589 HaveHandshake pktoq -> return (runUponHandshake netCryptoSession0 addr pktoq)
590 return (myhandshake,maybeLaunchMissles)
596 591
597type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 TVar) 592type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 TVar)
598 CryptoMessage 593 CryptoMessage
@@ -600,7 +595,7 @@ type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8
600 CryptoData 595 CryptoData
601 596
602createNetCryptoOutQueue :: NetCryptoSessions -> SecretKey -> PublicKey -> PacketQueue CryptoData 597createNetCryptoOutQueue :: NetCryptoSessions -> SecretKey -> PublicKey -> PacketQueue CryptoData
603 -> TVar Nonce24 -> RangeMap TArray Word8 TVar -> IO (UponHandshake NetCryptoOutQueue) 598 -> TVar Nonce24 -> RangeMap TArray Word8 TVar -> STM (UponHandshake NetCryptoOutQueue)
604createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 = do 599createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 = do
605 let crypto = transportCrypto sessions 600 let crypto = transportCrypto sessions
606 let toWireIO = do 601 let toWireIO = do
@@ -613,33 +608,33 @@ createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce
613 ++ "\n toWireIO: my public session key = " ++ show (key2id (toPublic newsession)) 608 ++ "\n toWireIO: my public session key = " ++ show (key2id (toPublic newsession))
614 ) $ writeTVar ncMyPacketNonce0 n24plus1 609 ) $ writeTVar ncMyPacketNonce0 n24plus1
615 return (return (f n24, n24, ncOutgoingIdMap0)) 610 return (return (f n24, n24, ncOutgoingIdMap0))
616 pktoq <- atomically $ PQ.newOutGoing pktq ncToWire toWireIO 0 (outboundQueueCapacity sessions) 0 611 pktoq <- PQ.newOutGoing pktq ncToWire toWireIO 0 (outboundQueueCapacity sessions) 0
617 return (HaveHandshake pktoq) 612 return (HaveHandshake pktoq)
618 613
619-- | add this session to the lookup maps, unless its already in them 614-- | add this session to the lookup maps, unless its already in them
620addSessionToMapIfNotThere :: NetCryptoSessions -> SockAddr -> NetCryptoSession -> IO () 615addSessionToMapIfNotThere :: NetCryptoSessions -> SockAddr -> NetCryptoSession -> STM ()
621addSessionToMapIfNotThere sessions addr netCryptoSession = do 616addSessionToMapIfNotThere sessions addr netCryptoSession = do
622 dput XNetCrypto $ "addSessionToMapIfNotThere sockaddr = " ++ show addr ++ ", sessionid = " ++ show (ncSessionId netCryptoSession) 617 let dmsg msg = trace msg (return ())
623 atomically $ do 618 dmsg $ "addSessionToMapIfNotThere sockaddr = " ++ show addr ++ ", sessionid = " ++ show (ncSessionId netCryptoSession)
624 let remotePublicKey = ncTheirPublicKey netCryptoSession 619 let remotePublicKey = ncTheirPublicKey netCryptoSession
625 allsessions = netCryptoSessions sessions 620 allsessions = netCryptoSessions sessions
626 allsessionsByKey= netCryptoSessionsByKey sessions 621 allsessionsByKey= netCryptoSessionsByKey sessions
627 byAddrResult <- readTVar allsessions >>= return . Map.lookup addr 622 byAddrResult <- readTVar allsessions >>= return . Map.lookup addr
628 case byAddrResult of 623 case byAddrResult of
629 Just (NCrypto { ncSessionId = staleId }) -> do 624 Just (NCrypto { ncSessionId = staleId }) -> do
630 -- manually remove the stale session from the by-key map 625 -- manually remove the stale session from the by-key map
631 modifyTVar allsessionsByKey (Map.map (filter ((/=staleId) . ncSessionId))) 626 modifyTVar allsessionsByKey (Map.map (filter ((/=staleId) . ncSessionId)))
632 Nothing -> return () -- nothing to remove 627 Nothing -> return () -- nothing to remove
633 -- write session to by-addr map regardless of whether one is in there, 628 -- write session to by-addr map regardless of whether one is in there,
634 -- it should overwrite on match 629 -- it should overwrite on match
635 modifyTVar allsessions (Map.insert addr netCryptoSession) 630 modifyTVar allsessions (Map.insert addr netCryptoSession)
636 -- Now insert new session into by-key map 631 -- Now insert new session into by-key map
637 byKeyResult <- readTVar allsessionsByKey >>= return . Map.lookup remotePublicKey 632 byKeyResult <- readTVar allsessionsByKey >>= return . Map.lookup remotePublicKey
638 case byKeyResult of 633 case byKeyResult of
639 Nothing -> modifyTVar allsessionsByKey (Map.insert remotePublicKey [netCryptoSession]) 634 Nothing -> modifyTVar allsessionsByKey (Map.insert remotePublicKey [netCryptoSession])
640 Just xs -> do 635 Just xs -> do
641 -- in case we're using the same long term key on different IPs ... 636 -- in case we're using the same long term key on different IPs ...
642 modifyTVar allsessionsByKey (Map.insert remotePublicKey (netCryptoSession:xs)) 637 modifyTVar allsessionsByKey (Map.insert remotePublicKey (netCryptoSession:xs))
643 638
644runUponHandshake :: NetCryptoSession -> SockAddr -> NetCryptoOutQueue -> IO () 639runUponHandshake :: NetCryptoSession -> SockAddr -> NetCryptoOutQueue -> IO ()
645runUponHandshake netCryptoSession0 addr pktoq = do 640runUponHandshake netCryptoSession0 addr pktoq = do
@@ -673,7 +668,7 @@ runUponHandshake netCryptoSession0 addr pktoq = do
673 -- update session with thread ids 668 -- update session with thread ids
674 let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid, ncPingMachine=Just pingMachine} 669 let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid, ncPingMachine=Just pingMachine}
675 -- add this session to the lookup maps 670 -- add this session to the lookup maps
676 addSessionToMapIfNotThere sessions addr netCryptoSession 671 -- atomically $ addSessionToMapIfNotThere sessions addr netCryptoSession
677 -- run announceNewSessionHooks 672 -- run announceNewSessionHooks
678 hooks <- atomically $ readTVar (announceNewSessionHooks sessions) 673 hooks <- atomically $ readTVar (announceNewSessionHooks sessions)
679 flip fix (hooks,netCryptoSession) $ \loop (hooks,session) -> 674 flip fix (hooks,netCryptoSession) $ \loop (hooks,session) ->
@@ -691,10 +686,12 @@ runUponHandshake netCryptoSession0 addr pktoq = do
691-- 2) handshake for new session (old session is lost?) 686-- 2) handshake for new session (old session is lost?)
692 687
693-- 3) we initiated, this a response 688-- 3) we initiated, this a response
694updateCryptoSession :: NetCryptoSessions -> SockAddr -> HandshakeParams -> NetCryptoSession -> Handshake Encrypted -> IO () 689updateCryptoSession :: NetCryptoSessions -> SockAddr -> SecretKey -> POSIXTime -> HandshakeParams
695updateCryptoSession sessions addr hp session handshake = do 690 -> NetCryptoSession -> Handshake Encrypted -> STM (Maybe (Handshake Encrypted), IO ())
696 ncState0 <- atomically $ readTVar (ncState session) 691updateCryptoSession sessions addr newsession timestamp hp session handshake = do
697 ncTheirBaseNonce0 <- atomically $ readTVar (ncTheirBaseNonce session) 692 let dmsg msg = trace msg (return ())
693 ncState0 <- readTVar (ncState session)
694 ncTheirBaseNonce0 <- readTVar (ncTheirBaseNonce session)
698 if (ncState0 >= {-Accepted-}InProgress AwaitingSessionPacket) 695 if (ncState0 >= {-Accepted-}InProgress AwaitingSessionPacket)
699 -- If the nonce in the handshake and the dht key are both the same as 696 -- If the nonce in the handshake and the dht key are both the same as
700 -- the ones we have saved, assume we already handled this and this is a 697 -- the ones we have saved, assume we already handled this and this is a
@@ -702,42 +699,31 @@ updateCryptoSession sessions addr hp session handshake = do
702 -- refresh all state. 699 -- refresh all state.
703 -- 700 --
704 then do 701 then do
705 dput XNetCrypto "updateCryptoSession already accepted.." 702 dmsg "updateCryptoSession already accepted.."
706 dput XNetCrypto (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0 703 dmsg (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0
707 ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp) 704 ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp)
708 ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp)) 705 ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp))
709 dput XNetCrypto (" ncTheirDHTKey=" ++ show (ncTheirDHTKey session) 706 dmsg (" ncTheirDHTKey=" ++ show (ncTheirDHTKey session)
710 ++ bool "{/=}" "{==}" (ncTheirDHTKey session == HaveDHTKey (hpCookieRemoteDhtkey hp)) 707 ++ bool "{/=}" "{==}" (ncTheirDHTKey session == HaveDHTKey (hpCookieRemoteDhtkey hp))
711 ++ "hpCookieRemoteDhtkey=" ++ show (hpCookieRemoteDhtkey hp)) 708 ++ "hpCookieRemoteDhtkey=" ++ show (hpCookieRemoteDhtkey hp))
712 when ( -- Just ncTheirBaseNonce0 /= hpTheirBaseNonce hp -- XXX: Do we really want to compare base nonce here? 709 if ( -- Just ncTheirBaseNonce0 /= hpTheirBaseNonce hp -- XXX: Do we really want to compare base nonce here?
713 -- || 710 -- ||
714 ncTheirDHTKey session /= HaveDHTKey (hpCookieRemoteDhtkey hp) 711 ncTheirDHTKey session /= HaveDHTKey (hpCookieRemoteDhtkey hp)
715 ) $ freshCryptoSession sessions addr hp 712 )
716 -- else do 713 then freshCryptoSession sessions addr newsession timestamp hp
717 -- atomically $ do 714 else return (Nothing,return ())
718 -- writeTVar (ncTheirBaseNonce session) (frmMaybe (hpTheirBaseNonce hp))
719 -- writeTVar (ncTheirSessionPublic session) (frmMaybe (hpTheirSessionKeyPublic hp))
720 -- writeTVar (ncHandShake session) (HaveHandshake handshake)
721 -- case ncOutgoingQueue session of
722 -- NeedHandshake -> do
723 -- case hpTheirSessionKeyPublic hp of
724 -- Just sessionpubkey -> do
725 -- pktoq <- createNetCryptoOutQueue sessions (ncSessionSecret session) sessionpubkey
726 -- (ncPacketQueue session) (ncMyPacketNonce session) (ncOutgoingIdMap session)
727 -- case pktoq of
728 -- NeedHandshake -> dput XNetCrypto "Unexpectedly missing ncOutgoingQueue"
729 -- HaveHandshake pktoq -> runUponHandshake session addr pktoq
730 -- HaveHandshake pktoq -> runUponHandshake session addr pktoq
731 else do 715 else do
732 dput XNetCrypto "updateCryptoSession else clause" 716 dmsg "updateCryptoSession else clause"
733 dput XNetCrypto (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0 717 dmsg (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0
734 ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp) 718 ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp)
735 ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp)) 719 ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp))
736 if ( ncTheirBaseNonce0 /= frmMaybe (hpTheirBaseNonce hp)) 720 if ( ncTheirBaseNonce0 /= frmMaybe (hpTheirBaseNonce hp))
737 then do 721 then do
738 dput XNetCrypto "basenonce mismatch, trigger refresh" 722 dmsg "basenonce mismatch, trigger refresh"
739 freshCryptoSession sessions addr hp -- basenonce mismatch, trigger refresh 723 freshCryptoSession sessions addr newsession timestamp hp -- basenonce mismatch, trigger refresh
740 else atomically $ writeTVar (ncState session) {-Accepted-}(InProgress AwaitingSessionPacket) 724 else do
725 writeTVar (ncState session) {-Accepted-}(InProgress AwaitingSessionPacket)
726 return (Nothing,return ())
741 727
742anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1) 728anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1)
743anyRight e [] f = return $ Left e 729anyRight e [] f = return $ Left e
@@ -819,15 +805,25 @@ handshakeH sessions addr hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypte
819 , hpCookieRemoteDhtkey = remoteDhtPublicKey 805 , hpCookieRemoteDhtkey = remoteDhtPublicKey
820 }) -> do 806 }) -> do
821 dput XNetCrypto ("(NetCrypto)handshakeH: hpTheirBaseNonce = " ++ show theirBaseNonce) 807 dput XNetCrypto ("(NetCrypto)handshakeH: hpTheirBaseNonce = " ++ show theirBaseNonce)
822 sessionsmap <- atomically $ readTVar allsessions 808 -- IO action to get a new session key in case we need it in transaction to come
809 newsession <- generateSecretKey
823 -- Do a lookup, so we can handle the update case differently 810 -- Do a lookup, so we can handle the update case differently
824 case Map.lookup addr sessionsmap of 811 let dmsg msg = trace msg (return ())
825 Nothing -> do 812 timestamp <- getPOSIXTime
826 dput XNetCrypto "sockaddr not in session map, so freshCryptoSession" 813 (myhandshake,launchThreads)
827 freshCryptoSession sessions addr hp -- create new session 814 <- atomically $ do
828 Just session -> do 815 sessionsmap <- readTVar allsessions
829 dput XNetCrypto "sockaddr ALREADY in session map, so updateCryptoSession" 816 case Map.lookup addr sessionsmap of
830 updateCryptoSession sessions addr hp session hshake -- update existing session 817 Nothing -> do
818 dmsg "sockaddr not in session map, so freshCryptoSession"
819 freshCryptoSession sessions addr newsession timestamp hp -- create new session
820 Just session -> do
821 dmsg "sockaddr ALREADY in session map, so updateCryptoSession"
822 updateCryptoSession sessions addr newsession timestamp hp session hshake -- update existing session
823 launchThreads
824 forM myhandshake $ \response_handshake -> do
825 sendHandshake sessions addr response_handshake
826 return ()
831 return Nothing 827 return Nothing
832 828
833sessionPacketH :: NetCryptoSessions -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (x -> x)) 829sessionPacketH :: NetCryptoSessions -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (x -> x))
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs
index 238fb0d0..dd586430 100644
--- a/src/Network/Tox/DHT/Handlers.hs
+++ b/src/Network/Tox/DHT/Handlers.hs
@@ -5,6 +5,7 @@
5{-# LANGUAGE TupleSections #-} 5{-# LANGUAGE TupleSections #-}
6module Network.Tox.DHT.Handlers where 6module Network.Tox.DHT.Handlers where
7 7
8import Debug.Trace
8import Network.Tox.DHT.Transport as DHTTransport 9import Network.Tox.DHT.Transport as DHTTransport
9import Network.QueryResponse as QR hiding (Client) 10import Network.QueryResponse as QR hiding (Client)
10import qualified Network.QueryResponse as QR (Client) 11import qualified Network.QueryResponse as QR (Client)
@@ -234,6 +235,23 @@ createCookie crypto ni remoteUserKey = do
234 dput XNetCrypto $ "Created cookie with n24 = 0x" ++ show n24 ++ "\n sym=" ++ show sym 235 dput XNetCrypto $ "Created cookie with n24 = 0x" ++ show n24 ++ "\n sym=" ++ show sym
235 return $ Cookie n24 edta 236 return $ Cookie n24 edta
236 237
238createCookieSTM :: POSIXTime -> TransportCrypto -> NodeInfo -> PublicKey -> STM (Cookie Encrypted)
239createCookieSTM now crypto ni remoteUserKey = do
240 let dmsg msg = trace msg (return ())
241 (n24,sym) <- do
242 n24 <- transportNewNonce crypto
243 sym <- transportSymmetric crypto
244 return (n24,sym)
245 let timestamp = round (now * 1000000)
246 let dta = encodePlain $ CookieData
247 { cookieTime = timestamp
248 , longTermKey = remoteUserKey
249 , dhtKey = transportPublic crypto
250 }
251 edta = encryptSymmetric sym n24 dta
252 dmsg $ "(createCookieSTM) Created cookie with n24 = 0x" ++ show n24 ++ "\n sym=" ++ show sym
253 return $ Cookie n24 edta
254
237cookieRequestH :: TransportCrypto -> NodeInfo -> CookieRequest -> IO (Cookie Encrypted) 255cookieRequestH :: TransportCrypto -> NodeInfo -> CookieRequest -> IO (Cookie Encrypted)
238cookieRequestH crypto ni (CookieRequest remoteUserKey) = do 256cookieRequestH crypto ni (CookieRequest remoteUserKey) = do
239 dput XNetCrypto $ unlines 257 dput XNetCrypto $ unlines