{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE PatternSynonyms #-} {-# OPTIONS_HADDOCK hide #-} -- | The Struct module contains all definitions and values of the TLS -- protocol. module Network.TLS.Struct ( Version (..), CipherData (..), ExtensionID ( .., EID_ServerName, EID_MaxFragmentLength, EID_ClientCertificateUrl, EID_TrustedCAKeys, EID_TruncatedHMAC, EID_StatusRequest, EID_UserMapping, EID_ClientAuthz, EID_ServerAuthz, EID_CertType, EID_SupportedGroups, EID_EcPointFormats, EID_SRP, EID_SignatureAlgorithms, EID_SRTP, EID_Heartbeat, EID_ApplicationLayerProtocolNegotiation, EID_StatusRequestv2, EID_SignedCertificateTimestamp, EID_ClientCertificateType, EID_ServerCertificateType, EID_Padding, EID_EncryptThenMAC, EID_ExtendedMainSecret, EID_SessionTicket, EID_PreSharedKey, EID_EarlyData, EID_SupportedVersions, EID_Cookie, EID_PskKeyExchangeModes, EID_CertificateAuthorities, EID_OidFilters, EID_PostHandshakeAuth, EID_SignatureAlgorithmsCert, EID_KeyShare, EID_QuicTransportParameters, EID_SecureRenegotiation ), ExtensionRaw (..), CertificateType ( CertificateType, CertificateType_RSA_Sign, CertificateType_DSA_Sign, CertificateType_ECDSA_Sign, CertificateType_Ed25519_Sign, CertificateType_Ed448_Sign ), fromCertificateType, lastSupportedCertificateType, HashAlgorithm ( .., HashNone, HashMD5, HashSHA1, HashSHA224, HashSHA256, HashSHA384, HashSHA512, HashIntrinsic ), SignatureAlgorithm ( .., SignatureAnonymous, SignatureRSA, SignatureDSA, SignatureECDSA, SignatureRSApssRSAeSHA256, SignatureRSApssRSAeSHA384, SignatureRSApssRSAeSHA512, SignatureEd25519, SignatureEd448, SignatureRSApsspssSHA256, SignatureRSApsspssSHA384, SignatureRSApsspssSHA512 ), HashAndSignatureAlgorithm, supportedSignatureSchemes, DigitallySigned (..), Signature, ProtocolType ( .., ProtocolType_ChangeCipherSpec, ProtocolType_Alert, ProtocolType_Handshake, ProtocolType_AppData ), TLSError (..), TLSException (..), DistinguishedName, BigNum (..), bigNumToInteger, bigNumFromInteger, ServerDHParams (..), serverDHParamsToParams, serverDHParamsToPublic, serverDHParamsFrom, ServerECDHParams (..), ServerRSAParams (..), ServerKeyXchgAlgorithmData (..), ClientKeyXchgAlgorithmData (..), Packet (..), Header (..), ServerRandom (..), ClientRandom (..), FinishedData, VerifyData, SessionID, Session (..), SessionData (..), AlertLevel ( .., AlertLevel_Warning, AlertLevel_Fatal ), AlertDescription ( .., CloseNotify, UnexpectedMessage, BadRecordMac, DecryptionFailed, RecordOverflow, DecompressionFailure, HandshakeFailure, BadCertificate, UnsupportedCertificate, CertificateRevoked, CertificateExpired, CertificateUnknown, IllegalParameter, UnknownCa, AccessDenied, DecodeError, DecryptError, ExportRestriction, ProtocolVersion, InsufficientSecurity, InternalError, InappropriateFallback, UserCanceled, NoRenegotiation, MissingExtension, UnsupportedExtension, CertificateUnobtainable, UnrecognizedName, BadCertificateStatusResponse, BadCertificateHashValue, UnknownPskIdentity, CertificateRequired, NoApplicationProtocol ), HandshakeType ( .., HandshakeType_HelloRequest, HandshakeType_ClientHello, HandshakeType_ServerHello, HandshakeType_NewSessionTicket, HandshakeType_EndOfEarlyData, HandshakeType_EncryptedExtensions, HandshakeType_Certificate, HandshakeType_ServerKeyXchg, HandshakeType_CertRequest, HandshakeType_ServerHelloDone, HandshakeType_CertVerify, HandshakeType_ClientKeyXchg, HandshakeType_Finished, HandshakeType_KeyUpdate ), Handshake (..), CH (..), packetType, typeOfHandshake, ) where import Control.Exception (Exception (..)) import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Char8 as C8 import Data.Typeable import Data.X509 (CertificateChain, DistinguishedName) import Network.TLS.Crypto import Network.TLS.Imports import Network.TLS.Types import Network.TLS.Util.Serialization ---------------------------------------------------------------- data CipherData = CipherData { cipherDataContent :: ByteString , cipherDataMAC :: Maybe ByteString , cipherDataPadding :: Maybe (ByteString, Int) } deriving (Show, Eq) ---------------------------------------------------------------- -- | Some of the IANA registered code points for 'CertificateType' are not -- currently supported by the library. Nor should they be, they're are either -- unwise, obsolete or both. There's no point in conveying these to the user -- in the client certificate request callback. The request callback will be -- filtered to exclude unsupported values. If the user cannot find a certificate -- for a supported code point, we'll go ahead without a client certificate and -- hope for the best, unless the user's callback decides to throw an exception. newtype CertificateType = CertificateType {fromCertificateType :: Word8} deriving (Eq, Ord) {- FOURMOLU_DISABLE -} -- | TLS10 and up, RFC5246 pattern CertificateType_RSA_Sign :: CertificateType pattern CertificateType_RSA_Sign = CertificateType 1 -- | TLS10 and up, RFC5246 pattern CertificateType_DSA_Sign :: CertificateType pattern CertificateType_DSA_Sign = CertificateType 2 -- | TLS10 and up, RFC8422 pattern CertificateType_ECDSA_Sign :: CertificateType pattern CertificateType_ECDSA_Sign = CertificateType 64 -- \| There are no code points that map to the below synthetic types, these -- are inferred indirectly from the @signature_algorithms@ extension of the -- TLS 1.3 @CertificateRequest@ message. the value assignments are there -- only to avoid partial function warnings. pattern CertificateType_Ed25519_Sign :: CertificateType pattern CertificateType_Ed25519_Sign = CertificateType 254 -- fixme: dummy value pattern CertificateType_Ed448_Sign :: CertificateType pattern CertificateType_Ed448_Sign = CertificateType 255 -- fixme: dummy value instance Show CertificateType where show CertificateType_RSA_Sign = "CertificateType_RSA_Sign" show CertificateType_DSA_Sign = "CertificateType_DSA_Sign" show CertificateType_ECDSA_Sign = "CertificateType_ECDSA_Sign" show CertificateType_Ed25519_Sign = "CertificateType_Ed25519_Sign" show CertificateType_Ed448_Sign = "CertificateType_Ed448_Sign" show (CertificateType x) = "CertificateType " ++ show x {- FOURMOLU_ENABLE -} -- | Last supported certificate type, no 'CertificateType that -- compares greater than this one (based on the 'Ord' instance, -- not on the wire code point) will be reported to the application -- via the client certificate request callback. lastSupportedCertificateType :: CertificateType lastSupportedCertificateType = CertificateType_ECDSA_Sign ------------------------------------------------------------ newtype HashAlgorithm = HashAlgorithm {fromHashAlgorithm :: Word8} deriving (Eq) {- FOURMOLU_DISABLE -} pattern HashNone :: HashAlgorithm pattern HashNone = HashAlgorithm 0 pattern HashMD5 :: HashAlgorithm pattern HashMD5 = HashAlgorithm 1 pattern HashSHA1 :: HashAlgorithm pattern HashSHA1 = HashAlgorithm 2 pattern HashSHA224 :: HashAlgorithm pattern HashSHA224 = HashAlgorithm 3 pattern HashSHA256 :: HashAlgorithm pattern HashSHA256 = HashAlgorithm 4 pattern HashSHA384 :: HashAlgorithm pattern HashSHA384 = HashAlgorithm 5 pattern HashSHA512 :: HashAlgorithm pattern HashSHA512 = HashAlgorithm 6 pattern HashIntrinsic :: HashAlgorithm pattern HashIntrinsic = HashAlgorithm 8 instance Show HashAlgorithm where show HashNone = "HashNone" show HashMD5 = "HashMD5" show HashSHA1 = "HashSHA1" show HashSHA224 = "HashSHA224" show HashSHA256 = "HashSHA256" show HashSHA384 = "HashSHA384" show HashSHA512 = "HashSHA512" show HashIntrinsic = "HashIntrinsic" show (HashAlgorithm x) = "HashAlgorithm " ++ show x {- FOURMOLU_ENABLE -} ------------------------------------------------------------ newtype SignatureAlgorithm = SignatureAlgorithm {fromSignatureAlgorithm :: Word8} deriving (Eq) {- FOURMOLU_DISABLE -} pattern SignatureAnonymous :: SignatureAlgorithm pattern SignatureAnonymous = SignatureAlgorithm 0 pattern SignatureRSA :: SignatureAlgorithm pattern SignatureRSA = SignatureAlgorithm 1 pattern SignatureDSA :: SignatureAlgorithm pattern SignatureDSA = SignatureAlgorithm 2 pattern SignatureECDSA :: SignatureAlgorithm pattern SignatureECDSA = SignatureAlgorithm 3 -- TLS 1.3 from here pattern SignatureRSApssRSAeSHA256 :: SignatureAlgorithm pattern SignatureRSApssRSAeSHA256 = SignatureAlgorithm 4 pattern SignatureRSApssRSAeSHA384 :: SignatureAlgorithm pattern SignatureRSApssRSAeSHA384 = SignatureAlgorithm 5 pattern SignatureRSApssRSAeSHA512 :: SignatureAlgorithm pattern SignatureRSApssRSAeSHA512 = SignatureAlgorithm 6 pattern SignatureEd25519 :: SignatureAlgorithm pattern SignatureEd25519 = SignatureAlgorithm 7 pattern SignatureEd448 :: SignatureAlgorithm pattern SignatureEd448 = SignatureAlgorithm 8 pattern SignatureRSApsspssSHA256 :: SignatureAlgorithm pattern SignatureRSApsspssSHA256 = SignatureAlgorithm 9 pattern SignatureRSApsspssSHA384 :: SignatureAlgorithm pattern SignatureRSApsspssSHA384 = SignatureAlgorithm 10 pattern SignatureRSApsspssSHA512 :: SignatureAlgorithm pattern SignatureRSApsspssSHA512 = SignatureAlgorithm 11 instance Show SignatureAlgorithm where show SignatureAnonymous = "SignatureAnonymous" show SignatureRSA = "SignatureRSA" show SignatureDSA = "SignatureDSA" show SignatureECDSA = "SignatureECDSA" show SignatureRSApssRSAeSHA256 = "SignatureRSApssRSAeSHA256" show SignatureRSApssRSAeSHA384 = "SignatureRSApssRSAeSHA384" show SignatureRSApssRSAeSHA512 = "SignatureRSApssRSAeSHA512" show SignatureEd25519 = "SignatureEd25519" show SignatureEd448 = "SignatureEd448" show SignatureRSApsspssSHA256 = "SignatureRSApsspssSHA256" show SignatureRSApsspssSHA384 = "SignatureRSApsspssSHA384" show SignatureRSApsspssSHA512 = "SignatureRSApsspssSHA512" show (SignatureAlgorithm x) = "SignatureAlgorithm " ++ show x {- FOURMOLU_ENABLE -} ------------------------------------------------------------ type HashAndSignatureAlgorithm = (HashAlgorithm, SignatureAlgorithm) {- FOURMOLU_DISABLE -} supportedSignatureSchemes :: [HashAndSignatureAlgorithm] supportedSignatureSchemes = -- EdDSA algorithms [ (HashIntrinsic, SignatureEd448) -- ed448 (0x0808) , (HashIntrinsic, SignatureEd25519) -- ed25519(0x0807) -- ECDSA algorithms , (HashSHA256, SignatureECDSA) -- ecdsa_secp256r1_sha256(0x0403) , (HashSHA384, SignatureECDSA) -- ecdsa_secp384r1_sha384(0x0503) , (HashSHA512, SignatureECDSA) -- ecdsa_secp256r1_sha256(0x0403) -- RSASSA-PSS algorithms with public key OID RSASSA-PSS , (HashIntrinsic, SignatureRSApssRSAeSHA512) -- rsa_pss_pss_sha512(0x080b) , (HashIntrinsic, SignatureRSApssRSAeSHA384) -- rsa_pss_pss_sha384(0x080a) , (HashIntrinsic, SignatureRSApssRSAeSHA256) -- rsa_pss_pss_sha256(0x0809) -- RSASSA-PKCS1-v1_5 algorithms , (HashSHA512, SignatureRSA) -- rsa_pkcs1_sha512(0x0601) , (HashSHA384, SignatureRSA) -- rsa_pkcs1_sha384(0x0501) , (HashSHA256, SignatureRSA) -- rsa_pkcs1_sha256(0x0401) -- Legacy algorithms , (HashSHA1, SignatureRSA) -- rsa_pkcs1_sha1 (0x0201) , (HashSHA1, SignatureECDSA) -- ecdsa_sha1 (0x0203) ] {- FOURMOLU_ENABLE -} ------------------------------------------------------------ type Signature = ByteString data DigitallySigned = DigitallySigned HashAndSignatureAlgorithm Signature deriving (Show, Eq) ---------------------------------------------------------------- newtype ProtocolType = ProtocolType {fromProtocolType :: Word8} deriving (Eq) {- FOURMOLU_DISABLE -} pattern ProtocolType_ChangeCipherSpec :: ProtocolType pattern ProtocolType_ChangeCipherSpec = ProtocolType 20 pattern ProtocolType_Alert :: ProtocolType pattern ProtocolType_Alert = ProtocolType 21 pattern ProtocolType_Handshake :: ProtocolType pattern ProtocolType_Handshake = ProtocolType 22 pattern ProtocolType_AppData :: ProtocolType pattern ProtocolType_AppData = ProtocolType 23 instance Show ProtocolType where show ProtocolType_ChangeCipherSpec = "ChangeCipherSpec" show ProtocolType_Alert = "Alert" show ProtocolType_Handshake = "Handshake" show ProtocolType_AppData = "AppData" show (ProtocolType x) = "ProtocolType " ++ show x {- FOURMOLU_ENABLE -} ---------------------------------------------------------------- -- | TLSError that might be returned through the TLS stack. -- -- Prior to version 1.8.0, this type had an @Exception@ instance. -- In version 1.8.0, this instance was removed, and functions in -- this library now only throw 'TLSException'. data TLSError = -- | mainly for instance of Error Error_Misc String | -- | A fatal error condition was encountered at a low level. The -- elements of the tuple give (freeform text description, structured -- error description). Error_Protocol String AlertDescription | -- | A non-fatal error condition was encountered at a low level at a low -- level. The elements of the tuple give (freeform text description, -- structured error description). Error_Protocol_Warning String AlertDescription | Error_Certificate String | -- | handshake policy failed. Error_HandshakePolicy String | Error_EOF | Error_Packet String | Error_Packet_unexpected String String | Error_Packet_Parsing String deriving (Eq, Show, Typeable) ---------------------------------------------------------------- -- | TLS Exceptions. Some of the data constructors indicate incorrect use of -- the library, and the documentation for those data constructors calls -- this out. The others wrap 'TLSError' with some kind of context to explain -- when the exception occurred. data TLSException = -- | Early termination exception with the reason and the error associated Terminated Bool String TLSError | -- | Handshake failed for the reason attached. HandshakeFailed TLSError | -- | Failure occurred while sending or receiving data after the -- TLS handshake succeeded. PostHandshake TLSError | -- | Lifts a 'TLSError' into 'TLSException' without provided any context -- around when the error happened. Uncontextualized TLSError | -- | Usage error when the connection has not been established -- and the user is trying to send or receive data. -- Indicates that this library has been used incorrectly. ConnectionNotEstablished | -- | Expected that a TLS handshake had already taken place, but no TLS -- handshake had occurred. -- Indicates that this library has been used incorrectly. MissingHandshake deriving (Show, Eq, Typeable) instance Exception TLSException ---------------------------------------------------------------- data Packet = Handshake [Handshake] | Alert [(AlertLevel, AlertDescription)] | ChangeCipherSpec | AppData ByteString deriving (Eq) instance Show Packet where show (Handshake hs) = "Handshake " ++ show hs show (Alert as) = "Alert " ++ show as show ChangeCipherSpec = "ChangeCipherSpec" show (AppData bs) = "AppData " ++ C8.unpack (B16.encode bs) data Header = Header ProtocolType Version Word16 deriving (Show, Eq) newtype ServerRandom = ServerRandom {unServerRandom :: ByteString} deriving (Show, Eq) newtype ClientRandom = ClientRandom {unClientRandom :: ByteString} deriving (Show, Eq) newtype Session = Session (Maybe SessionID) deriving (Show, Eq) {-# DEPRECATED FinishedData "use VerifyData" #-} type FinishedData = ByteString type VerifyData = ByteString ---------------------------------------------------------------- -- | Identifier of a TLS extension. -- newtype ExtensionID = ExtensionID {fromExtensionID :: Word16} deriving (Eq) {- FOURMOLU_DISABLE -} pattern EID_ServerName :: ExtensionID -- RFC6066 pattern EID_ServerName = ExtensionID 0x0 pattern EID_MaxFragmentLength :: ExtensionID -- RFC6066 pattern EID_MaxFragmentLength = ExtensionID 0x1 pattern EID_ClientCertificateUrl :: ExtensionID -- RFC6066 pattern EID_ClientCertificateUrl = ExtensionID 0x2 pattern EID_TrustedCAKeys :: ExtensionID -- RFC6066 pattern EID_TrustedCAKeys = ExtensionID 0x3 pattern EID_TruncatedHMAC :: ExtensionID -- RFC6066 pattern EID_TruncatedHMAC = ExtensionID 0x4 pattern EID_StatusRequest :: ExtensionID -- RFC6066 pattern EID_StatusRequest = ExtensionID 0x5 pattern EID_UserMapping :: ExtensionID -- RFC4681 pattern EID_UserMapping = ExtensionID 0x6 pattern EID_ClientAuthz :: ExtensionID -- RFC5878 pattern EID_ClientAuthz = ExtensionID 0x7 pattern EID_ServerAuthz :: ExtensionID -- RFC5878 pattern EID_ServerAuthz = ExtensionID 0x8 pattern EID_CertType :: ExtensionID -- RFC6091 pattern EID_CertType = ExtensionID 0x9 pattern EID_SupportedGroups :: ExtensionID -- RFC8422,8446 pattern EID_SupportedGroups = ExtensionID 0xa pattern EID_EcPointFormats :: ExtensionID -- RFC4492 pattern EID_EcPointFormats = ExtensionID 0xb pattern EID_SRP :: ExtensionID -- RFC5054 pattern EID_SRP = ExtensionID 0xc pattern EID_SignatureAlgorithms :: ExtensionID -- RFC5246,8446 pattern EID_SignatureAlgorithms = ExtensionID 0xd pattern EID_SRTP :: ExtensionID -- RFC5764 pattern EID_SRTP = ExtensionID 0xe pattern EID_Heartbeat :: ExtensionID -- RFC6520 pattern EID_Heartbeat = ExtensionID 0xf pattern EID_ApplicationLayerProtocolNegotiation :: ExtensionID -- RFC7301 pattern EID_ApplicationLayerProtocolNegotiation = ExtensionID 0x10 pattern EID_StatusRequestv2 :: ExtensionID -- RFC6961 pattern EID_StatusRequestv2 = ExtensionID 0x11 pattern EID_SignedCertificateTimestamp :: ExtensionID -- RFC6962 pattern EID_SignedCertificateTimestamp = ExtensionID 0x12 pattern EID_ClientCertificateType :: ExtensionID -- RFC7250 pattern EID_ClientCertificateType = ExtensionID 0x13 pattern EID_ServerCertificateType :: ExtensionID -- RFC7250 pattern EID_ServerCertificateType = ExtensionID 0x14 pattern EID_Padding :: ExtensionID -- RFC5246 pattern EID_Padding = ExtensionID 0x15 pattern EID_EncryptThenMAC :: ExtensionID -- RFC7366 pattern EID_EncryptThenMAC = ExtensionID 0x16 pattern EID_ExtendedMainSecret :: ExtensionID -- REF7627 pattern EID_ExtendedMainSecret = ExtensionID 0x17 pattern EID_SessionTicket :: ExtensionID -- RFC4507 pattern EID_SessionTicket = ExtensionID 0x23 pattern EID_PreSharedKey :: ExtensionID -- RFC8446 pattern EID_PreSharedKey = ExtensionID 0x29 pattern EID_EarlyData :: ExtensionID -- RFC8446 pattern EID_EarlyData = ExtensionID 0x2a pattern EID_SupportedVersions :: ExtensionID -- RFC8446 pattern EID_SupportedVersions = ExtensionID 0x2b pattern EID_Cookie :: ExtensionID -- RFC8446 pattern EID_Cookie = ExtensionID 0x2c pattern EID_PskKeyExchangeModes :: ExtensionID -- RFC8446 pattern EID_PskKeyExchangeModes = ExtensionID 0x2d pattern EID_CertificateAuthorities :: ExtensionID -- RFC8446 pattern EID_CertificateAuthorities = ExtensionID 0x2f pattern EID_OidFilters :: ExtensionID -- RFC8446 pattern EID_OidFilters = ExtensionID 0x30 pattern EID_PostHandshakeAuth :: ExtensionID -- RFC8446 pattern EID_PostHandshakeAuth = ExtensionID 0x31 pattern EID_SignatureAlgorithmsCert :: ExtensionID -- RFC8446 pattern EID_SignatureAlgorithmsCert = ExtensionID 0x32 pattern EID_KeyShare :: ExtensionID -- RFC8446 pattern EID_KeyShare = ExtensionID 0x33 pattern EID_QuicTransportParameters :: ExtensionID -- RFC9001 pattern EID_QuicTransportParameters = ExtensionID 0x39 pattern EID_SecureRenegotiation :: ExtensionID -- RFC5746 pattern EID_SecureRenegotiation = ExtensionID 0xff01 instance Show ExtensionID where show EID_ServerName = "ServerName" show EID_MaxFragmentLength = "MaxFragmentLength" show EID_ClientCertificateUrl = "ClientCertificateUrl" show EID_TrustedCAKeys = "TrustedCAKeys" show EID_TruncatedHMAC = "TruncatedHMAC" show EID_StatusRequest = "StatusRequest" show EID_UserMapping = "UserMapping" show EID_ClientAuthz = "ClientAuthz" show EID_ServerAuthz = "ServerAuthz" show EID_CertType = "CertType" show EID_SupportedGroups = "SupportedGroups" show EID_EcPointFormats = "EcPointFormats" show EID_SRP = "SRP" show EID_SignatureAlgorithms = "SignatureAlgorithms" show EID_SRTP = "SRTP" show EID_Heartbeat = "Heartbeat" show EID_ApplicationLayerProtocolNegotiation = "ApplicationLayerProtocolNegotiation" show EID_StatusRequestv2 = "StatusRequestv2" show EID_SignedCertificateTimestamp = "SignedCertificateTimestamp" show EID_ClientCertificateType = "ClientCertificateType" show EID_ServerCertificateType = "ServerCertificateType" show EID_Padding = "Padding" show EID_EncryptThenMAC = "EncryptThenMAC" show EID_ExtendedMainSecret = "ExtendedMainSecret" show EID_SessionTicket = "SessionTicket" show EID_PreSharedKey = "PreSharedKey" show EID_EarlyData = "EarlyData" show EID_SupportedVersions = "SupportedVersions" show EID_Cookie = "Cookie" show EID_PskKeyExchangeModes = "PskKeyExchangeModes" show EID_CertificateAuthorities = "CertificateAuthorities" show EID_OidFilters = "OidFilters" show EID_PostHandshakeAuth = "PostHandshakeAuth" show EID_SignatureAlgorithmsCert = "SignatureAlgorithmsCert" show EID_KeyShare = "KeyShare" show EID_QuicTransportParameters = "QuicTransportParameters" show EID_SecureRenegotiation = "SecureRenegotiation" show (ExtensionID x) = "ExtensionID " ++ show x {- FOURMOLU_ENABLE -} ---------------------------------------------------------------- -- | The raw content of a TLS extension. data ExtensionRaw = ExtensionRaw ExtensionID ByteString deriving (Eq) instance Show ExtensionRaw where show (ExtensionRaw eid bs) = "ExtensionRaw " ++ show eid ++ " " ++ showBytesHex bs ---------------------------------------------------------------- newtype AlertLevel = AlertLevel {fromAlertLevel :: Word8} deriving (Eq) {- FOURMOLU_DISABLE -} pattern AlertLevel_Warning :: AlertLevel pattern AlertLevel_Warning = AlertLevel 1 pattern AlertLevel_Fatal :: AlertLevel pattern AlertLevel_Fatal = AlertLevel 2 instance Show AlertLevel where show AlertLevel_Warning = "AlertLevel_Warning" show AlertLevel_Fatal = "AlertLevel_Fatal" show (AlertLevel x) = "AlertLevel " ++ show x {- FOURMOLU_ENABLE -} ---------------------------------------------------------------- newtype AlertDescription = AlertDescription {fromAlertDescription :: Word8} deriving (Eq) {- FOURMOLU_DISABLE -} pattern CloseNotify :: AlertDescription pattern CloseNotify = AlertDescription 0 pattern UnexpectedMessage :: AlertDescription pattern UnexpectedMessage = AlertDescription 10 pattern BadRecordMac :: AlertDescription pattern BadRecordMac = AlertDescription 20 pattern DecryptionFailed :: AlertDescription pattern DecryptionFailed = AlertDescription 21 pattern RecordOverflow :: AlertDescription pattern RecordOverflow = AlertDescription 22 pattern DecompressionFailure :: AlertDescription pattern DecompressionFailure = AlertDescription 30 pattern HandshakeFailure :: AlertDescription pattern HandshakeFailure = AlertDescription 40 pattern BadCertificate :: AlertDescription pattern BadCertificate = AlertDescription 42 pattern UnsupportedCertificate :: AlertDescription pattern UnsupportedCertificate = AlertDescription 43 pattern CertificateRevoked :: AlertDescription pattern CertificateRevoked = AlertDescription 44 pattern CertificateExpired :: AlertDescription pattern CertificateExpired = AlertDescription 45 pattern CertificateUnknown :: AlertDescription pattern CertificateUnknown = AlertDescription 46 pattern IllegalParameter :: AlertDescription pattern IllegalParameter = AlertDescription 47 pattern UnknownCa :: AlertDescription pattern UnknownCa = AlertDescription 48 pattern AccessDenied :: AlertDescription pattern AccessDenied = AlertDescription 49 pattern DecodeError :: AlertDescription pattern DecodeError = AlertDescription 50 pattern DecryptError :: AlertDescription pattern DecryptError = AlertDescription 51 pattern ExportRestriction :: AlertDescription pattern ExportRestriction = AlertDescription 60 pattern ProtocolVersion :: AlertDescription pattern ProtocolVersion = AlertDescription 70 pattern InsufficientSecurity :: AlertDescription pattern InsufficientSecurity = AlertDescription 71 pattern InternalError :: AlertDescription pattern InternalError = AlertDescription 80 pattern InappropriateFallback :: AlertDescription pattern InappropriateFallback = AlertDescription 86 -- RFC7507 pattern UserCanceled :: AlertDescription pattern UserCanceled = AlertDescription 90 pattern NoRenegotiation :: AlertDescription pattern NoRenegotiation = AlertDescription 100 pattern MissingExtension :: AlertDescription pattern MissingExtension = AlertDescription 109 pattern UnsupportedExtension :: AlertDescription pattern UnsupportedExtension = AlertDescription 110 pattern CertificateUnobtainable :: AlertDescription pattern CertificateUnobtainable = AlertDescription 111 pattern UnrecognizedName :: AlertDescription pattern UnrecognizedName = AlertDescription 112 pattern BadCertificateStatusResponse :: AlertDescription pattern BadCertificateStatusResponse = AlertDescription 113 pattern BadCertificateHashValue :: AlertDescription pattern BadCertificateHashValue = AlertDescription 114 pattern UnknownPskIdentity :: AlertDescription pattern UnknownPskIdentity = AlertDescription 115 pattern CertificateRequired :: AlertDescription pattern CertificateRequired = AlertDescription 116 pattern GeneralError :: AlertDescription pattern GeneralError = AlertDescription 117 pattern NoApplicationProtocol :: AlertDescription pattern NoApplicationProtocol = AlertDescription 120 -- RFC7301 instance Show AlertDescription where show CloseNotify = "CloseNotify" show UnexpectedMessage = "UnexpectedMessage" show BadRecordMac = "BadRecordMac" show DecryptionFailed = "DecryptionFailed" show RecordOverflow = "RecordOverflow" show DecompressionFailure = "DecompressionFailure" show HandshakeFailure = "HandshakeFailure" show BadCertificate = "BadCertificate" show UnsupportedCertificate = "UnsupportedCertificate" show CertificateRevoked = "CertificateRevoked" show CertificateExpired = "CertificateExpired" show CertificateUnknown = "CertificateUnknown" show IllegalParameter = "IllegalParameter" show UnknownCa = "UnknownCa" show AccessDenied = "AccessDenied" show DecodeError = "DecodeError" show DecryptError = "DecryptError" show ExportRestriction = "ExportRestriction" show ProtocolVersion = "ProtocolVersion" show InsufficientSecurity = "InsufficientSecurity" show InternalError = "InternalError" show InappropriateFallback = "InappropriateFallback" show UserCanceled = "UserCanceled" show NoRenegotiation = "NoRenegotiation" show MissingExtension = "MissingExtension" show UnsupportedExtension = "UnsupportedExtension" show CertificateUnobtainable = "CertificateUnobtainable" show UnrecognizedName = "UnrecognizedName" show BadCertificateStatusResponse = "BadCertificateStatusResponse" show BadCertificateHashValue = "BadCertificateHashValue" show UnknownPskIdentity = "UnknownPskIdentity" show CertificateRequired = "CertificateRequired" show GeneralError = "GeneralError" show NoApplicationProtocol = "NoApplicationProtocol" show (AlertDescription x) = "AlertDescription " ++ show x {- FOURMOLU_ENABLE -} ---------------------------------------------------------------- newtype HandshakeType = HandshakeType {fromHandshakeType :: Word8} deriving (Eq) {- FOURMOLU_DISABLE -} pattern HandshakeType_HelloRequest :: HandshakeType pattern HandshakeType_HelloRequest = HandshakeType 0 pattern HandshakeType_ClientHello :: HandshakeType pattern HandshakeType_ClientHello = HandshakeType 1 pattern HandshakeType_ServerHello :: HandshakeType pattern HandshakeType_ServerHello = HandshakeType 2 pattern HandshakeType_NewSessionTicket :: HandshakeType pattern HandshakeType_NewSessionTicket = HandshakeType 4 pattern HandshakeType_EndOfEarlyData :: HandshakeType pattern HandshakeType_EndOfEarlyData = HandshakeType 5 pattern HandshakeType_EncryptedExtensions :: HandshakeType pattern HandshakeType_EncryptedExtensions = HandshakeType 8 pattern HandshakeType_Certificate :: HandshakeType pattern HandshakeType_Certificate = HandshakeType 11 pattern HandshakeType_ServerKeyXchg :: HandshakeType pattern HandshakeType_ServerKeyXchg = HandshakeType 12 pattern HandshakeType_CertRequest :: HandshakeType pattern HandshakeType_CertRequest = HandshakeType 13 pattern HandshakeType_ServerHelloDone :: HandshakeType pattern HandshakeType_ServerHelloDone = HandshakeType 14 pattern HandshakeType_CertVerify :: HandshakeType pattern HandshakeType_CertVerify = HandshakeType 15 pattern HandshakeType_ClientKeyXchg :: HandshakeType pattern HandshakeType_ClientKeyXchg = HandshakeType 16 pattern HandshakeType_Finished :: HandshakeType pattern HandshakeType_Finished = HandshakeType 20 pattern HandshakeType_KeyUpdate :: HandshakeType pattern HandshakeType_KeyUpdate = HandshakeType 24 instance Show HandshakeType where show HandshakeType_HelloRequest = "HandshakeType_HelloRequest" show HandshakeType_ClientHello = "HandshakeType_ClientHello" show HandshakeType_ServerHello = "HandshakeType_ServerHello" show HandshakeType_Certificate = "HandshakeType_Certificate" show HandshakeType_ServerKeyXchg = "HandshakeType_ServerKeyXchg" show HandshakeType_CertRequest = "HandshakeType_CertRequest" show HandshakeType_ServerHelloDone = "HandshakeType_ServerHelloDone" show HandshakeType_CertVerify = "HandshakeType_CertVerify" show HandshakeType_ClientKeyXchg = "HandshakeType_ClientKeyXchg" show HandshakeType_Finished = "HandshakeType_Finished" show HandshakeType_NewSessionTicket = "HandshakeType_NewSessionTicket" show (HandshakeType x) = "HandshakeType " ++ show x {- FOURMOLU_ENABLE -} ---------------------------------------------------------------- newtype BigNum = BigNum ByteString deriving (Show, Eq) bigNumToInteger :: BigNum -> Integer bigNumToInteger (BigNum b) = os2ip b bigNumFromInteger :: Integer -> BigNum bigNumFromInteger i = BigNum $ i2osp i ---------------------------------------------------------------- data ServerDHParams = ServerDHParams { serverDHParams_p :: BigNum , serverDHParams_g :: BigNum , serverDHParams_y :: BigNum } deriving (Show, Eq) serverDHParamsFrom :: DHParams -> DHPublic -> ServerDHParams serverDHParamsFrom params dhPub = ServerDHParams (bigNumFromInteger $ dhParamsGetP params) (bigNumFromInteger $ dhParamsGetG params) (bigNumFromInteger $ dhUnwrapPublic dhPub) serverDHParamsToParams :: ServerDHParams -> DHParams serverDHParamsToParams serverParams = dhParams (bigNumToInteger $ serverDHParams_p serverParams) (bigNumToInteger $ serverDHParams_g serverParams) serverDHParamsToPublic :: ServerDHParams -> DHPublic serverDHParamsToPublic serverParams = dhPublic (bigNumToInteger $ serverDHParams_y serverParams) ---------------------------------------------------------------- data ServerECDHParams = ServerECDHParams Group GroupPublic deriving (Show, Eq) ---------------------------------------------------------------- data ServerRSAParams = ServerRSAParams { rsa_modulus :: Integer , rsa_exponent :: Integer } deriving (Show, Eq) ---------------------------------------------------------------- data ServerDSAParams = ServerDSAParams deriving (Show, Eq) ---------------------------------------------------------------- data ServerKeyXchgAlgorithmData = SKX_DH_Anon ServerDHParams | SKX_DHE_DSA ServerDHParams DigitallySigned | SKX_DHE_RSA ServerDHParams DigitallySigned | SKX_ECDHE_RSA ServerECDHParams DigitallySigned | SKX_ECDHE_ECDSA ServerECDHParams DigitallySigned | SKX_RSA (Maybe ServerRSAParams) | SKX_DH_DSA (Maybe ServerDSAParams) | SKX_DH_RSA (Maybe ServerRSAParams) | SKX_Unparsed ByteString -- if we parse the server key xchg before knowing the actual cipher, we end up with this structure. | SKX_Unknown ByteString deriving (Show, Eq) ---------------------------------------------------------------- data ClientKeyXchgAlgorithmData = CKX_RSA ByteString | CKX_DH DHPublic | CKX_ECDH ByteString deriving (Show, Eq) ---------------------------------------------------------------- data CH = CH { chSession :: Session , chCiphers :: [CipherID] , chExtensions :: [ExtensionRaw] } deriving (Show, Eq) data Handshake = ClientHello Version ClientRandom [CompressionID] CH | ServerHello Version ServerRandom Session CipherID CompressionID [ExtensionRaw] | Certificate CertificateChain | HelloRequest | ServerHelloDone | ClientKeyXchg ClientKeyXchgAlgorithmData | ServerKeyXchg ServerKeyXchgAlgorithmData | CertRequest [CertificateType] [HashAndSignatureAlgorithm] [DistinguishedName] | CertVerify DigitallySigned | Finished VerifyData | NewSessionTicket Second Ticket deriving (Show, Eq) {- FOURMOLU_DISABLE -} packetType :: Packet -> ProtocolType packetType (Handshake _) = ProtocolType_Handshake packetType (Alert _) = ProtocolType_Alert packetType ChangeCipherSpec = ProtocolType_ChangeCipherSpec packetType (AppData _) = ProtocolType_AppData typeOfHandshake :: Handshake -> HandshakeType typeOfHandshake ClientHello{} = HandshakeType_ClientHello typeOfHandshake ServerHello{} = HandshakeType_ServerHello typeOfHandshake Certificate{} = HandshakeType_Certificate typeOfHandshake HelloRequest = HandshakeType_HelloRequest typeOfHandshake ServerHelloDone = HandshakeType_ServerHelloDone typeOfHandshake ClientKeyXchg{} = HandshakeType_ClientKeyXchg typeOfHandshake ServerKeyXchg{} = HandshakeType_ServerKeyXchg typeOfHandshake CertRequest{} = HandshakeType_CertRequest typeOfHandshake CertVerify{} = HandshakeType_CertVerify typeOfHandshake Finished{} = HandshakeType_Finished typeOfHandshake NewSessionTicket{} = HandshakeType_NewSessionTicket {- FOURMOLU_ENABLE -}