summaryrefslogtreecommitdiff
path: root/src/Network/Tox/Crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/Tox/Crypto')
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs210
1 files changed, 103 insertions, 107 deletions
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))