1 //! ASN.1 `SET OF` support.
2 //!
3 //! # Ordering Notes
4 //!
5 //! Some DER serializer implementations fail to properly sort elements of a
6 //! `SET OF`. This is technically non-canonical, but occurs frequently
7 //! enough that most DER decoders tolerate it. Unfortunately because
8 //! of that, we must also follow suit.
9 //!
10 //! However, all types in this module sort elements of a set at decode-time,
11 //! ensuring they'll be in the proper order if reserialized.
12
13 use crate::{
14 arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error,
15 ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, ValueOrd, Writer,
16 };
17 use core::cmp::Ordering;
18
19 #[cfg(feature = "alloc")]
20 use {alloc::vec::Vec, core::slice};
21
22 /// ASN.1 `SET OF` backed by an array.
23 ///
24 /// This type implements an append-only `SET OF` type which is stack-based
25 /// and does not depend on `alloc` support.
26 // TODO(tarcieri): use `ArrayVec` when/if it's merged into `core`
27 // See: https://github.com/rust-lang/rfcs/pull/2990
28 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
29 pub struct SetOf<T, const N: usize>
30 where
31 T: DerOrd,
32 {
33 inner: ArrayVec<T, N>,
34 }
35
36 impl<T, const N: usize> SetOf<T, N>
37 where
38 T: DerOrd,
39 {
40 /// Create a new [`SetOf`].
new() -> Self41 pub fn new() -> Self {
42 Self {
43 inner: ArrayVec::default(),
44 }
45 }
46
47 /// Add an item to this [`SetOf`].
48 ///
49 /// Items MUST be added in lexicographical order according to the
50 /// [`DerOrd`] impl on `T`.
51 #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")]
add(&mut self, new_elem: T) -> Result<()>52 pub fn add(&mut self, new_elem: T) -> Result<()> {
53 self.insert_ordered(new_elem)
54 }
55
56 /// Insert an item into this [`SetOf`].
insert(&mut self, item: T) -> Result<()>57 pub fn insert(&mut self, item: T) -> Result<()> {
58 self.inner.push(item)?;
59 der_sort(self.inner.as_mut())
60 }
61
62 /// Insert an item into this [`SetOf`].
63 ///
64 /// Items MUST be added in lexicographical order according to the
65 /// [`DerOrd`] impl on `T`.
insert_ordered(&mut self, item: T) -> Result<()>66 pub fn insert_ordered(&mut self, item: T) -> Result<()> {
67 // Ensure set elements are lexicographically ordered
68 if let Some(last) = self.inner.last() {
69 check_der_ordering(last, &item)?;
70 }
71
72 self.inner.push(item)
73 }
74
75 /// Get the nth element from this [`SetOf`].
get(&self, index: usize) -> Option<&T>76 pub fn get(&self, index: usize) -> Option<&T> {
77 self.inner.get(index)
78 }
79
80 /// Iterate over the elements of this [`SetOf`].
iter(&self) -> SetOfIter<'_, T>81 pub fn iter(&self) -> SetOfIter<'_, T> {
82 SetOfIter {
83 inner: self.inner.iter(),
84 }
85 }
86
87 /// Is this [`SetOf`] empty?
is_empty(&self) -> bool88 pub fn is_empty(&self) -> bool {
89 self.inner.is_empty()
90 }
91
92 /// Number of elements in this [`SetOf`].
len(&self) -> usize93 pub fn len(&self) -> usize {
94 self.inner.len()
95 }
96 }
97
98 impl<T, const N: usize> Default for SetOf<T, N>
99 where
100 T: DerOrd,
101 {
default() -> Self102 fn default() -> Self {
103 Self::new()
104 }
105 }
106
107 impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
108 where
109 T: Decode<'a> + DerOrd,
110 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>111 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
112 reader.read_nested(header.length, |reader| {
113 let mut result = Self::new();
114
115 while !reader.is_finished() {
116 result.inner.push(T::decode(reader)?)?;
117 }
118
119 der_sort(result.inner.as_mut())?;
120 validate(result.inner.as_ref())?;
121 Ok(result)
122 })
123 }
124 }
125
126 impl<'a, T, const N: usize> EncodeValue for SetOf<T, N>
127 where
128 T: 'a + Decode<'a> + Encode + DerOrd,
129 {
value_len(&self) -> Result<Length>130 fn value_len(&self) -> Result<Length> {
131 self.iter()
132 .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
133 }
134
encode_value(&self, writer: &mut impl Writer) -> Result<()>135 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
136 for elem in self.iter() {
137 elem.encode(writer)?;
138 }
139
140 Ok(())
141 }
142 }
143
144 impl<'a, T, const N: usize> FixedTag for SetOf<T, N>
145 where
146 T: Decode<'a> + DerOrd,
147 {
148 const TAG: Tag = Tag::Set;
149 }
150
151 impl<T, const N: usize> TryFrom<[T; N]> for SetOf<T, N>
152 where
153 T: DerOrd,
154 {
155 type Error = Error;
156
try_from(mut arr: [T; N]) -> Result<SetOf<T, N>>157 fn try_from(mut arr: [T; N]) -> Result<SetOf<T, N>> {
158 der_sort(&mut arr)?;
159
160 let mut result = SetOf::new();
161
162 for elem in arr {
163 result.insert_ordered(elem)?;
164 }
165
166 Ok(result)
167 }
168 }
169
170 impl<T, const N: usize> ValueOrd for SetOf<T, N>
171 where
172 T: DerOrd,
173 {
value_cmp(&self, other: &Self) -> Result<Ordering>174 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
175 iter_cmp(self.iter(), other.iter())
176 }
177 }
178
179 /// Iterator over the elements of an [`SetOf`].
180 #[derive(Clone, Debug)]
181 pub struct SetOfIter<'a, T> {
182 /// Inner iterator.
183 inner: arrayvec::Iter<'a, T>,
184 }
185
186 impl<'a, T> Iterator for SetOfIter<'a, T> {
187 type Item = &'a T;
188
next(&mut self) -> Option<&'a T>189 fn next(&mut self) -> Option<&'a T> {
190 self.inner.next()
191 }
192 }
193
194 impl<'a, T> ExactSizeIterator for SetOfIter<'a, T> {}
195
196 /// ASN.1 `SET OF` backed by a [`Vec`].
197 ///
198 /// This type implements an append-only `SET OF` type which is heap-backed
199 /// and depends on `alloc` support.
200 #[cfg(feature = "alloc")]
201 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
202 pub struct SetOfVec<T>
203 where
204 T: DerOrd,
205 {
206 inner: Vec<T>,
207 }
208
209 #[cfg(feature = "alloc")]
210 impl<T: DerOrd> Default for SetOfVec<T> {
default() -> Self211 fn default() -> Self {
212 Self {
213 inner: Default::default(),
214 }
215 }
216 }
217
218 #[cfg(feature = "alloc")]
219 impl<T> SetOfVec<T>
220 where
221 T: DerOrd,
222 {
223 /// Create a new [`SetOfVec`].
new() -> Self224 pub fn new() -> Self {
225 Self {
226 inner: Vec::default(),
227 }
228 }
229
230 /// Create a new [`SetOfVec`] from the given iterator.
231 ///
232 /// Note: this is an inherent method instead of an impl of the
233 /// [`FromIterator`] trait in order to be fallible.
234 #[allow(clippy::should_implement_trait)]
from_iter<I>(iter: I) -> Result<Self> where I: IntoIterator<Item = T>,235 pub fn from_iter<I>(iter: I) -> Result<Self>
236 where
237 I: IntoIterator<Item = T>,
238 {
239 Vec::from_iter(iter).try_into()
240 }
241
242 /// Add an element to this [`SetOfVec`].
243 ///
244 /// Items MUST be added in lexicographical order according to the
245 /// [`DerOrd`] impl on `T`.
246 #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")]
add(&mut self, item: T) -> Result<()>247 pub fn add(&mut self, item: T) -> Result<()> {
248 self.insert_ordered(item)
249 }
250
251 /// Extend a [`SetOfVec`] using an iterator.
252 ///
253 /// Note: this is an inherent method instead of an impl of the
254 /// [`Extend`] trait in order to be fallible.
extend<I>(&mut self, iter: I) -> Result<()> where I: IntoIterator<Item = T>,255 pub fn extend<I>(&mut self, iter: I) -> Result<()>
256 where
257 I: IntoIterator<Item = T>,
258 {
259 self.inner.extend(iter);
260 der_sort(&mut self.inner)
261 }
262
263 /// Insert an item into this [`SetOfVec`]. Must be unique.
insert(&mut self, item: T) -> Result<()>264 pub fn insert(&mut self, item: T) -> Result<()> {
265 self.inner.push(item);
266 der_sort(&mut self.inner)
267 }
268
269 /// Insert an item into this [`SetOfVec`]. Must be unique.
270 ///
271 /// Items MUST be added in lexicographical order according to the
272 /// [`DerOrd`] impl on `T`.
insert_ordered(&mut self, item: T) -> Result<()>273 pub fn insert_ordered(&mut self, item: T) -> Result<()> {
274 // Ensure set elements are lexicographically ordered
275 if let Some(last) = self.inner.last() {
276 check_der_ordering(last, &item)?;
277 }
278
279 self.inner.push(item);
280 Ok(())
281 }
282
283 /// Borrow the elements of this [`SetOfVec`] as a slice.
as_slice(&self) -> &[T]284 pub fn as_slice(&self) -> &[T] {
285 self.inner.as_slice()
286 }
287
288 /// Get the nth element from this [`SetOfVec`].
get(&self, index: usize) -> Option<&T>289 pub fn get(&self, index: usize) -> Option<&T> {
290 self.inner.get(index)
291 }
292
293 /// Convert this [`SetOfVec`] into the inner [`Vec`].
into_vec(self) -> Vec<T>294 pub fn into_vec(self) -> Vec<T> {
295 self.inner
296 }
297
298 /// Iterate over the elements of this [`SetOfVec`].
iter(&self) -> slice::Iter<'_, T>299 pub fn iter(&self) -> slice::Iter<'_, T> {
300 self.inner.iter()
301 }
302
303 /// Is this [`SetOfVec`] empty?
is_empty(&self) -> bool304 pub fn is_empty(&self) -> bool {
305 self.inner.is_empty()
306 }
307
308 /// Number of elements in this [`SetOfVec`].
len(&self) -> usize309 pub fn len(&self) -> usize {
310 self.inner.len()
311 }
312 }
313
314 #[cfg(feature = "alloc")]
315 impl<T> AsRef<[T]> for SetOfVec<T>
316 where
317 T: DerOrd,
318 {
as_ref(&self) -> &[T]319 fn as_ref(&self) -> &[T] {
320 self.as_slice()
321 }
322 }
323
324 #[cfg(feature = "alloc")]
325 impl<'a, T> DecodeValue<'a> for SetOfVec<T>
326 where
327 T: Decode<'a> + DerOrd,
328 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>329 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
330 reader.read_nested(header.length, |reader| {
331 let mut inner = Vec::new();
332
333 while !reader.is_finished() {
334 inner.push(T::decode(reader)?);
335 }
336
337 der_sort(inner.as_mut())?;
338 validate(inner.as_ref())?;
339 Ok(Self { inner })
340 })
341 }
342 }
343
344 #[cfg(feature = "alloc")]
345 impl<'a, T> EncodeValue for SetOfVec<T>
346 where
347 T: 'a + Decode<'a> + Encode + DerOrd,
348 {
value_len(&self) -> Result<Length>349 fn value_len(&self) -> Result<Length> {
350 self.iter()
351 .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
352 }
353
encode_value(&self, writer: &mut impl Writer) -> Result<()>354 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
355 for elem in self.iter() {
356 elem.encode(writer)?;
357 }
358
359 Ok(())
360 }
361 }
362
363 #[cfg(feature = "alloc")]
364 impl<T> FixedTag for SetOfVec<T>
365 where
366 T: DerOrd,
367 {
368 const TAG: Tag = Tag::Set;
369 }
370
371 #[cfg(feature = "alloc")]
372 impl<T> From<SetOfVec<T>> for Vec<T>
373 where
374 T: DerOrd,
375 {
from(set: SetOfVec<T>) -> Vec<T>376 fn from(set: SetOfVec<T>) -> Vec<T> {
377 set.into_vec()
378 }
379 }
380
381 #[cfg(feature = "alloc")]
382 impl<T> TryFrom<Vec<T>> for SetOfVec<T>
383 where
384 T: DerOrd,
385 {
386 type Error = Error;
387
try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>>388 fn try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>> {
389 der_sort(vec.as_mut_slice())?;
390 Ok(SetOfVec { inner: vec })
391 }
392 }
393
394 #[cfg(feature = "alloc")]
395 impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
396 where
397 T: DerOrd,
398 {
399 type Error = Error;
400
try_from(arr: [T; N]) -> Result<SetOfVec<T>>401 fn try_from(arr: [T; N]) -> Result<SetOfVec<T>> {
402 Vec::from(arr).try_into()
403 }
404 }
405
406 #[cfg(feature = "alloc")]
407 impl<T> ValueOrd for SetOfVec<T>
408 where
409 T: DerOrd,
410 {
value_cmp(&self, other: &Self) -> Result<Ordering>411 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
412 iter_cmp(self.iter(), other.iter())
413 }
414 }
415
416 // Implement by hand because the derive would create invalid values.
417 // Use the conversion from Vec to create a valid value.
418 #[cfg(feature = "arbitrary")]
419 impl<'a, T> arbitrary::Arbitrary<'a> for SetOfVec<T>
420 where
421 T: DerOrd + arbitrary::Arbitrary<'a>,
422 {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>423 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
424 Self::try_from(
425 u.arbitrary_iter()?
426 .collect::<std::result::Result<Vec<_>, _>>()?,
427 )
428 .map_err(|_| arbitrary::Error::IncorrectFormat)
429 }
430
size_hint(_depth: usize) -> (usize, Option<usize>)431 fn size_hint(_depth: usize) -> (usize, Option<usize>) {
432 (0, None)
433 }
434 }
435
436 /// Ensure set elements are lexicographically ordered using [`DerOrd`].
check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<()>437 fn check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<()> {
438 match a.der_cmp(b)? {
439 Ordering::Less => Ok(()),
440 Ordering::Equal => Err(ErrorKind::SetDuplicate.into()),
441 Ordering::Greater => Err(ErrorKind::SetOrdering.into()),
442 }
443 }
444
445 /// Sort a mut slice according to its [`DerOrd`], returning any errors which
446 /// might occur during the comparison.
447 ///
448 /// The algorithm is insertion sort, which should perform well when the input
449 /// is mostly sorted to begin with.
450 ///
451 /// This function is used rather than Rust's built-in `[T]::sort_by` in order
452 /// to support heapless `no_std` targets as well as to enable bubbling up
453 /// sorting errors.
454 #[allow(clippy::integer_arithmetic)]
der_sort<T: DerOrd>(slice: &mut [T]) -> Result<()>455 fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<()> {
456 for i in 0..slice.len() {
457 let mut j = i;
458
459 while j > 0 {
460 match slice[j - 1].der_cmp(&slice[j])? {
461 Ordering::Less => break,
462 Ordering::Equal => return Err(ErrorKind::SetDuplicate.into()),
463 Ordering::Greater => {
464 slice.swap(j - 1, j);
465 j -= 1;
466 }
467 }
468 }
469 }
470
471 Ok(())
472 }
473
474 /// Validate the elements of a `SET OF`, ensuring that they are all in order
475 /// and that there are no duplicates.
validate<T: DerOrd>(slice: &[T]) -> Result<()>476 fn validate<T: DerOrd>(slice: &[T]) -> Result<()> {
477 if let Some(len) = slice.len().checked_sub(1) {
478 for i in 0..len {
479 let j = i.checked_add(1).ok_or(ErrorKind::Overflow)?;
480
481 match slice.get(i..=j) {
482 Some([a, b]) => {
483 if a.der_cmp(b)? != Ordering::Less {
484 return Err(ErrorKind::SetOrdering.into());
485 }
486 }
487 _ => return Err(Tag::Set.value_error()),
488 }
489 }
490 }
491
492 Ok(())
493 }
494
495 #[cfg(test)]
496 mod tests {
497 use super::SetOf;
498 #[cfg(feature = "alloc")]
499 use super::SetOfVec;
500 use crate::ErrorKind;
501
502 #[test]
setof_tryfrom_array()503 fn setof_tryfrom_array() {
504 let arr = [3u16, 2, 1, 65535, 0];
505 let set = SetOf::try_from(arr).unwrap();
506 assert!(set.iter().copied().eq([0, 1, 2, 3, 65535]));
507 }
508
509 #[test]
setof_tryfrom_array_reject_duplicates()510 fn setof_tryfrom_array_reject_duplicates() {
511 let arr = [1u16, 1];
512 let err = SetOf::try_from(arr).err().unwrap();
513 assert_eq!(err.kind(), ErrorKind::SetDuplicate);
514 }
515
516 #[cfg(feature = "alloc")]
517 #[test]
setofvec_tryfrom_array()518 fn setofvec_tryfrom_array() {
519 let arr = [3u16, 2, 1, 65535, 0];
520 let set = SetOfVec::try_from(arr).unwrap();
521 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
522 }
523
524 #[cfg(feature = "alloc")]
525 #[test]
setofvec_tryfrom_vec()526 fn setofvec_tryfrom_vec() {
527 let vec = vec![3u16, 2, 1, 65535, 0];
528 let set = SetOfVec::try_from(vec).unwrap();
529 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
530 }
531
532 #[cfg(feature = "alloc")]
533 #[test]
setofvec_tryfrom_vec_reject_duplicates()534 fn setofvec_tryfrom_vec_reject_duplicates() {
535 let vec = vec![1u16, 1];
536 let err = SetOfVec::try_from(vec).err().unwrap();
537 assert_eq!(err.kind(), ErrorKind::SetDuplicate);
538 }
539 }
540