verdict_parser/asn1/
len.rs1use super::*;
2use vstd::prelude::*;
3
4verus! {
5
6#[derive(Debug, View)]
8pub struct Length;
9
10pub type LengthValue = usize;
12
13impl SpecCombinator for Length {
14 type SpecResult = LengthValue;
15
16 closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()>
17 {
18 if s.len() == 0 {
19 Err(())
20 } else if s[0] < 0x80 {
21 Ok((1, s[0] as LengthValue))
23 } else {
24 let bytes = (s[0] - 0x80) as LengthValue;
26 match VarUInt(bytes as usize).spec_parse(s.drop_first()) {
27 Ok((n, v)) => {
28 if bytes > 0 && !fits_n_bytes_unsigned!(v, bytes - 1) && v > 0x7f && v <= LengthValue::MAX {
32 Ok(((n + 1) as usize, v as LengthValue))
33 } else {
34 Err(())
35 }
36 }
37 Err(()) => Err(()),
38 }
39 }
40 }
41
42 proof fn spec_parse_wf(&self, s: Seq<u8>) {
43 if s.len() != 0 && s[0] >= 0x80 {
44 let bytes = (s[0] - 0x80) as LengthValue;
45 VarUInt(bytes as usize).spec_parse_wf(s.drop_first());
46 }
47 }
48
49 closed spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()>
50 {
51 if v < 0x80 {
52 Ok(seq![v as u8])
53 } else {
54 let bytes = min_num_bytes_unsigned(v as VarUIntResult);
56
57 match VarUInt(bytes as usize).spec_serialize(v as VarUIntResult) {
58 Ok(buf) => Ok(seq![(0x80 + bytes) as u8] + buf),
59 Err(()) => Err(()),
60 }
61 }
62 }
63}
64
65impl SecureSpecCombinator for Length {
66 open spec fn is_prefix_secure() -> bool {
67 true
68 }
69
70 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
71 if let Ok(buf) = self.spec_serialize(v) {
72 if v >= 0x80 {
73 let bytes = min_num_bytes_unsigned(v as VarUIntResult);
74 let var_uint = VarUInt(bytes as usize);
75
76 lemma_min_num_bytes_unsigned(v as VarUIntResult);
77
78 var_uint.theorem_serialize_parse_roundtrip(v as VarUIntResult);
79 var_uint.lemma_serialize_ok_len(v as VarUIntResult);
80
81 let buf2 = var_uint.spec_serialize(v as VarUIntResult).unwrap();
82 assert(buf.drop_first() == buf2);
83 }
84 }
85 }
86
87 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
88 if let Ok((n, v)) = self.spec_parse(buf) {
89 if buf[0] < 0x80 {
90 assert(seq![ buf[0] ] == buf.subrange(0, 1));
91 } else {
92 let bytes = (buf[0] - 0x80) as UInt;
93 let var_uint = VarUInt(bytes as usize);
94
95 var_uint.theorem_parse_serialize_roundtrip(buf.drop_first());
97 var_uint.lemma_parse_ok(buf.drop_first());
98 var_uint.lemma_parse_ok_bound(buf.drop_first());
99
100 let (len, v2) = var_uint.spec_parse(buf.drop_first()).unwrap();
102
103 assert(is_min_num_bytes_unsigned(v2, bytes));
104 lemma_min_num_bytes_unsigned(v2);
105
106 assert(var_uint.spec_serialize(v as VarUIntResult).is_ok());
108 let buf2 = var_uint.spec_serialize(v as VarUIntResult).unwrap();
109 assert(seq![(0x80 + bytes) as u8] + buf2 == buf.subrange(0, 1 + bytes));
110 }
111 }
112 }
113
114 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
115 if s1.len() > 0 {
116 let bytes = (s1[0] - 0x80) as UInt;
117 VarUInt(bytes as usize).lemma_prefix_secure(s1.drop_first(), s2);
118 assert((s1 + s2).drop_first() =~= s1.drop_first() + s2);
119 }
120 }
121}
122
123impl Combinator for Length {
124 type Result<'a> = LengthValue;
125 type Owned = LengthValue;
126
127 closed spec fn spec_length(&self) -> Option<usize> {
128 None
129 }
130
131 fn length(&self) -> Option<usize> {
132 None
133 }
134
135 #[inline]
136 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>) {
137 if s.len() == 0 {
138 return Err(ParseError::UnexpectedEndOfInput);
139 }
140
141 if s[0] < 0x80 {
142 return Ok((1, s[0] as LengthValue));
144 }
145
146 let bytes = (s[0] - 0x80) as UInt;
147
148 let (len, v) = VarUInt(bytes as usize).parse(slice_drop_first(s))?;
149
150 if bytes > 0 && !fits_n_bytes_unsigned!(v, bytes - 1) && v > 0x7f && v <= LengthValue::MAX as VarUIntResult {
151 Ok(((len + 1) as usize, v as LengthValue))
152 } else {
153 Err(ParseError::Other("Invalid length encoding".to_string()))
154 }
155 }
156
157 #[inline]
158 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<usize, SerializeError>) {
159 if v < 0x80 {
160 if pos < data.len() {
161 data.set(pos, v as u8);
162 assert(data@ =~= seq_splice(old(data)@, pos, seq![v as u8]));
163 return Ok(1);
164 } else {
165 return Err(SerializeError::InsufficientBuffer);
166 }
167 }
168
169 let bytes = min_num_bytes_unsigned_exec(v as VarUIntResult);
170
171 if pos >= data.len() || pos > usize::MAX - 1 {
173 return Err(SerializeError::InsufficientBuffer);
174 }
175
176 data.set(pos, (0x80 + bytes) as u8);
177 let len = VarUInt(bytes as usize).serialize(v as VarUIntResult, data, pos + 1)?;
178
179 proof {
180 lemma_min_num_bytes_unsigned(v as VarUIntResult);
181 assert(data@ =~= seq_splice(old(data)@, pos, self@.spec_serialize(v).unwrap()));
182 }
183
184 Ok(len + 1)
185 }
186}
187
188}
189
190#[cfg(test)]
191mod test {
192 use super::*;
193
194 #[test]
195 fn parse() {
196 assert_eq!(Length.parse(&[0x0]).unwrap(), (1, 0));
197 assert_eq!(Length.parse(&[0x7f]).unwrap(), (1, 0x7f));
198 assert_eq!(Length.parse(&[0x81, 0x80]).unwrap(), (2, 0x80));
199 assert_eq!(Length.parse(&[0x82, 0x0f, 0xff]).unwrap(), (3, 0x0fff));
200
201 assert!(Length.parse(&[0x80]).is_err());
202 assert!(Length.parse(&[0x81, 0x7f]).is_err());
203 assert!(Length.parse(&[0x82, 0x00, 0xff]).is_err());
204 }
205}