diff options
author | joe <joe@jerkface.net> | 2018-06-18 21:04:20 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2018-06-18 21:04:20 -0400 |
commit | 2051912a76c7b6aedbda60f58dd37c39344470ec (patch) | |
tree | 9fe1a8820f15e0a70176851f9181d7dff1528b96 /src/Network/Tox/Crypto/Handlers.hs | |
parent | 772f6547a40eb6a3a1dd76befb691f9160ed2d7a (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.hs | 103 |
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 | |||
58 | import Data.Bool | 58 | import Data.Bool |
59 | import Connection (Status(..), Policy(..)) | 59 | import Connection (Status(..), Policy(..)) |
60 | import Network.Tox.ContactInfo | 60 | import Network.Tox.ContactInfo |
61 | import 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 | ||
468 | data 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 | |||
478 | newHandShakeData :: POSIXTime -> TransportCrypto -> Nonce24 -> HandshakeParams -> SockAddr -> PublicKey -> STM (Maybe HandshakeData) | ||
479 | newHandShakeData 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 | |||
499 | type XMessage = CryptoMessage -- todo | 469 | type 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 | ||
877 | anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1) | ||
878 | anyRight e [] f = return $ Left e | ||
879 | anyRight e (x:xs) f = f x >>= either (const $ anyRight e xs f) (return . Right) | ||
880 | |||
881 | decryptHandshake :: TransportCrypto -> Handshake Encrypted -> IO (Either String (SecretKey,Handshake Identity)) | ||
882 | decryptHandshake 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 | |||
920 | toHandshakeParams :: (SecretKey, Handshake Identity) -> HandshakeParams | ||
921 | toHandshakeParams (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 | |||
933 | handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a) | 840 | handshakeH :: NetCryptoSessions -> SockAddr -> Handshake Encrypted -> IO (Maybe a) |
934 | handshakeH sessions addrRaw hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypted) = do | 841 | handshakeH 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 |