1use super::modifiers::{defaulted, explicit_tag};
7pub use super::modifiers::{
8 implicitly_tagged as Implicit, ImplicitFmt, CHOICE, IMPLICIT, IMPLICIT_APPLICATION,
9 IMPLICIT_PRIVATE, OPTIONAL, REQUIRED,
10};
11use super::{
12 ASN1Fmt, AnyFmt, BitStringFmt, BmpStringFmt, BoolFmt, Class, EnumeratedFmt, GeneralizedTimeFmt,
13 Ia5StringFmt, Integer16Fmt, Integer8Fmt, IntegerFmt, NullFmt, NumericStringFmt,
14 ObjectIdentifierFmt, OctetStringFmt, PrintableStringFmt, RealFmt, SetOfFmt, TagFmt,
15 TeletexStringFmt, UniversalStringFmt, UtcTimeFmt, Utf8StringFmt, DER,
16};
17use crate::core::{proof::*, spec::*};
18use vstd::prelude::*;
19
20verus! {
21
22pub type BoolTlvFmt = ASN1Fmt<BoolFmt<DER>, DER>;
24
25pub type AnyTlvFmt = AnyFmt<DER>;
26
27pub type IntegerTlvFmt = ASN1Fmt<IntegerFmt, DER>;
28
29pub type Integer8TlvFmt = ASN1Fmt<Integer8Fmt, DER>;
30
31pub type Integer16TlvFmt = ASN1Fmt<Integer16Fmt, DER>;
32
33pub type EnumeratedTlvFmt = ASN1Fmt<EnumeratedFmt, DER>;
34
35pub type Enumerated16TlvFmt = ASN1Fmt<Integer16Fmt, DER>;
36
37pub type ObjectIdentifierTlvFmt = ASN1Fmt<ObjectIdentifierFmt, DER>;
38
39pub type RealTlvFmt = ASN1Fmt<RealFmt<DER>, DER>;
40
41pub type BitStringTlvFmt = ASN1Fmt<BitStringFmt<DER>, DER>;
42
43pub type OctetStringTlvFmt = ASN1Fmt<OctetStringFmt, DER>;
44
45pub type NullTlvFmt = ASN1Fmt<NullFmt, DER>;
46
47pub type Utf8StringTlvFmt = ASN1Fmt<Utf8StringFmt, DER>;
48
49pub type PrintableStringTlvFmt = ASN1Fmt<PrintableStringFmt, DER>;
50
51pub type NumericStringTlvFmt = ASN1Fmt<NumericStringFmt, DER>;
52
53pub type TeletexStringTlvFmt = ASN1Fmt<TeletexStringFmt, DER>;
54
55pub type Ia5StringTlvFmt = ASN1Fmt<Ia5StringFmt, DER>;
56
57pub type UtcTimeTlvFmt = ASN1Fmt<UtcTimeFmt<DER>, DER>;
58
59pub type GeneralizedTimeTlvFmt = ASN1Fmt<GeneralizedTimeFmt<DER>, DER>;
60
61pub type BmpStringTlvFmt = ASN1Fmt<BmpStringFmt, DER>;
62
63pub type UniversalStringTlvFmt = ASN1Fmt<UniversalStringFmt, DER>;
64
65pub type SequenceFmt<C> = ASN1Fmt<C, DER>;
66
67pub type SetFmt<C> = ASN1Fmt<C, DER>;
68
69pub type SequenceOfFmt<C> = ASN1Fmt<crate::combinators::RepeatTillEnd<C>, DER>;
70
71pub type SetOfTlvFmt<C> = ASN1Fmt<SetOfFmt<C>, DER>;
72
73pub type ExplicitFmt<C> = ASN1Fmt<C, DER>;
74
75pub type DefaultFmt<Field, Default, Rest> = super::DefaultedFmt<Field, Default, Rest, DER>;
76
77pub type Eof = crate::combinators::Eof;
78
79#[allow(non_upper_case_globals)]
80pub const Eof: Eof = crate::combinators::Eof;
81
82pub const BOOLEAN: BoolTlvFmt = ASN1Fmt(TagFmt::BOOLEAN, BoolFmt::<DER>);
83
84pub const ANY: AnyTlvFmt = AnyFmt::<DER>;
85
86pub const INTEGER: IntegerTlvFmt = ASN1Fmt(TagFmt::INTEGER, IntegerFmt);
87
88pub const INTEGER8: Integer8TlvFmt = ASN1Fmt(TagFmt::INTEGER, Integer8Fmt);
89
90pub const INTEGER16: Integer16TlvFmt = ASN1Fmt(TagFmt::INTEGER, Integer16Fmt);
91
92pub const ENUMERATED: EnumeratedTlvFmt = ASN1Fmt(TagFmt::ENUMERATED, EnumeratedFmt);
93
94pub const ENUMERATED16: Enumerated16TlvFmt = ASN1Fmt(TagFmt::ENUMERATED, Integer16Fmt);
95
96pub const OBJECT_IDENTIFIER: ObjectIdentifierTlvFmt = ASN1Fmt(
97 TagFmt::OBJECT_IDENTIFIER,
98 ObjectIdentifierFmt,
99);
100
101pub const REAL: RealTlvFmt = ASN1Fmt(TagFmt::REAL, RealFmt::<DER>);
102
103pub const BIT_STRING: BitStringTlvFmt = ASN1Fmt(TagFmt::BIT_STRING, BitStringFmt::<DER>);
104
105pub const OCTET_STRING: OctetStringTlvFmt = ASN1Fmt(TagFmt::OCTET_STRING, OctetStringFmt);
106
107pub const NULL: NullTlvFmt = ASN1Fmt(TagFmt::NULL, NullFmt);
108
109pub const UTF8_STRING: Utf8StringTlvFmt = ASN1Fmt(TagFmt::UTF8_STRING, Utf8StringFmt);
110
111pub const PRINTABLE_STRING: PrintableStringTlvFmt = ASN1Fmt(
112 TagFmt::PRINTABLE_STRING,
113 PrintableStringFmt,
114);
115
116pub const NUMERIC_STRING: NumericStringTlvFmt = ASN1Fmt(TagFmt::NUMERIC_STRING, NumericStringFmt);
117
118pub const TELETEX_STRING: TeletexStringTlvFmt = ASN1Fmt(TagFmt::TELETEX_STRING, TeletexStringFmt);
119
120pub const IA5_STRING: Ia5StringTlvFmt = ASN1Fmt(TagFmt::IA5_STRING, Ia5StringFmt);
121
122pub const UTC_TIME: UtcTimeTlvFmt = ASN1Fmt(TagFmt::UTC_TIME, UtcTimeFmt::<DER>);
123
124pub const GENERALIZED_TIME: GeneralizedTimeTlvFmt = ASN1Fmt(
125 TagFmt::GENERALIZED_TIME,
126 GeneralizedTimeFmt::<DER>,
127);
128
129pub const BMP_STRING: BmpStringTlvFmt = ASN1Fmt(TagFmt::BMP_STRING, BmpStringFmt);
130
131pub const UNIVERSAL_STRING: UniversalStringTlvFmt = ASN1Fmt(
132 TagFmt::UNIVERSAL_STRING,
133 UniversalStringFmt,
134);
135
136#[allow(non_snake_case)]
138#[verifier::allow_in_spec]
139pub const fn SET_OF<C: Copy>(inner: C) -> SetOfTlvFmt<C>
140 returns
141 ASN1Fmt::<SetOfFmt<C>, DER>(TagFmt::SET, SetOfFmt(inner)),
142{
143 ASN1Fmt::<SetOfFmt<C>, DER>(TagFmt::SET, SetOfFmt(inner))
144}
145
146#[allow(non_snake_case)]
148#[verifier::allow_in_spec]
149pub const fn SEQUENCE<C: Copy>(inner: C) -> SequenceFmt<C>
150 returns
151 ASN1Fmt::<C, DER>(TagFmt::SEQUENCE, inner),
152{
153 ASN1Fmt::<C, DER>(TagFmt::SEQUENCE, inner)
154}
155
156#[allow(non_snake_case)]
158#[verifier::allow_in_spec]
159pub const fn SET<C: Copy>(inner: C) -> SetFmt<C>
160 returns
161 ASN1Fmt::<C, DER>(TagFmt::SET, inner),
162{
163 ASN1Fmt::<C, DER>(TagFmt::SET, inner)
164}
165
166#[allow(non_snake_case)]
168#[verifier::allow_in_spec]
169pub const fn SEQUENCE_OF<C: Copy>(inner: C) -> SequenceOfFmt<C>
170 returns
171 ASN1Fmt::<crate::combinators::RepeatTillEnd<C>, DER>(
172 TagFmt::SEQUENCE,
173 crate::combinators::RepeatTillEnd(inner),
174 ),
175{
176 ASN1Fmt::<crate::combinators::RepeatTillEnd<C>, DER>(
177 TagFmt::SEQUENCE,
178 crate::combinators::RepeatTillEnd(inner),
179 )
180}
181
182#[allow(non_snake_case)]
184#[verifier::allow_in_spec]
185pub const fn Explicit<C: Copy>(class: Class, number: u64, inner: C) -> ExplicitFmt<C>
186 returns
187 ASN1Fmt::<C, DER>(explicit_tag(class, number), inner),
188{
189 ASN1Fmt(explicit_tag(class, number), inner)
190}
191
192#[allow(non_snake_case)]
194#[verifier::allow_in_spec]
195pub const fn EXPLICIT<C: Copy>(number: u64, inner: C) -> ExplicitFmt<C>
196 returns
197 Explicit(Class::ContextSpecific, number, inner),
198{
199 Explicit(Class::ContextSpecific, number, inner)
200}
201
202#[allow(non_snake_case)]
204#[verifier::allow_in_spec]
205pub const fn EXPLICIT_APPLICATION<C: Copy>(number: u64, inner: C) -> ExplicitFmt<C>
206 returns
207 Explicit(Class::Application, number, inner),
208{
209 Explicit(Class::Application, number, inner)
210}
211
212#[allow(non_snake_case)]
214#[verifier::allow_in_spec]
215pub const fn EXPLICIT_PRIVATE<C: Copy>(number: u64, inner: C) -> ExplicitFmt<C>
216 returns
217 Explicit(Class::Private, number, inner),
218{
219 Explicit(Class::Private, number, inner)
220}
221
222#[allow(non_snake_case)]
224#[verifier::allow_in_spec]
225pub const fn DEFAULT<Field, Rest>(field: Field, default: Field::T, cont: Rest) -> DefaultFmt<
226 Field,
227 Field::T,
228 Rest,
229> where Field: SpecByteLen
230 returns
231 defaulted::<Field, Rest, DER>(field, default, cont),
232{
233 defaulted::<Field, Rest, DER>(field, default, cont)
234}
235
236} verus! {
238
239use crate::combinators::{Choice, Optional, Pair};
240
241#[verifier::allow_in_spec]
242#[allow(non_snake_case)]
243const fn MY_FMT() -> Pair<
244 IntegerTlvFmt,
245 DefaultFmt<
246 BoolTlvFmt,
247 bool,
248 Pair<
249 BitStringTlvFmt,
250 Optional<
251 OctetStringTlvFmt,
252 DefaultFmt<Integer8TlvFmt, i8, Optional<UtcTimeTlvFmt, Utf8StringTlvFmt>>,
253 >,
254 >,
255 >,
256>
257 returns
258 REQUIRED(
259 INTEGER,
260 DEFAULT(
261 BOOLEAN,
262 false,
263 REQUIRED(
264 BIT_STRING,
265 OPTIONAL(OCTET_STRING, DEFAULT(INTEGER8, 0, OPTIONAL(UTC_TIME, UTF8_STRING))),
266 ),
267 ),
268 ),
269{
270 REQUIRED(
271 INTEGER,
272 DEFAULT(
273 BOOLEAN,
274 false,
275 REQUIRED(
276 BIT_STRING,
277 OPTIONAL(OCTET_STRING, DEFAULT(INTEGER8, 0, OPTIONAL(UTC_TIME, UTF8_STRING))),
278 ),
279 ),
280 )
281}
282
283#[verifier::allow_in_spec]
284#[allow(non_snake_case)]
285const fn MY_FMT2() -> Pair<
286 IntegerTlvFmt,
287 DefaultFmt<
288 ExplicitFmt<Integer16TlvFmt>,
289 i16,
290 Optional<
291 ImplicitFmt<Integer16TlvFmt>,
292 Optional<
293 ImplicitFmt<Integer16TlvFmt>,
294 DefaultFmt<
295 ExplicitFmt<Integer16TlvFmt>,
296 i16,
297 Optional<UtcTimeTlvFmt, Utf8StringTlvFmt>,
298 >,
299 >,
300 >,
301 >,
302>
303 returns
304 REQUIRED(
305 INTEGER,
306 DEFAULT(
307 EXPLICIT(0, INTEGER16),
308 10,
309 OPTIONAL(
310 IMPLICIT(1, INTEGER16),
311 OPTIONAL(
312 IMPLICIT(2, INTEGER16),
313 DEFAULT(EXPLICIT(3, INTEGER16), 0, OPTIONAL(UTC_TIME, UTF8_STRING)),
314 ),
315 ),
316 ),
317 ),
318{
319 REQUIRED(
320 INTEGER,
321 DEFAULT(
322 EXPLICIT(0, INTEGER16),
323 10,
324 OPTIONAL(
325 IMPLICIT(1, INTEGER16),
326 OPTIONAL(
327 IMPLICIT(2, INTEGER16),
328 DEFAULT(EXPLICIT(3, INTEGER16), 0, OPTIONAL(UTC_TIME, UTF8_STRING)),
329 ),
330 ),
331 ),
332 )
333}
334
335proof fn chain_of_optional_defaulted() {
336 use crate::combinators::disjoint::disjointness_lemmas;
337 use super::disjoint::asn1_disjointness_lemmas;
338
339 broadcast use disjointness_lemmas;
340 broadcast use asn1_disjointness_lemmas;
341
342 assert(MY_FMT().safe_inv());
343 assert(MY_FMT().sound_inv());
344 assert(MY_FMT().unambiguous());
345 assert(MY_FMT().nonmal_inv());
346
347 assert(MY_FMT2().safe_inv());
348 assert(MY_FMT2().sound_inv());
349 assert(MY_FMT2().unambiguous());
350 assert(MY_FMT2().nonmal_inv());
351
352 #[verusfmt::skip]
353 let fmt =
354 REQUIRED (INTEGER,
355 DEFAULT (BOOLEAN, false,
356 REQUIRED (BIT_STRING,
357 OPTIONAL (OCTET_STRING,
358 DEFAULT (INTEGER8, 0,
359 OPTIONAL (UTC_TIME, UTF8_STRING))))));
360
361 assert(fmt.safe_inv());
362 assert(fmt.sound_inv());
363 assert(fmt.unambiguous());
364
365 #[verusfmt::skip]
366 let fmt1 =
367 REQUIRED (INTEGER,
368 DEFAULT (EXPLICIT (0, INTEGER16), 10,
369 OPTIONAL (IMPLICIT (1, INTEGER16),
370 OPTIONAL (IMPLICIT (2, INTEGER16),
371 DEFAULT (EXPLICIT (3, INTEGER16), 0,
372 OPTIONAL (UTC_TIME, UTF8_STRING))))));
373
374 assert(fmt1.safe_inv());
375 assert(fmt1.sound_inv());
376 assert(fmt1.unambiguous());
377
378 #[verusfmt::skip]
379 let fmt2 = CHOICE(
380 IMPLICIT (0, NULL), CHOICE(
381 IMPLICIT (1, NULL), CHOICE(
382 IMPLICIT (2, INTEGER8), CHOICE(
383 EXPLICIT (3, INTEGER8), CHOICE(
384 OCTET_STRING, UTF8_STRING)))));
385
386 assert(fmt2.safe_inv());
387 assert(fmt2.sound_inv());
388 assert(fmt2.unambiguous());
389}
390
391}