    -- |
    -- Module      : Network.TLS.Wire
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- the Wire module is a specialized marshalling/unmarshalling package related to the TLS protocol.
    -- all multibytes values are written as big endian.
    --
    module Network.TLS.Wire
        ( Get
        , GetResult(..)
        , GetContinuation
        , runGet
        , runGetErr
        , runGetMaybe
        , tryGet
        , remaining
        , getWord8
        , getWords8
        , getWord16
        , getWords16
        , getWord24
        , getWord32
        , getWord64
        , getBytes
        , getOpaque8
        , getOpaque16
        , getOpaque24
        , getInteger16
        , getBigNum16
        , getList
        , processBytes
        , isEmpty
        , Put
        , runPut
        , putWord8
        , putWords8
        , putWord16
        , putWords16
        , putWord24
        , putWord32
        , putWord64
        , putBytes
        , putOpaque8
        , putOpaque16
        , putOpaque24
        , putInteger16
        , putBigNum16
        , encodeWord16
        , encodeWord32
        , encodeWord64
        ) where

    import Data.Serialize.Get hiding (runGet)
    import qualified Data.Serialize.Get as G
    import Data.Serialize.Put
    import qualified Data.ByteString as B
    import Network.TLS.Struct
    import Network.TLS.Imports
    import Network.TLS.Util.Serialization

    type GetContinuation a = ByteString -> GetResult a
    data GetResult a =
          GotError TLSError
        | GotPartial (GetContinuation a)
        | GotSuccess a
        | GotSuccessRemaining a ByteString

    runGet :: String -> Get a -> ByteString -> GetResult a
    runGet :: String -> Get a -> ByteString -> GetResult a
    runGet lbl :: String
    lbl f :: Get a
    f = Result a -> GetResult a
    forall a. Result a -> GetResult a
    toGetResult (Result a -> GetResult a)
    -> (ByteString -> Result a) -> ByteString -> GetResult a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get a -> ByteString -> Result a
    forall a. Get a -> ByteString -> Result a
    G.runGetPartial (String -> Get a -> Get a
    forall a. String -> Get a -> Get a
    label String
    lbl Get a
    f)
      where toGetResult :: Result a -> GetResult a
    toGetResult (G.Fail err :: String
    err _)    = TLSError -> GetResult a
    forall a. TLSError -> GetResult a
    GotError (String -> TLSError
    Error_Packet_Parsing String
    err)
            toGetResult (G.Partial cont :: ByteString -> Result a
    cont)  = GetContinuation a -> GetResult a
    forall a. GetContinuation a -> GetResult a
    GotPartial (Result a -> GetResult a
    toGetResult (Result a -> GetResult a)
    -> (ByteString -> Result a) -> GetContinuation a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> Result a
    cont)
            toGetResult (G.Done r :: a
    r bsLeft :: ByteString
    bsLeft)
                | ByteString -> Bool
    B.null ByteString
    bsLeft = a -> GetResult a
    forall a. a -> GetResult a
    GotSuccess a
    r
                | Bool
    otherwise     = a -> GetContinuation a
    forall a. a -> GetContinuation a
    GotSuccessRemaining a
    r ByteString
    bsLeft

    runGetErr :: String -> Get a -> ByteString -> Either TLSError a
    runGetErr :: String -> Get a -> ByteString -> Either TLSError a
    runGetErr lbl :: String
    lbl getter :: Get a
    getter b :: ByteString
    b = GetResult a -> Either TLSError a
    forall b. GetResult b -> Either TLSError b
    toSimple (GetResult a -> Either TLSError a)
    -> GetResult a -> Either TLSError a
    forall a b. (a -> b) -> a -> b
    $ String -> Get a -> ByteString -> GetResult a
    forall a. String -> Get a -> ByteString -> GetResult a
    runGet String
    lbl Get a
    getter ByteString
    b
      where toSimple :: GetResult b -> Either TLSError b
    toSimple (GotError err :: TLSError
    err) = TLSError -> Either TLSError b
    forall a b. a -> Either a b
    Left TLSError
    err
            toSimple (GotPartial _) = TLSError -> Either TLSError b
    forall a b. a -> Either a b
    Left (String -> TLSError
    Error_Packet_Parsing (String
    lbl String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": parsing error: partial packet"))
            toSimple (GotSuccessRemaining _ _) = TLSError -> Either TLSError b
    forall a b. a -> Either a b
    Left (String -> TLSError
    Error_Packet_Parsing (String
    lbl String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": parsing error: remaining bytes"))
            toSimple (GotSuccess r :: b
    r) = b -> Either TLSError b
    forall a b. b -> Either a b
    Right b
    r

    runGetMaybe :: Get a -> ByteString -> Maybe a
    runGetMaybe :: Get a -> ByteString -> Maybe a
    runGetMaybe f :: Get a
    f = (String -> Maybe a) -> (a -> Maybe a) -> Either String a -> Maybe a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe a -> String -> Maybe a
    forall a b. a -> b -> a
    const Maybe a
    forall a. Maybe a
    Nothing) a -> Maybe a
    forall a. a -> Maybe a
    Just (Either String a -> Maybe a)
    -> (ByteString -> Either String a) -> ByteString -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Get a -> ByteString -> Either String a
    forall a. Get a -> ByteString -> Either String a
    G.runGet Get a
    f

    tryGet :: Get a -> ByteString -> Maybe a
    tryGet :: Get a -> ByteString -> Maybe a
    tryGet f :: Get a
    f = (String -> Maybe a) -> (a -> Maybe a) -> Either String a -> Maybe a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe a -> String -> Maybe a
    forall a b. a -> b -> a
    const Maybe a
    forall a. Maybe a
    Nothing) a -> Maybe a
    forall a. a -> Maybe a
    Just (Either String a -> Maybe a)
    -> (ByteString -> Either String a) -> ByteString -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Get a -> ByteString -> Either String a
    forall a. Get a -> ByteString -> Either String a
    G.runGet Get a
    f

    getWords8 :: Get [Word8]
    getWords8 :: Get [Word8]
    getWords8 = Get Word8
    getWord8 Get Word8 -> (Word8 -> Get [Word8]) -> Get [Word8]
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \lenb :: Word8
    lenb -> Int -> Get Word8 -> Get [Word8]
    forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
    replicateM (Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    lenb) Get Word8
    getWord8

    getWord16 :: Get Word16
    getWord16 :: Get Word16
    getWord16 = Get Word16
    getWord16be

    getWords16 :: Get [Word16]
    getWords16 :: Get [Word16]
    getWords16 = Get Word16
    getWord16 Get Word16 -> (Word16 -> Get [Word16]) -> Get [Word16]
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \lenb :: Word16
    lenb -> Int -> Get Word16 -> Get [Word16]
    forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
    replicateM (Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word16
    lenb Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `div` 2) Get Word16
    getWord16

    getWord24 :: Get Int
    getWord24 :: Get Int
    getWord24 = do
        Int
    a <- Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8 -> Int) -> Get Word8 -> Get Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Word8
    getWord8
        Int
    b <- Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8 -> Int) -> Get Word8 -> Get Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Word8
    getWord8
        Int
    c <- Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8 -> Int) -> Get Word8 -> Get Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Word8
    getWord8
        Int -> Get Int
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> Get Int) -> Int -> Get Int
    forall a b. (a -> b) -> a -> b
    $ (Int
    a Int -> Int -> Int
    forall a. Bits a => a -> Int -> a
    `shiftL` 16) Int -> Int -> Int
    forall a. Bits a => a -> a -> a
    .|. (Int
    b Int -> Int -> Int
    forall a. Bits a => a -> Int -> a
    `shiftL` 8) Int -> Int -> Int
    forall a. Bits a => a -> a -> a
    .|. Int
    c

    getWord32 :: Get Word32
    getWord32 :: Get Word32
    getWord32 = Get Word32
    getWord32be

    getWord64 :: Get Word64
    getWord64 :: Get Word64
    getWord64 = Get Word64
    getWord64be

    getOpaque8 :: Get ByteString
    getOpaque8 :: Get ByteString
    getOpaque8 = Get Word8
    getWord8 Get Word8 -> (Word8 -> Get ByteString) -> Get ByteString
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Int -> Get ByteString
    getBytes (Int -> Get ByteString)
    -> (Word8 -> Int) -> Word8 -> Get ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    getOpaque16 :: Get ByteString
    getOpaque16 :: Get ByteString
    getOpaque16 = Get Word16
    getWord16 Get Word16 -> (Word16 -> Get ByteString) -> Get ByteString
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Int -> Get ByteString
    getBytes (Int -> Get ByteString)
    -> (Word16 -> Int) -> Word16 -> Get ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    getOpaque24 :: Get ByteString
    getOpaque24 :: Get ByteString
    getOpaque24 = Get Int
    getWord24 Get Int -> (Int -> Get ByteString) -> Get ByteString
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Int -> Get ByteString
    getBytes

    getInteger16 :: Get Integer
    getInteger16 :: Get Integer
    getInteger16 = ByteString -> Integer
    forall ba. ByteArrayAccess ba => ba -> Integer
    os2ip (ByteString -> Integer) -> Get ByteString -> Get Integer
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get ByteString
    getOpaque16

    getBigNum16 :: Get BigNum
    getBigNum16 :: Get BigNum
    getBigNum16 = ByteString -> BigNum
    BigNum (ByteString -> BigNum) -> Get ByteString -> Get BigNum
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get ByteString
    getOpaque16

    getList :: Int -> Get (Int, a) -> Get [a]
    getList :: Int -> Get (Int, a) -> Get [a]
    getList totalLen :: Int
    totalLen getElement :: Get (Int, a)
    getElement = Int -> Get [a] -> Get [a]
    forall a. Int -> Get a -> Get a
    isolate Int
    totalLen (Int -> Get [a]
    getElements Int
    totalLen)
      where getElements :: Int -> Get [a]
    getElements len :: Int
    len
                | Int
    len Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0     = String -> Get [a]
    forall a. HasCallStack => String -> a
    error "list consumed too much data. should never happen with isolate."
                | Int
    len Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0    = [a] -> Get [a]
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
                | Bool
    otherwise   = Get (Int, a)
    getElement Get (Int, a) -> ((Int, a) -> Get [a]) -> Get [a]
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \(elementLen :: Int
    elementLen, a :: a
    a) -> (:) a
    a ([a] -> [a]) -> Get [a] -> Get [a]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> Get [a]
    getElements (Int
    len Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    elementLen)

    processBytes :: Int -> Get a -> Get a
    processBytes :: Int -> Get a -> Get a
    processBytes i :: Int
    i f :: Get a
    f = Int -> Get a -> Get a
    forall a. Int -> Get a -> Get a
    isolate Int
    i Get a
    f

    putWords8 :: [Word8] -> Put
    putWords8 :: [Word8] -> Put
    putWords8 l :: [Word8]
    l = do
        Putter Word8
    putWord8 Putter Word8 -> Putter Word8
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ([Word8] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Word8]
    l)
        Putter Word8 -> [Word8] -> Put
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Putter Word8
    putWord8 [Word8]
    l

    putWord16 :: Word16 -> Put
    putWord16 :: Word16 -> Put
    putWord16 = Word16 -> Put
    putWord16be

    putWord32 :: Word32 -> Put
    putWord32 :: Word32 -> Put
    putWord32 = Word32 -> Put
    putWord32be

    putWord64 :: Word64 -> Put
    putWord64 :: Word64 -> Put
    putWord64 = Word64 -> Put
    putWord64be

    putWords16 :: [Word16] -> Put
    putWords16 :: [Word16] -> Put
    putWords16 l :: [Word16]
    l = do
        Word16 -> Put
    putWord16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ 2 Word16 -> Word16 -> Word16
    forall a. Num a => a -> a -> a
    * Int -> Word16
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ([Word16] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Word16]
    l)
        (Word16 -> Put) -> [Word16] -> Put
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Word16 -> Put
    putWord16 [Word16]
    l

    putWord24 :: Int -> Put
    putWord24 :: Int -> Put
    putWord24 i :: Int
    i = do
        let a :: Word8
    a = Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ((Int
    i Int -> Int -> Int
    forall a. Bits a => a -> Int -> a
    `shiftR` 16) Int -> Int -> Int
    forall a. Bits a => a -> a -> a
    .&. 0xff)
        let b :: Word8
    b = Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ((Int
    i Int -> Int -> Int
    forall a. Bits a => a -> Int -> a
    `shiftR` 8) Int -> Int -> Int
    forall a. Bits a => a -> a -> a
    .&. 0xff)
        let c :: Word8
    c = Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    i Int -> Int -> Int
    forall a. Bits a => a -> a -> a
    .&. 0xff)
        Putter Word8 -> [Word8] -> Put
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Putter Word8
    putWord8 [Word8
    a,Word8
    b,Word8
    c]

    putBytes :: ByteString -> Put
    putBytes :: ByteString -> Put
    putBytes = ByteString -> Put
    putByteString

    putOpaque8 :: ByteString -> Put
    putOpaque8 :: ByteString -> Put
    putOpaque8 b :: ByteString
    b = Putter Word8
    putWord8 (Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word8) -> Int -> Word8
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Int
    B.length ByteString
    b) Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ByteString -> Put
    putBytes ByteString
    b

    putOpaque16 :: ByteString -> Put
    putOpaque16 :: ByteString -> Put
    putOpaque16 b :: ByteString
    b = Word16 -> Put
    putWord16 (Int -> Word16
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word16) -> Int -> Word16
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Int
    B.length ByteString
    b) Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ByteString -> Put
    putBytes ByteString
    b

    putOpaque24 :: ByteString -> Put
    putOpaque24 :: ByteString -> Put
    putOpaque24 b :: ByteString
    b = Int -> Put
    putWord24 (ByteString -> Int
    B.length ByteString
    b) Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ByteString -> Put
    putBytes ByteString
    b

    putInteger16 :: Integer -> Put
    putInteger16 :: Integer -> Put
    putInteger16 = ByteString -> Put
    putOpaque16 (ByteString -> Put) -> (Integer -> ByteString) -> Integer -> Put
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> ByteString
    forall ba. ByteArray ba => Integer -> ba
    i2osp

    putBigNum16 :: BigNum -> Put
    putBigNum16 :: BigNum -> Put
    putBigNum16 (BigNum b :: ByteString
    b) = ByteString -> Put
    putOpaque16 ByteString
    b

    encodeWord16 :: Word16 -> ByteString
    encodeWord16 :: Word16 -> ByteString
    encodeWord16 = Put -> ByteString
    runPut (Put -> ByteString) -> (Word16 -> Put) -> Word16 -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word16 -> Put
    putWord16

    encodeWord32 :: Word32 -> ByteString
    encodeWord32 :: Word32 -> ByteString
    encodeWord32 = Put -> ByteString
    runPut (Put -> ByteString) -> (Word32 -> Put) -> Word32 -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word32 -> Put
    putWord32

    encodeWord64 :: Word64 -> ByteString
    encodeWord64 :: Word64 -> ByteString
    encodeWord64 = Put -> ByteString
    runPut (Put -> ByteString) -> (Word64 -> Put) -> Word64 -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word64 -> Put
    putWord64be