0 | module Network.TLS.Record
6 | import public Network.TLS.HelloExtension
7 | import public Network.TLS.Handshake
8 | import public Network.TLS.Magic
9 | import public Network.TLS.Parsing
10 | import public Network.TLS.Wrapper
13 | data Record : RecordType -> Type where
14 | ChangeCipherSpec : (body : List Bits8) -> Record ChangeCipherSpec
15 | Handshake : (handshakes : List (DPair _ Handshake)) -> Record Handshake
16 | ApplicationData : (body : List Bits8) -> Record ApplicationData
17 | Alert : (AlertLevel, AlertDescription) -> Record Alert
20 | Show (Record type) where
21 | show (ChangeCipherSpec body) = show_record "ChangeCipherSpec"
22 | [ ("body", xxd body)
24 | show (Handshake handshakes) = show_record "Handshake"
25 | [ ("handshakes", show (map (\x => show x.snd) handshakes))
27 | show (ApplicationData body) = show_record "ApplicationData"
28 | [ ("body", xxd body)
30 | show (Alert (lvl, desc)) = show_record "Alert"
31 | [ ("alert_level", show lvl)
32 | , ("alert", show desc)
36 | XRecord = Eithers [Record ChangeCipherSpec, Record Handshake, Record ApplicationData, Record Alert]
38 | hack_record : DPair _ Record -> XRecord
39 | hack_record (
ChangeCipherSpec ** x)
= Left x
40 | hack_record (
Handshake ** x)
= Right (Left x)
41 | hack_record (
ApplicationData ** x)
= Right (Right (Left x))
42 | hack_record (
Alert ** x)
= Right (Right (Right x))
44 | fix_record : XRecord -> DPair _ Record
45 | fix_record (Left x) = (
ChangeCipherSpec ** x)
46 | fix_record (Right (Left x)) = (
Handshake ** x)
47 | fix_record (Right (Right (Left x))) = (
ApplicationData ** x)
48 | fix_record (Right (Right (Right x))) = (
Alert ** x)
50 | XRecordWithVersion : Type
51 | XRecordWithVersion = Eithers
52 | [ (TLSVersion, Record ChangeCipherSpec)
53 | , (TLSVersion, Record Handshake)
54 | , (TLSVersion, Record ApplicationData)
55 | , (TLSVersion, Record Alert)
58 | hack_record_with_version : (TLSVersion, DPair _ Record) -> XRecordWithVersion
59 | hack_record_with_version (v, (
ChangeCipherSpec ** x)
) = Left (v, x)
60 | hack_record_with_version (v, (
Handshake ** x)
) = Right (Left (v, x))
61 | hack_record_with_version (v, (
ApplicationData ** x)
) = Right (Right (Left (v, x)))
62 | hack_record_with_version (v, (
Alert ** x)
) = Right (Right (Right (v, x)))
64 | fix_record_with_version : XRecordWithVersion -> (TLSVersion, DPair _ Record)
65 | fix_record_with_version (Left (v, x)) = (v, (
ChangeCipherSpec ** x)
)
66 | fix_record_with_version (Right (Left (v, x))) = (v, (
Handshake ** x)
)
67 | fix_record_with_version (Right (Right (Left (v, x)))) = (v, (
ApplicationData ** x)
)
68 | fix_record_with_version (Right (Right (Right (v, x)))) = (v, (
Alert ** x)
)
72 | no_id_change_cipher_spec : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Record ChangeCipherSpec)
73 | no_id_change_cipher_spec = map (\a => ChangeCipherSpec a) (\(ChangeCipherSpec a) => a)
74 | $
lengthed_list 2 token
77 | no_id_handshake : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Record Handshake)
78 | no_id_handshake = map (\a => Handshake a) (\(Handshake a) => a)
79 | $
lengthed_list 2 handshake
82 | no_id_handshake2 : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Record Handshake)
83 | no_id_handshake2 = map (\a => Handshake a) (\(Handshake a) => a)
84 | $
lengthed_list 2 handshake2
87 | no_id_application_data : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Record ApplicationData)
88 | no_id_application_data = map (\a => ApplicationData a) (\(ApplicationData a) => a)
89 | $
lengthed_list 2 token
92 | record_type_with_version : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (RecordType, TLSVersion)
93 | record_type_with_version = record_type <*>> tls_version
96 | record_type_with_version_with_length : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (RecordType, TLSVersion, Nat)
97 | record_type_with_version_with_length = record_type <*>> tls_version <*>> nat 2
100 | alert : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (AlertLevel, AlertDescription)
101 | alert = under "alert protocol" $
alert_level <*>> alert_description
104 | no_id_alert : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Record Alert)
105 | no_id_alert = map (\((), a) => Alert a) (\(Alert a) => ((), a)) $
is [0x00, 0x02] <*>> alert
108 | with_id_with_version : (Cons (Posed Bits8) i, Monoid i) => {type : RecordType} -> Parserializer Bits8 i (SimpleError String) (Record type) -> Parserializer Bits8 i (SimpleError String) (TLSVersion, Record type)
109 | with_id_with_version pser = under (show type <+> " record") $
is (to_vect $
record_type_to_id type) *> (tls_version <*>> pser)
112 | arecord : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (TLSVersion, DPair _ Record)
114 | map fix_record_with_version hack_record_with_version
115 | $
(with_id_with_version no_id_change_cipher_spec)
116 | <|> (with_id_with_version no_id_handshake)
117 | <|> (with_id_with_version no_id_application_data)
118 | <|> (with_id_with_version no_id_alert)
121 | arecord2 : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (TLSVersion, DPair _ Record)
123 | map fix_record_with_version hack_record_with_version
124 | $
(with_id_with_version no_id_change_cipher_spec)
125 | <|> (with_id_with_version no_id_handshake2)
126 | <|> (with_id_with_version no_id_application_data)
127 | <|> (with_id_with_version no_id_alert)
130 | alert_or_arecord : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Either (AlertLevel, AlertDescription) (TLSVersion, DPair _ Record))
131 | alert_or_arecord = alert <|> arecord
134 | alert_or_arecord2 : (Cons (Posed Bits8) i, Monoid i) => Parserializer Bits8 i (SimpleError String) (Either (AlertLevel, AlertDescription) (TLSVersion, DPair _ Record))
135 | alert_or_arecord2 = alert <|> arecord2
138 | wrapper2 : (Cons (Posed Bits8) i, Monoid i) => {iv_size : Nat} -> {mac_size : Nat} -> Parserializer Bits8 i (SimpleError String) (RecordType, TLSVersion, Wrapper2 iv_size mac_size)
142 | <*>> (mapEither (\x => maybe_to_either (from_application_data2 x) (msg "cannot parse wrapper")) to_application_data2 $
lengthed_list 2 token)