module Pipes.Noise
(
MessagePipe,
messageEncryptPipe,
messageDecryptPipe
) where
import Control.Concurrent.MVar (MVar, putMVar, takeMVar)
import Control.Monad (forever)
import Data.ByteString (ByteString)
import Pipes (Pipe, await, yield, lift)
import Crypto.Noise.Cipher (Cipher)
import Crypto.Noise.Handshake
import Crypto.Noise.Types (Plaintext(..), bsToSB', sbToBS')
type MessagePipe = Pipe ByteString ByteString
messageEncryptPipe :: Cipher c
=> MVar (SendingCipherState c)
-> MessagePipe IO r
messageEncryptPipe csmv = forever $ do
msg <- await
encState <- lift $ takeMVar csmv
let pt = Plaintext . bsToSB' $ msg
(ct, encState') = encryptPayload pt encState
lift $ putMVar csmv encState'
yield ct
messageDecryptPipe :: Cipher c
=> MVar (ReceivingCipherState c)
-> MessagePipe IO r
messageDecryptPipe csmv = forever $ do
msg <- await
decState <- lift $ takeMVar csmv
let (Plaintext pt, decState') = decryptPayload msg decState
lift $ putMVar csmv decState'
yield . sbToBS' $ pt