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