module Network.PeyoTLS.Codec.Hello (
ClHello(..), SvHello(..), SssnId(..),
CipherSuite(..), KeyEx(..), BulkEnc(..),
CmpMtd(..), SignAlg(..), HashAlg(..),
Extension(..), isRnInfo, emptyRnInfo ) where
import Control.Applicative ((<$>), (<*>))
import Data.Word (Word8, Word16)
import qualified Data.ByteString as BS
import qualified Codec.Bytable.BigEndian as B
import Network.PeyoTLS.Codec.Extension (
Extension(..), isRnInfo, emptyRnInfo, SignAlg(..), HashAlg(..) )
import Network.PeyoTLS.CipherSuite (CipherSuite(..), KeyEx(..), BulkEnc(..))
modNm :: String
modNm = "Network.PeyoTLS.Codec.Hello"
data ClHello
= ClHello (Word8, Word8) BS.ByteString SssnId [CipherSuite] [CmpMtd]
(Maybe [Extension])
| ClHelloRaw BS.ByteString
deriving Show
instance B.Bytable ClHello where
decode = B.evalBytableM $ ClHello
<$> ((,) <$> B.head <*> B.head)
<*> B.take 32 <*> (B.take =<< B.take 1)
<*> (flip B.list (B.take 2) =<< B.take 2)
<*> (flip B.list (B.take 1) =<< B.take 1)
<*> do nl <- B.null
if nl then return Nothing else Just <$>
(flip B.list B.parse =<< B.take 2)
encode (ClHello (vj, vn) r sid css cms mel) = BS.concat [
B.encode vj, B.encode vn, B.encode r, B.addLen w8 $ B.encode sid,
B.addLen w16 . BS.concat $ map B.encode css,
B.addLen w8 . BS.concat $ map B.encode cms,
maybe "" (B.addLen w16 . BS.concat . map B.encode) mel ]
encode (ClHelloRaw bs) = bs
data SvHello
= SvHello (Word8, Word8) BS.ByteString SssnId CipherSuite CmpMtd
(Maybe [Extension])
| SvHelloRaw BS.ByteString
deriving Show
instance B.Bytable SvHello where
decode = B.evalBytableM $ SvHello
<$> ((,) <$> B.head <*> B.head)
<*> B.take 32 <*> (B.take =<< B.take 1) <*> B.take 2 <*> B.take 1
<*> do n <- B.null
if n then return Nothing else Just <$>
(flip B.list B.parse =<< B.take 2)
encode (SvHello (vj, vn) r sid cs cm mes) = BS.concat [
B.encode vj, B.encode vn, B.encode r, B.addLen w8 $ B.encode sid,
B.encode cs, B.encode cm,
maybe "" (B.addLen w16 . BS.concat . map B.encode) mes ]
encode (SvHelloRaw sh) = sh
data SssnId = SssnId BS.ByteString deriving Show
instance B.Bytable SssnId where decode = Right . SssnId; encode (SssnId bs) = bs
data CmpMtd = CmpMtdNull | CmpMtdRaw Word8 deriving (Show, Eq)
instance B.Bytable CmpMtd where
decode bs = case BS.unpack bs of
[cm] -> Right $ case cm of 0 -> CmpMtdNull; _ -> CmpMtdRaw cm
_ -> Left $ modNm ++ ": CmpMtd.decode"
encode CmpMtdNull = "\0"
encode (CmpMtdRaw cm) = BS.pack [cm]
w8 :: Word8; w8 = undefined
w16 :: Word16; w16 = undefined