Skip to main content

der/asn1/
set_of.rs

1//! ASN.1 `SET OF` support.
2//!
3//! # Ordering Notes
4//!
5//! Some DER serializer implementations fail to properly sort elements of a `SET OF`. This is
6//! technically non-canonical, but occurs frequently enough that most DER decoders tolerate it.
7//!
8//! When decoding with `EncodingRules::Der`, this implementation sorts the elements of `SET OF` at
9//! decode-time to ensure reserializations are canonical.
10
11#![cfg(any(feature = "alloc", feature = "heapless"))]
12
13use crate::{
14    Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, ErrorKind, FixedTag, Header, Length,
15    Reader, SliceReader, Tag, ValueOrd, Writer, ord::iter_cmp, ord::iter_cmp_owned,
16};
17use core::cmp::Ordering;
18
19#[cfg(feature = "alloc")]
20use alloc::vec::Vec;
21#[cfg(any(feature = "alloc", feature = "heapless"))]
22use core::slice;
23
24/// ASN.1 `SET OF` backed by an array.
25///
26/// This type implements an append-only `SET OF` type which is stack-based
27/// and does not depend on `alloc` support.
28// TODO(tarcieri): use `ArrayVec` when/if it's merged into `core` (rust-lang/rfcs#3316)
29#[cfg(feature = "heapless")]
30#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
31pub struct SetOf<T, const N: usize>
32where
33    T: DerOrd,
34{
35    inner: heapless::Vec<T, N>,
36}
37
38// Inner reference of a SetOfRef
39//
40// An internal reference can either be bytes when constructed during decoding
41// or a slice of items of the generic type T.
42#[derive(Clone, Debug, Eq, PartialEq, Hash)]
43enum InnerRef<'a, T> {
44    BytesRef(&'a [u8], usize),
45    ObjectsRef(&'a [T]),
46}
47
48/// ASN.1 `SET OF` with a reference to an array.
49///
50/// This type implements a viewer in a `SET OF` type
51/// and does not depend on `alloc` support.
52#[derive(Clone, Debug, Eq, PartialEq, Hash)]
53pub struct SetOfRef<'a, T>
54where
55    T: DerOrd,
56{
57    inner: InnerRef<'a, T>,
58}
59
60#[cfg(feature = "heapless")]
61impl<T, const N: usize> SetOf<T, N>
62where
63    T: DerOrd,
64{
65    /// Create a new [`SetOf`].
66    #[must_use]
67    pub fn new() -> Self {
68        Self {
69            inner: heapless::Vec::default(),
70        }
71    }
72
73    /// Insert an item into this [`SetOf`].
74    ///
75    /// # Errors
76    /// If there's a sorting error.
77    pub fn insert(&mut self, item: T) -> Result<(), Error> {
78        self.try_push(item)?;
79        der_sort(self.inner.as_mut())
80    }
81
82    /// Insert an item into this [`SetOf`].
83    ///
84    /// Items MUST be added in lexicographical order according to the [`DerOrd`] impl on `T`.
85    ///
86    /// # Errors
87    /// If items are added out-of-order or there isn't sufficient space.
88    pub fn insert_ordered(&mut self, item: T) -> Result<(), Error> {
89        // Ensure set elements are lexicographically ordered
90        if let Some(last) = self.inner.last() {
91            check_der_ordering(last, &item)?;
92        }
93
94        self.try_push(item)
95    }
96
97    /// Borrow the elements of this [`SetOf`] as a slice.
98    pub fn as_slice(&self) -> &[T] {
99        self.inner.as_slice()
100    }
101
102    /// Get the nth element from this [`SetOf`].
103    pub fn get(&self, index: usize) -> Option<&T> {
104        self.inner.get(index)
105    }
106
107    /// Extract the inner `heapless::Vec`.
108    pub fn into_inner(self) -> heapless::Vec<T, N> {
109        self.inner
110    }
111
112    /// Iterate over the elements of this [`SetOf`].
113    pub fn iter(&self) -> SetOfIter<'_, T> {
114        SetOfIter {
115            inner: self.inner.iter(),
116        }
117    }
118
119    /// Is this [`SetOf`] empty?
120    pub fn is_empty(&self) -> bool {
121        self.inner.is_empty()
122    }
123
124    /// Number of elements in this [`SetOf`].
125    pub fn len(&self) -> usize {
126        self.inner.len()
127    }
128
129    /// Attempt to push an element onto the [`SetOf`].
130    ///
131    /// Does not perform ordering or uniqueness checks.
132    fn try_push(&mut self, item: T) -> Result<(), Error> {
133        self.inner
134            .push(item)
135            .map_err(|_| ErrorKind::Overlength.into())
136    }
137}
138
139#[cfg(feature = "heapless")]
140impl<T, const N: usize> AsRef<[T]> for SetOf<T, N>
141where
142    T: DerOrd,
143{
144    fn as_ref(&self) -> &[T] {
145        self.as_slice()
146    }
147}
148
149impl<'a, T> SetOfRef<'a, T>
150where
151    T: Decode<'a> + 'a,
152    T: Clone + DerOrd,
153{
154    /// Creates a [`SetOfRef`] by parsing the *contents* of a DER-encoded `SET OF` —
155    /// that is, the raw bytes after the tag and length bytes have been stripped.
156    fn from_bytes(v: &'a [u8]) -> Result<Self, T::Error> {
157        // Cache len for .iter() calls
158        let mut iter_len = 0;
159
160        // Make sure we can decode valid objects from the bytes
161        let mut reader = SliceReader::new(v)?;
162
163        // Remember last item to check ordering
164        let mut last_item: Option<T> = None;
165
166        while !reader.is_finished() {
167            let item = T::decode(&mut reader)?;
168
169            if let Some(last_item) = last_item {
170                check_der_ordering(&last_item, &item)?;
171            }
172            last_item = Some(item);
173            iter_len += 1;
174        }
175
176        // Generate the set as a byte reference
177        Ok(Self {
178            inner: InnerRef::BytesRef(v, iter_len),
179        })
180    }
181
182    /// Get the nth element from this [`SetOfRef`].
183    #[must_use]
184    pub fn get(&self, index: usize) -> Option<T>
185    where
186        T: Decode<'a> + 'a,
187        T: Clone,
188    {
189        self.iter().nth(index)
190    }
191
192    /// Iterate over the elements of this [`SetOfRef`].
193    ///
194    /// # Panics
195    ///
196    /// Panics if the inner byte slice contains invalid data that cannot be
197    /// parsed by [`SliceReader`].
198    #[must_use]
199    pub fn iter(&self) -> SetOfRefIter<'a, T>
200    where
201        T: Decode<'a> + 'a,
202    {
203        match self.inner {
204            InnerRef::BytesRef(inner, length) => SetOfRefIter {
205                inner: InnerIterRef::<'a, T>::BytesRef(
206                    SliceReader::new(inner).expect("Invalid data"),
207                ),
208                length,
209            },
210            InnerRef::ObjectsRef(inner) => SetOfRefIter {
211                inner: InnerIterRef::<'a, T>::ObjectsRef(inner),
212                length: inner.len(),
213            },
214        }
215    }
216
217    /// Is this [`SetOfRef`] empty?
218    #[must_use]
219    pub fn is_empty(&self) -> bool {
220        match self.inner {
221            InnerRef::BytesRef(inner, _) => inner.is_empty(),
222            InnerRef::ObjectsRef(inner) => inner.is_empty(),
223        }
224    }
225
226    /// Number of elements in this [`SetOfRef`].
227    #[must_use]
228    pub fn len(&self) -> usize
229    where
230        T: Decode<'a> + 'a,
231        T: Clone,
232    {
233        self.iter().len()
234    }
235}
236
237#[cfg(feature = "heapless")]
238impl<T, const N: usize> Default for SetOf<T, N>
239where
240    T: DerOrd,
241{
242    fn default() -> Self {
243        Self::new()
244    }
245}
246
247#[cfg(feature = "heapless")]
248impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
249where
250    T: Decode<'a> + DerOrd,
251{
252    type Error = T::Error;
253
254    fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> Result<Self, Self::Error> {
255        let mut result = Self::new();
256
257        while !reader.is_finished() {
258            result.try_push(T::decode(reader)?)?;
259        }
260
261        if reader.encoding_rules().is_der() {
262            // Ensure elements of the `SetOf` are sorted and will serialize as valid DER
263            der_sort(result.inner.as_mut())?;
264        }
265
266        Ok(result)
267    }
268}
269
270impl<'a, T> DecodeValue<'a> for SetOfRef<'a, T>
271where
272    T: Clone,
273    T: Decode<'a> + DerOrd,
274{
275    type Error = T::Error;
276
277    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
278        let inner_slice: &'a [u8] = reader.read_slice(header.length())?;
279        SetOfRef::<'a, T>::from_bytes(inner_slice)
280    }
281}
282
283#[cfg(feature = "heapless")]
284impl<T, const N: usize> EncodeValue for SetOf<T, N>
285where
286    T: Encode + DerOrd,
287{
288    fn value_len(&self) -> Result<Length, Error> {
289        self.iter()
290            .try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
291    }
292
293    fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
294        for elem in self.iter() {
295            elem.encode(writer)?;
296        }
297
298        Ok(())
299    }
300}
301
302impl<'a, T> EncodeValue for SetOfRef<'a, T>
303where
304    T: Decode<'a> + Encode + DerOrd,
305    T: Clone,
306{
307    fn value_len(&self) -> Result<Length, Error> {
308        self.iter()
309            .try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
310    }
311
312    fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
313        for elem in self.iter() {
314            elem.encode(writer)?;
315        }
316
317        Ok(())
318    }
319}
320
321#[cfg(feature = "heapless")]
322impl<T, const N: usize> FixedTag for SetOf<T, N>
323where
324    T: DerOrd,
325{
326    const TAG: Tag = Tag::Set;
327}
328
329impl<'a, T> FixedTag for SetOfRef<'a, T>
330where
331    T: DerOrd,
332{
333    const TAG: Tag = Tag::Set;
334}
335
336#[cfg(feature = "heapless")]
337impl<T, const N: usize> TryFrom<[T; N]> for SetOf<T, N>
338where
339    T: DerOrd,
340{
341    type Error = Error;
342
343    fn try_from(mut arr: [T; N]) -> Result<SetOf<T, N>, Error> {
344        der_sort(&mut arr)?;
345
346        let mut result = SetOf::new();
347
348        for elem in arr {
349            result.insert_ordered(elem)?;
350        }
351
352        Ok(result)
353    }
354}
355
356impl<'a, T> TryFrom<&'a [T]> for SetOfRef<'a, T>
357where
358    T: DerOrd,
359{
360    type Error = Error;
361
362    fn try_from(arr: &'a [T]) -> Result<SetOfRef<'a, T>, Error> {
363        arr.iter()
364            .is_sorted_by(|&a, &b| check_der_ordering(a, b).is_ok())
365            .then_some(SetOfRef {
366                inner: InnerRef::ObjectsRef(arr),
367            })
368            .ok_or_else(|| Error::from_kind(ErrorKind::SetOrdering))
369    }
370}
371
372impl<'a, T> From<&SetOfRef<'a, T>> for SetOfRef<'a, T>
373where
374    T: Clone + DerOrd,
375{
376    fn from(value: &SetOfRef<'a, T>) -> SetOfRef<'a, T> {
377        value.clone()
378    }
379}
380
381#[cfg(feature = "heapless")]
382impl<T, const N: usize> ValueOrd for SetOf<T, N>
383where
384    T: DerOrd,
385{
386    fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
387        iter_cmp(self.iter(), other.iter())
388    }
389}
390
391impl<'a, T> ValueOrd for SetOfRef<'a, T>
392where
393    T: Decode<'a> + DerOrd + 'a,
394    T: Clone,
395{
396    fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
397        iter_cmp_owned(self.iter(), other.iter())
398    }
399}
400
401/// Iterator over the elements of an [`SetOf`].
402#[derive(Clone, Debug)]
403pub struct SetOfIter<'a, T> {
404    /// Inner iterator.
405    inner: slice::Iter<'a, T>,
406}
407
408impl<'a, T: 'a> Iterator for SetOfIter<'a, T> {
409    type Item = &'a T;
410
411    fn next(&mut self) -> Option<&'a T> {
412        self.inner.next()
413    }
414
415    fn size_hint(&self) -> (usize, Option<usize>) {
416        self.inner.size_hint()
417    }
418}
419
420impl<'a, T: 'a> ExactSizeIterator for SetOfIter<'a, T> {}
421
422// Inner reference of a SetOfRefIter
423//
424// An internal reference can either be a slice reader when constructed during decoding
425// or a slice of items of the generic type T.
426#[derive(Clone, Debug)]
427enum InnerIterRef<'a, T> {
428    BytesRef(SliceReader<'a>),
429    ObjectsRef(&'a [T]),
430}
431
432/// Iterator over the elements of an [`SetOfRef`].
433#[derive(Clone, Debug)]
434pub struct SetOfRefIter<'a, T>
435where
436    T: Decode<'a>,
437{
438    /// Inner iterator.
439    inner: InnerIterRef<'a, T>,
440    length: usize,
441}
442
443impl<'a, T> Iterator for SetOfRefIter<'a, T>
444where
445    T: Decode<'a> + 'a,
446    T: Clone,
447{
448    type Item = T;
449
450    fn next(&mut self) -> Option<T> {
451        match &mut self.inner {
452            InnerIterRef::BytesRef(inner_reader) => {
453                if inner_reader.is_finished() {
454                    return None;
455                }
456
457                let next_val = T::decode(inner_reader).ok()?;
458                self.length -= 1;
459                Some(next_val)
460            }
461            InnerIterRef::ObjectsRef(inner_slice) => {
462                let next_val = inner_slice.first()?;
463                self.inner = InnerIterRef::ObjectsRef(&inner_slice[1..]);
464                self.length -= 1;
465
466                Some(next_val.clone())
467            }
468        }
469    }
470
471    fn size_hint(&self) -> (usize, Option<usize>) {
472        (self.length, Some(self.length))
473    }
474}
475
476impl<'a, T> ExactSizeIterator for SetOfRefIter<'a, T>
477where
478    T: Decode<'a> + 'a,
479    T: Clone,
480{
481}
482
483/// ASN.1 `SET OF` backed by a [`Vec`].
484///
485/// This type implements an append-only `SET OF` type which is heap-backed
486/// and depends on `alloc` support.
487#[cfg(feature = "alloc")]
488#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
489pub struct SetOfVec<T>
490where
491    T: DerOrd,
492{
493    inner: Vec<T>,
494}
495
496#[cfg(feature = "alloc")]
497impl<T: DerOrd> Default for SetOfVec<T> {
498    fn default() -> Self {
499        Self {
500            inner: Default::default(),
501        }
502    }
503}
504
505#[cfg(feature = "alloc")]
506impl<T> SetOfVec<T>
507where
508    T: DerOrd,
509{
510    /// Create a new [`SetOfVec`].
511    #[must_use]
512    pub fn new() -> Self {
513        Self {
514            inner: Vec::default(),
515        }
516    }
517
518    /// Create a new [`SetOfVec`] from the given iterator.
519    ///
520    /// Note: this is an inherent method instead of an impl of the [`FromIterator`] trait in order
521    /// to be fallible.
522    ///
523    /// # Errors
524    /// If a sorting error occurred.
525    #[allow(clippy::should_implement_trait)]
526    pub fn from_iter<I>(iter: I) -> Result<Self, Error>
527    where
528        I: IntoIterator<Item = T>,
529    {
530        Vec::from_iter(iter).try_into()
531    }
532
533    /// Extend a [`SetOfVec`] using an iterator.
534    ///
535    /// Note: this is an inherent method instead of an impl of the [`Extend`] trait in order to
536    /// be fallible.
537    ///
538    /// # Errors
539    /// If a sorting error occurred.
540    pub fn extend<I>(&mut self, iter: I) -> Result<(), Error>
541    where
542        I: IntoIterator<Item = T>,
543    {
544        self.inner.extend(iter);
545        der_sort(&mut self.inner)
546    }
547
548    /// Insert an item into this [`SetOfVec`]. Must be unique.
549    ///
550    /// # Errors
551    /// If a sorting error occurred.
552    pub fn insert(&mut self, item: T) -> Result<(), Error> {
553        self.inner.push(item);
554        der_sort(&mut self.inner)
555    }
556
557    /// Insert an item into this [`SetOfVec`]. Must be unique.
558    ///
559    /// Items MUST be added in lexicographical order according to the [`DerOrd`] impl on `T`.
560    ///
561    /// # Errors
562    /// If a sorting error occurred.
563    pub fn insert_ordered(&mut self, item: T) -> Result<(), Error> {
564        // Ensure set elements are lexicographically ordered
565        if let Some(last) = self.inner.last() {
566            check_der_ordering(last, &item)?;
567        }
568
569        self.inner.push(item);
570        Ok(())
571    }
572
573    /// Borrow the elements of this [`SetOfVec`] as a slice.
574    #[must_use]
575    pub fn as_slice(&self) -> &[T] {
576        self.inner.as_slice()
577    }
578
579    /// Get the nth element from this [`SetOfVec`].
580    #[must_use]
581    pub fn get(&self, index: usize) -> Option<&T> {
582        self.inner.get(index)
583    }
584
585    /// Convert this [`SetOfVec`] into the inner [`Vec`].
586    #[must_use]
587    pub fn into_vec(self) -> Vec<T> {
588        self.inner
589    }
590
591    /// Iterate over the elements of this [`SetOfVec`].
592    #[must_use]
593    pub fn iter(&self) -> SetOfIter<'_, T> {
594        SetOfIter {
595            inner: self.inner.iter(),
596        }
597    }
598
599    /// Is this [`SetOfVec`] empty?
600    #[must_use]
601    pub fn is_empty(&self) -> bool {
602        self.inner.is_empty()
603    }
604
605    /// Number of elements in this [`SetOfVec`].
606    #[must_use]
607    pub fn len(&self) -> usize {
608        self.inner.len()
609    }
610}
611
612#[cfg(feature = "alloc")]
613impl<T> AsRef<[T]> for SetOfVec<T>
614where
615    T: DerOrd,
616{
617    fn as_ref(&self) -> &[T] {
618        self.as_slice()
619    }
620}
621
622#[cfg(feature = "alloc")]
623impl<'a, T> DecodeValue<'a> for SetOfVec<T>
624where
625    T: Decode<'a> + DerOrd,
626{
627    type Error = T::Error;
628
629    fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> Result<Self, Self::Error> {
630        let mut inner = Vec::new();
631
632        while !reader.is_finished() {
633            inner.push(T::decode(reader)?);
634        }
635
636        if reader.encoding_rules().is_der() {
637            der_sort(inner.as_mut())?;
638        }
639
640        Ok(Self { inner })
641    }
642}
643
644#[cfg(feature = "alloc")]
645impl<T> EncodeValue for SetOfVec<T>
646where
647    T: Encode + DerOrd,
648{
649    fn value_len(&self) -> Result<Length, Error> {
650        self.iter()
651            .try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
652    }
653
654    fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
655        for elem in self.iter() {
656            elem.encode(writer)?;
657        }
658
659        Ok(())
660    }
661}
662
663#[cfg(feature = "alloc")]
664impl<T> FixedTag for SetOfVec<T>
665where
666    T: DerOrd,
667{
668    const TAG: Tag = Tag::Set;
669}
670
671#[cfg(feature = "alloc")]
672impl<T> From<SetOfVec<T>> for Vec<T>
673where
674    T: DerOrd,
675{
676    fn from(set: SetOfVec<T>) -> Vec<T> {
677        set.into_vec()
678    }
679}
680
681#[cfg(feature = "alloc")]
682impl<T> TryFrom<Vec<T>> for SetOfVec<T>
683where
684    T: DerOrd,
685{
686    type Error = Error;
687
688    fn try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>, Error> {
689        // TODO(tarcieri): use `[T]::sort_by` here?
690        der_sort(vec.as_mut_slice())?;
691        Ok(SetOfVec { inner: vec })
692    }
693}
694
695#[cfg(feature = "alloc")]
696impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
697where
698    T: DerOrd,
699{
700    type Error = Error;
701
702    fn try_from(arr: [T; N]) -> Result<SetOfVec<T>, Error> {
703        Vec::from(arr).try_into()
704    }
705}
706
707#[cfg(feature = "alloc")]
708impl<T> ValueOrd for SetOfVec<T>
709where
710    T: DerOrd,
711{
712    fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
713        iter_cmp(self.iter(), other.iter())
714    }
715}
716
717// Implement by hand because custom derive would create invalid values.
718// Use the conversion from Vec to create a valid value.
719#[cfg(feature = "arbitrary")]
720impl<'a, T> arbitrary::Arbitrary<'a> for SetOfVec<T>
721where
722    T: DerOrd + arbitrary::Arbitrary<'a>,
723{
724    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
725        Self::try_from(u.arbitrary_iter()?.collect::<Result<Vec<_>, _>>()?)
726            .map_err(|_| arbitrary::Error::IncorrectFormat)
727    }
728
729    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
730        (0, None)
731    }
732}
733
734/// Ensure set elements are lexicographically ordered using [`DerOrd`].
735fn check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<(), Error> {
736    if a.der_cmp(b)? == Ordering::Greater {
737        return Err(ErrorKind::SetOrdering.into());
738    }
739
740    Ok(())
741}
742
743/// Sort a mut slice according to its [`DerOrd`], returning any errors which
744/// might occur during the comparison.
745///
746/// Uses [`slice::sort_unstable_by`] (an O(n log n) introsort) rather than the
747/// stable [`slice::sort_by`] because the latter requires `alloc`, while this
748/// function must also work on heapless `no_std` targets where only `core` is
749/// available. Sorting unstably is fine here: two elements that compare
750/// [`Ordering::Equal`] under [`DerOrd`] have identical DER encodings, so their
751/// relative order does not affect the serialized output.
752///
753/// A previous implementation used a hand-rolled insertion sort. On adversarial
754/// reverse-sorted input that degrades to O(n^2), which let a crafted `SET OF`
755/// turn a single decode into a quadratic-time denial of service (see
756/// <https://github.com/RustCrypto/formats/issues/2319>).
757///
758/// `DerOrd::der_cmp` is fallible. Since the standard sort comparator must
759/// return [`Ordering`] rather than a `Result`, the first comparison error is
760/// captured and returned after the sort completes; on error the slice is left
761/// in an unspecified (but valid) order.
762fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<(), Error> {
763    let mut first_err: Option<Error> = None;
764
765    slice.sort_unstable_by(|a, b| {
766        a.der_cmp(b).unwrap_or_else(|err| {
767            first_err.get_or_insert(err);
768            Ordering::Equal
769        })
770    });
771
772    first_err.map_or(Ok(()), Err)
773}
774
775#[cfg(feature = "alloc")]
776mod allocating {
777    use super::*;
778    use crate::referenced::*;
779
780    impl<'a, T> RefToOwned<'a> for SetOfRef<'a, T>
781    where
782        T: Decode<'a> + EncodeValue + 'a,
783        T: DerOrd + FixedTag,
784        T: Clone,
785    {
786        type Owned = SetOfVec<T>;
787        fn ref_to_owned(&self) -> Self::Owned {
788            SetOfVec::from_iter(self.iter()).expect("SetOfVec: Could not sort inner slice")
789        }
790    }
791
792    impl<T> OwnedToRef for SetOfVec<T>
793    where
794        T: Encode,
795        T: DerOrd,
796    {
797        type Borrowed<'a>
798            = SetOfRef<'a, T>
799        where
800            T: 'a;
801
802        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
803            SetOfRef::<T>::try_from(self.inner.as_slice()).expect("Unsorted slice")
804        }
805    }
806}
807
808#[cfg(test)]
809#[allow(clippy::unwrap_used)]
810mod tests {
811
812    use crate::{ErrorKind, Tag, asn1::OctetStringRef};
813    #[cfg(feature = "alloc")]
814    use {
815        super::SetOfVec,
816        crate::{Decode, Encode, EncodeValue, SliceWriter},
817        alloc::vec,
818    };
819
820    #[cfg(feature = "heapless")]
821    use super::SetOf;
822    #[cfg(any(feature = "alloc", feature = "heapless"))]
823    use {super::SetOfRef, crate::DerOrd};
824
825    #[cfg(feature = "heapless")]
826    #[test]
827    fn setof_insert() {
828        let mut setof = SetOf::<u8, 10>::new();
829        setof.insert(42).unwrap();
830        assert_eq!(setof.len(), 1);
831        assert_eq!(*setof.iter().next().unwrap(), 42);
832    }
833
834    #[cfg(feature = "heapless")]
835    #[test]
836    fn setof_insert_duplicate() {
837        let mut setof = SetOf::<u8, 10>::new();
838        setof.insert(42).unwrap();
839        assert_eq!(setof.len(), 1);
840
841        setof.insert(42).unwrap();
842
843        let mut iter = setof.iter();
844
845        assert_eq!(setof.len(), 2);
846        assert_eq!(*iter.next().unwrap(), 42);
847        assert_eq!(*iter.next().unwrap(), 42);
848    }
849
850    #[cfg(feature = "heapless")]
851    #[test]
852    fn setof_tryfrom_array() {
853        let arr = [3u16, 2, 1, 65535, 0];
854        let set = SetOf::try_from(arr).unwrap();
855        assert!(set.iter().copied().eq([0, 1, 2, 3, 65535]));
856    }
857
858    #[cfg(feature = "heapless")]
859    #[test]
860    fn setof_valueord_value_cmp() {
861        use core::cmp::Ordering;
862
863        let arr1 = [3u16, 2, 1, 5, 0];
864        let arr2 = [3u16, 2, 1, 4, 0];
865        let set1 = SetOf::try_from(arr1).unwrap();
866        let set2 = SetOf::try_from(arr2).unwrap();
867        assert_eq!(set1.der_cmp(&set2), Ok(Ordering::Greater));
868    }
869
870    #[test]
871    fn setofref_tryfrom_array() {
872        let arr = [0u16, 1, 2, 3, 65535];
873        let set = SetOfRef::try_from(arr.as_ref()).unwrap();
874        assert!(set.iter().eq([0, 1, 2, 3, 65535]));
875    }
876
877    #[cfg(feature = "alloc")]
878    #[test]
879    fn setofref_tryfrom_der() {
880        let arr = SetOfVec::try_from([0u16, 1, 2, 3, 65535])
881            .unwrap()
882            .to_der()
883            .unwrap();
884        let set = SetOfRef::<u16>::from_der(arr.as_ref()).unwrap();
885        assert!(set.iter().eq([0, 1, 2, 3, 65535]));
886    }
887
888    #[cfg(feature = "alloc")]
889    #[test]
890    fn setofref_tryfrom_bytes() {
891        let arr = SetOfVec::try_from([0u16, 1, 2, 3, 65535]).unwrap();
892
893        let mut encoded = vec![0u8; arr.value_len().unwrap().try_into().unwrap()];
894        let mut writer = SliceWriter::new(&mut encoded);
895        arr.encode_value(&mut writer).unwrap();
896
897        let decoded = SetOfRef::<u16>::from_bytes(writer.finish().unwrap()).unwrap();
898
899        assert!(decoded.iter().eq([0, 1, 2, 3, 65535]));
900    }
901
902    #[test]
903    fn setofref_tryfrom_array_reject_unsorted() {
904        let arr = [3u16, 2, 1, 65535, 0];
905        let err = SetOfRef::try_from(arr.as_ref()).err().unwrap();
906        assert_eq!(err.kind(), ErrorKind::SetOrdering);
907    }
908
909    #[test]
910    fn setofref_tryfrom_array_allow_duplicates() {
911        let arr = [1u16, 1];
912        let set = SetOfRef::try_from(arr.as_ref()).unwrap();
913        assert!(set.iter().eq([1, 1]));
914    }
915
916    #[test]
917    fn setofref_valueord_value_cmp() {
918        use core::cmp::Ordering;
919
920        let arr1 = [0u16, 1, 2, 3, 5];
921        let arr2 = [0u16, 1, 2, 3, 4];
922        let set1 = SetOfRef::try_from(arr1.as_ref()).unwrap();
923        let set2 = SetOfRef::try_from(arr2.as_ref()).unwrap();
924        assert_eq!(set1.der_cmp(&set2), Ok(Ordering::Greater));
925    }
926
927    #[test]
928    fn setofref_from_bytes_should_return_decode_error() {
929        let inner_slice = [0x04, 0x00, 0x05, 0x00];
930        let result = SetOfRef::<'_, &OctetStringRef>::from_bytes(&inner_slice);
931
932        assert_eq!(
933            result,
934            Err(ErrorKind::TagUnexpected {
935                expected: Some(Tag::OctetString),
936                actual: Tag::Null
937            }
938            .into())
939        );
940    }
941
942    #[cfg(feature = "alloc")]
943    #[test]
944    fn setofvec_insert() {
945        let mut setof = SetOfVec::new();
946        setof.insert(42).unwrap();
947        assert_eq!(setof.len(), 1);
948
949        setof.insert(46).unwrap();
950
951        let mut iter = setof.iter();
952
953        assert_eq!(setof.len(), 2);
954        assert_eq!(*iter.next().unwrap(), 42);
955        assert_eq!(*iter.next().unwrap(), 46);
956    }
957
958    #[cfg(feature = "alloc")]
959    #[test]
960    fn setofvec_tryfrom_array() {
961        let arr = [3u16, 2, 1, 65535, 0];
962        let set = SetOfVec::try_from(arr).unwrap();
963        assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
964    }
965
966    #[cfg(feature = "alloc")]
967    #[test]
968    fn setofvec_tryfrom_vec() {
969        let vec = vec![3u16, 2, 1, 65535, 0];
970        let set = SetOfVec::try_from(vec).unwrap();
971        assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
972    }
973
974    #[cfg(feature = "alloc")]
975    #[test]
976    fn setofvec_tryfrom_vec_allow_duplicates() {
977        let vec = vec![1u16, 1];
978        let set = SetOfVec::try_from(vec).unwrap();
979        assert_eq!(set.as_ref(), &[1, 1]);
980    }
981
982    // Regression tests for #2319: `der_sort` was a hand-rolled O(n^2) insertion
983    // sort, which a crafted reverse-sorted `SET OF` could exploit for a
984    // quadratic-time denial of service. The fix swaps in `sort_unstable_by`
985    // (O(n log n)). These tests pin the externally observable contract so the
986    // algorithm swap cannot silently change behavior: the resulting order, the
987    // DER `SET OF` ordering invariant, and duplicate preservation.
988
989    #[cfg(feature = "alloc")]
990    use alloc::vec::Vec;
991
992    /// Reference implementation: the original insertion sort that `der_sort`
993    /// replaced. Used to confirm the new sort yields a byte-identical ordering.
994    #[cfg(feature = "alloc")]
995    fn insertion_sort_reference<T: DerOrd>(slice: &mut [T]) {
996        for i in 0..slice.len() {
997            let mut j = i;
998            while j > 0 {
999                if slice[j - 1].der_cmp(&slice[j]).unwrap() == core::cmp::Ordering::Greater {
1000                    slice.swap(j - 1, j);
1001                    j -= 1;
1002                } else {
1003                    break;
1004                }
1005            }
1006        }
1007    }
1008
1009    /// Assert the slice obeys the DER `SET OF` ordering invariant: each element
1010    /// is less-than-or-equal to its successor under `DerOrd`. Equal neighbors
1011    /// (duplicates / encoding ties) are allowed, matching the decoder.
1012    #[cfg(feature = "alloc")]
1013    fn assert_der_sorted<T: DerOrd>(slice: &[T]) {
1014        for pair in slice.windows(2) {
1015            assert_ne!(
1016                pair[0].der_cmp(&pair[1]).unwrap(),
1017                core::cmp::Ordering::Greater,
1018                "der_sort left an out-of-order pair"
1019            );
1020        }
1021    }
1022
1023    /// A small deterministic LCG so the test is reproducible without a `rand`
1024    /// dependency (the crate has none in dev-deps for this path).
1025    #[cfg(feature = "alloc")]
1026    fn lcg_next(state: &mut u64) -> u16 {
1027        *state = state
1028            .wrapping_mul(6364136223846793005)
1029            .wrapping_add(1442695040888963407);
1030        // Intentionally take the low 16 bits of the high word as the output;
1031        // the mask makes the truncation explicit rather than a lossy `as` cast.
1032        ((*state >> 33) & 0xFFFF) as u16
1033    }
1034
1035    /// The fix must not change which ordering `der_sort` produces. Cross-check
1036    /// it against the original insertion sort on many inputs: fully randomized
1037    /// (with intentional duplicates from a narrow value range), the adversarial
1038    /// reverse-sorted case from the issue, already-sorted, and constant.
1039    #[cfg(feature = "alloc")]
1040    #[test]
1041    fn der_sort_matches_reference_ordering() {
1042        let mut rng_state = 0x2319_u64;
1043
1044        // Randomized inputs of varied sizes. The narrow value range forces
1045        // frequent duplicates so duplicate handling is exercised.
1046        for &len in &[0usize, 1, 2, 5, 17, 64, 257, 1000] {
1047            let original: Vec<u16> = (0..len).map(|_| lcg_next(&mut rng_state) % 50).collect();
1048
1049            let mut via_new = original.clone();
1050            super::der_sort(&mut via_new).unwrap();
1051
1052            let mut via_reference = original.clone();
1053            insertion_sort_reference(&mut via_reference);
1054
1055            assert_eq!(via_new, via_reference, "ordering diverged at len={len}");
1056            assert_der_sorted(&via_new);
1057            // Multiset is preserved (nothing dropped or duplicated by the sort).
1058            let mut a = original.clone();
1059            let mut b = via_new.clone();
1060            a.sort_unstable();
1061            b.sort_unstable();
1062            assert_eq!(a, b, "der_sort changed the multiset at len={len}");
1063        }
1064
1065        // Adversarial worst case for insertion sort: strictly reverse-sorted.
1066        let reversed: Vec<u16> = (0..2000u16).rev().collect();
1067        let mut via_new = reversed.clone();
1068        super::der_sort(&mut via_new).unwrap();
1069        let mut via_reference = reversed;
1070        insertion_sort_reference(&mut via_reference);
1071        assert_eq!(via_new, via_reference);
1072        assert_der_sorted(&via_new);
1073        assert!(via_new.iter().copied().eq(0..2000u16));
1074    }
1075
1076    /// Decoding a large reverse-sorted DER `SET OF` must succeed, sort
1077    /// correctly, and re-encode to canonical (sorted) DER. This is the decode
1078    /// path that the `DoS` in #2319 targeted. With the O(n^2) sort this input
1079    /// took seconds; with O(n log n) it is effectively instant, but the
1080    /// assertion here is on correctness, not timing.
1081    #[cfg(feature = "alloc")]
1082    #[test]
1083    fn setofvec_decodes_large_reverse_sorted_der() {
1084        // Build non-canonical (reverse-sorted) DER for a SET OF INTEGER.
1085        let n = 4000u16;
1086        let elements: Vec<u16> = (0..n).rev().collect();
1087
1088        let mut encoded = elements.to_der().unwrap();
1089        // Trick: change SEQUENCE tag 0x30 to SET 0x31
1090        encoded[0] = 0x31;
1091
1092        // Decoder accepts the non-canonical input and sorts it at decode time.
1093        let set = SetOfVec::<u16>::from_der(&encoded).unwrap();
1094        assert_eq!(set.len(), n as usize);
1095        assert!(set.iter().copied().eq(0..n));
1096        assert_der_sorted(set.as_ref());
1097
1098        // Re-encoding yields canonical (sorted) DER, distinct from the input.
1099        let reencoded = set.to_der().unwrap();
1100        assert_ne!(reencoded, encoded, "expected canonicalization on re-encode");
1101        // And the canonical form round-trips unchanged.
1102        let reparsed = SetOfVec::<u16>::from_der(&reencoded).unwrap();
1103        assert!(reparsed.iter().copied().eq(0..n));
1104    }
1105
1106    /// Duplicate elements (allowed since #2272) must survive the sort: equal
1107    /// encodings are kept, not deduplicated, and end up adjacent.
1108    #[cfg(feature = "alloc")]
1109    #[test]
1110    fn der_sort_preserves_duplicates() {
1111        let vec = vec![5u16, 1, 5, 1, 3, 1, 5];
1112        let set = SetOfVec::try_from(vec).unwrap();
1113        assert_eq!(set.as_ref(), &[1, 1, 1, 3, 5, 5, 5]);
1114        assert_eq!(set.len(), 7);
1115    }
1116}