1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
-- | TLS record layer in Tx direction
module Network.TLS.Record.Send (
encodeRecord12,
encodeRecord13,
sendBytes,
) where
import Network.TLS.Cipher
import Network.TLS.Context.Internal
import Network.TLS.Hooks
import Network.TLS.Imports
import Network.TLS.Packet
import Network.TLS.Record
import Network.TLS.Struct
import Control.Concurrent.MVar
import Control.Monad.State.Strict
import qualified Data.ByteString as B
encodeRecordM :: Record Plaintext -> RecordM ByteString
encodeRecordM record = do
erecord <- encryptRecord record
let (hdr, content) = recordToRaw erecord
return $ B.concat [encodeHeader hdr, content]
----------------------------------------------------------------
encodeRecord12 :: Context -> Record Plaintext -> IO (Either TLSError ByteString)
encodeRecord12 ctx = prepareRecord12 ctx . encodeRecordM
-- before TLS 1.1, the block cipher IV is made of the residual of the previous block,
-- so we use cstIV as is, however in other case we generate an explicit IV
prepareRecord12 :: Context -> RecordM a -> IO (Either TLSError a)
prepareRecord12 ctx f = do
txState <- readMVar $ ctxTxRecordState ctx
let sz = case stCipher txState of
Nothing -> 0
Just cipher ->
if hasRecordIV $ bulkF $ cipherBulk cipher
then bulkIVSize $ cipherBulk cipher
else 0 -- to not generate IV
if sz > 0
then do
newIV <- getStateRNG ctx sz
runTxRecordState ctx (modify (setRecordIV newIV) >> f)
else runTxRecordState ctx f
----------------------------------------------------------------
encodeRecord13 :: Context -> Record Plaintext -> IO (Either TLSError ByteString)
encodeRecord13 ctx = prepareRecord13 ctx . encodeRecordM
prepareRecord13 :: Context -> RecordM a -> IO (Either TLSError a)
prepareRecord13 = runTxRecordState
----------------------------------------------------------------
sendBytes :: Context -> ByteString -> IO ()
sendBytes ctx dataToSend = do
withLog ctx $ \logging -> loggingIOSent logging dataToSend
contextSend ctx dataToSend
|