1use super::*;
2use std::fmt::{self, Debug, Formatter};
3use vstd::prelude::*;
4
5verus! {
6
7#[derive(Debug, View)]
9pub struct ObjectIdentifier;
10
11asn1_tagged!(ObjectIdentifier, tag_of!(OBJECT_IDENTIFIER));
12
13pub type SpecObjectIdentifierValue = Seq<UInt>;
14#[derive(PolyfillClone, Eq, PartialEq)]
15pub struct ObjectIdentifierValue(pub VecDeep<UInt>);
16pub type ObjectIdentifierValueOwned = ObjectIdentifierValue;
17
18impl View for ObjectIdentifierValue {
19 type V = Seq<UInt>;
20
21 open spec fn view(&self) -> Self::V {
22 self.0@
23 }
24}
25
26impl PolyfillEq for ObjectIdentifierValue {
27 #[inline(always)]
28 fn polyfill_eq(&self, other: &ObjectIdentifierValue) -> bool
29 {
30 self.0.polyfill_eq(&other.0)
31 }
32}
33
34impl ObjectIdentifier {
35 closed spec fn parse_first_two_arcs(byte: u8) -> Option<(UInt, UInt)> {
37 let arc1 = byte / 40;
38 let arc2 = byte % 40;
39
40 if arc1 <= 2 && arc2 <= 39 {
41 Some((arc1 as UInt, arc2 as UInt))
42 } else {
43 None
44 }
45 }
46
47 closed spec fn serialize_first_two_arcs(arc1: UInt, arc2: UInt) -> Option<u8> {
48 if arc1 <= 2 && arc2 <= 39 {
49 Some((arc1 * 40 + arc2) as u8)
50 } else {
51 None
52 }
53 }
54
55 proof fn lemma_serialize_parse_first_two_arcs(arc1: UInt, arc2: UInt)
56 ensures
57 Self::serialize_first_two_arcs(arc1, arc2) matches Some(byte) ==>
58 Self::parse_first_two_arcs(byte) == Some((arc1, arc2))
59 {}
60
61 proof fn lemma_parse_serialize_first_two_arcs(byte: u8)
62 ensures
63 Self::parse_first_two_arcs(byte) matches Some((arc1, arc2)) ==>
64 Self::serialize_first_two_arcs(arc1, arc2) == Some(byte)
65 {}
66}
67
68impl SpecCombinator for ObjectIdentifier {
69 type SpecResult = SpecObjectIdentifierValue;
70
71 closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()> {
72 match new_spec_object_identifier_inner().spec_parse(s) {
73 Ok((len, (_, (first, rest_arcs)))) =>
74 match Self::parse_first_two_arcs(first) {
75 Some((arc1, arc2)) =>
76 if rest_arcs.len() + 2 <= usize::MAX {
77 Ok((len, seq![ arc1, arc2 ] + rest_arcs))
78 } else {
79 Err(())
80 }
81 None => Err(()),
82 }
83
84 Err(..) => Err(()),
85 }
86 }
87
88 proof fn spec_parse_wf(&self, s: Seq<u8>) {
89 new_spec_object_identifier_inner().spec_parse_wf(s);
90 }
91
92 closed spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()> {
93 if v.len() < 2 || v.len() > usize::MAX {
94 Err(())
95 } else {
96 match Self::serialize_first_two_arcs(v[0], v[1]) {
97 Some(first_byte) => {
98 let rest_arcs = v.skip(2);
99
100 match (U8, Repeat(Base128UInt)).spec_serialize((first_byte, rest_arcs)) {
103 Ok(buf) =>
104 new_spec_object_identifier_inner().spec_serialize((buf.len() as LengthValue, (first_byte, rest_arcs))),
105 Err(..) => Err(())
106 }
107 },
108 None => Err(()),
109 }
110 }
111 }
112}
113
114impl SecureSpecCombinator for ObjectIdentifier {
115 open spec fn is_prefix_secure() -> bool {
116 true
117 }
118
119 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
120 if let Ok(b) = self.spec_serialize(v) {
121 let first_byte = Self::serialize_first_two_arcs(v[0], v[1]).unwrap();
122 let rest_arcs = v.skip(2);
123 let buf = (U8, Repeat(Base128UInt)).spec_serialize((first_byte, rest_arcs)).unwrap();
124
125 new_spec_object_identifier_inner().theorem_serialize_parse_roundtrip((buf.len() as LengthValue, (first_byte, rest_arcs)));
126 Self::lemma_serialize_parse_first_two_arcs(v[0], v[1]);
127
128 let (len, v2) = self.spec_parse(b).unwrap();
129 assert(len == b.len() as usize);
130 assert(v2 =~= v);
131 }
132 }
133
134 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
135 if let Ok((len, v)) = self.spec_parse(buf) {
136 let (_, (_, (first_byte, rest_arcs))) = new_spec_object_identifier_inner().spec_parse(buf).unwrap();
137
138 new_spec_object_identifier_inner().theorem_parse_serialize_roundtrip(buf);
139 Self::lemma_parse_serialize_first_two_arcs(first_byte);
140
141 assert(v.skip(2) =~= rest_arcs);
142
143 let buf2 = self.spec_serialize(v).unwrap();
144 assert(buf2 =~= buf.subrange(0, len as int));
145 }
146 }
147
148 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
149 new_spec_object_identifier_inner().lemma_prefix_secure(s1, s2);
150 }
151}
152
153impl Combinator for ObjectIdentifier {
154 type Result<'a> = ObjectIdentifierValue;
155 type Owned = ObjectIdentifierValueOwned;
156
157 closed spec fn spec_length(&self) -> Option<usize> {
158 None
159 }
160
161 fn length(&self) -> Option<usize> {
162 None
163 }
164
165 #[inline]
166 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>) {
167 let (len, (_, (first, mut rest_arcs))) = new_object_identifier_inner().parse(s)?;
168
169 let arc1 = first / 40;
170 let arc2 = first % 40;
171
172 if arc1 > 2 || arc2 > 39 {
173 return Err(ParseError::Other("Invalid first two arcs".to_string()));
174 }
175
176 if rest_arcs.len() > usize::MAX - 2 {
177 return Err(ParseError::SizeOverflow);
178 }
179
180 let mut res = VecDeep::with_capacity(2 + rest_arcs.len());
181 res.push(arc1 as UInt);
182 res.push(arc2 as UInt);
183 res.append(&mut rest_arcs);
184
185 assert(res@ == self.spec_parse(s@).unwrap().1);
186
187 Ok((len, ObjectIdentifierValue(res)))
188 }
189
190 #[inline]
191 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<usize, SerializeError>) {
192 let mut v = v.0;
193 let ghost old_v = v@;
194
195 if v.len() < 2 {
196 return Err(SerializeError::Other("OID should have at least two arcs".to_string()));
197 }
198
199 if *v.get(0) > 2 || *v.get(1) > 39 {
200 return Err(SerializeError::Other("Invalid first two arcs".to_string()));
201 }
202
203 let first_byte = *v.get(0) as u8 * 40 + *v.get(1) as u8;
204
205 let rest_arcs_inner = v.split_off(2);
206
207 let rest_arcs_cloned = PolyfillClone::clone(&rest_arcs_inner);
210 let rest_arcs = rest_arcs_inner;
211
212 let len = (U8, Repeat(Base128UInt)).serialize((first_byte, rest_arcs_cloned), data, pos)?;
213 let len2 = new_object_identifier_inner().serialize((len as LengthValue, (first_byte, rest_arcs)), data, pos)?;
214
215 if pos.checked_add(len2).is_some() && pos + len2 <= data.len() {
216 assert(rest_arcs_cloned@ == old_v.skip(2));
217 assert(data@ =~= seq_splice(old(data)@, pos, self.spec_serialize(old_v).unwrap()));
218
219 return Ok(len2);
220 }
221
222 Err(SerializeError::InsufficientBuffer)
223 }
224}
225
226struct OIDCont;
228
229impl Continuation for OIDCont {
230 type Input<'a> = LengthValue;
231 type Output = AndThen<Bytes, (U8, Repeat<Base128UInt>)>;
232
233 #[inline(always)]
234 fn apply<'a>(&self, i: Self::Input<'a>) -> (o: Self::Output) {
235 AndThen(Bytes(i as usize), (U8, Repeat(Base128UInt)))
236 }
237
238 closed spec fn requires<'a>(&self, i: Self::Input<'a>) -> bool {
239 true
240 }
241
242 closed spec fn ensures<'a>(&self, i: Self::Input<'a>, o: Self::Output) -> bool {
243 o == AndThen(Bytes(i as usize), (U8, Repeat(Base128UInt)))
244 }
245}
246
247#[allow(dead_code)]
251type SpecObjectIdentifierInner = SpecDepend<Length, AndThen<Bytes, (U8, Repeat<Base128UInt>)>>;
252type ObjectIdentifierInner = Depend<Length, AndThen<Bytes, (U8, Repeat<Base128UInt>)>, OIDCont>;
253
254closed spec fn new_spec_object_identifier_inner() -> SpecObjectIdentifierInner {
255 SpecDepend {
256 fst: Length,
257 snd: |l| {
258 AndThen(Bytes(l as usize), (U8, Repeat(Base128UInt)))
259 },
260 }
261}
262
263#[inline(always)]
264fn new_object_identifier_inner() -> (res: ObjectIdentifierInner)
265 ensures res@ == new_spec_object_identifier_inner()
266{
267 Depend {
268 fst: Length,
269 snd: OIDCont,
270 spec_snd: Ghost(|l| {
271 AndThen(Bytes(l as usize), (U8, Repeat(Base128UInt)))
272 }),
273 }
274}
275
276}
277
278impl Debug for ObjectIdentifierValue {
279 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
280 write!(f, "OID(")?;
281
282 for (i, arc) in self.0 .0.iter().enumerate() {
283 if i != 0 {
284 write!(f, ".")?;
285 }
286
287 write!(f, "{}", arc)?;
288 }
289
290 write!(f, ")")
291 }
292}
293
294#[cfg(test)]
295mod tests {
296 use super::*;
297 use der::Encode;
298
299 fn serialize_oid(v: Vec<UInt>) -> Result<Vec<u8>, SerializeError> {
300 let mut data = vec![0; 1 + 4 + v.len() * 8];
301 data[0] = 0x06;
302 let len = ObjectIdentifier.serialize(
303 ObjectIdentifierValue(VecDeep::from_vec(v)),
304 &mut data,
305 1,
306 )?;
307 data.truncate(len + 1);
308 Ok(data)
309 }
310
311 #[test]
312 fn diff_with_der() {
313 let diff = |v: Vec<UInt>| {
314 let res1 = serialize_oid(PolyfillClone::clone(&v)).map_err(|_| ());
315 let res2 = der::asn1::ObjectIdentifier::new_unwrap(
316 v.iter()
317 .map(|i| i.to_string())
318 .collect::<Vec<_>>()
319 .join(".")
320 .as_str(),
321 )
322 .to_der()
323 .map_err(|_| ());
324
325 assert_eq!(res1, res2);
326 };
327
328 diff(vec![1, 2, 3]);
329 diff(vec![1, 2, 123214]);
330 diff(vec![1, 2, 123214, 1231, 4534, 231]);
331 diff(vec![2, 10, 123214, 1231, 4534, 231]);
332 diff(vec![2, 39, 123214, 1231, 4534, 231]);
333 }
334}