pipes-cacophony-0.5.0: examples/loopback/Main.hs
module Main where
import Control.Monad (forever)
import Data.ByteString.Char8 (unpack, pack)
import Data.Maybe (fromMaybe)
import Pipes
import qualified Pipes.Prelude as P
import Crypto.Noise
import Crypto.Noise.Cipher.ChaChaPoly1305
import Crypto.Noise.DH
import Crypto.Noise.DH.Curve25519
import Crypto.Noise.HandshakePatterns (noiseNN)
import Crypto.Noise.Hash.SHA256
import Pipes.Noise
strToSB :: (Cipher c, DH d, Hash h)
=> Pipe String ScrubbedBytes IO (NoiseResult c d h)
strToSB = forever $ await >>= yield . convert . pack
sbToStr :: (Cipher c, DH d, Hash h)
=> Pipe ScrubbedBytes String IO (NoiseResult c d h)
sbToStr = forever $ await >>= yield . unpack . convert
performHandshake :: (Cipher c, DH d, Hash h)
=> NoiseState c d h
-> NoiseState c d h
-> (NoiseState c d h, NoiseState c d h)
performHandshake ins rns = (ins'', rns'')
where
(NoiseResultMessage ct ins') = writeMessage mempty ins
(NoiseResultMessage _ rns') = readMessage ct rns
(NoiseResultMessage ct' rns'') = writeMessage mempty rns'
(NoiseResultMessage _ ins'') = readMessage ct' ins'
main :: IO ()
main = do
iek <- dhGenKey :: IO (KeyPair Curve25519)
rek <- dhGenKey :: IO (KeyPair Curve25519)
let idho = defaultHandshakeOpts InitiatorRole "cacophony"
rdho = defaultHandshakeOpts ResponderRole "cacophony"
iho = setLocalEphemeral (Just iek) idho
rho = setLocalEphemeral (Just rek) rdho
ins = noiseState iho noiseNN :: NoiseState ChaChaPoly1305 Curve25519 SHA256
rns = noiseState rho noiseNN :: NoiseState ChaChaPoly1305 Curve25519 SHA256
(ins', rns') = performHandshake ins rns
(iip, iop) = fromMaybe (error "unable to make Noise pipe") $ mkNoisePipes ins'
(rip, rop) = fromMaybe (error "unable to make Noise pipe") $ mkNoisePipes rns'
result <- runEffect $ (undefined <$ P.stdinLn)
>-> strToSB
>-> iop
>-> rip
>-> rop
>-> iip
>-> sbToStr
>-> (undefined <$ P.stdoutLn)
case result of
NoiseResultException ex -> print ex
_ -> return ()