1 //! ASN.1 `SET OF` support.
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.
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.
14 arrayvec
, ord
::iter_cmp
, ArrayVec
, Decode
, DecodeValue
, DerOrd
, Encode
, EncodeValue
, Error
,
15 ErrorKind
, FixedTag
, Header
, Length
, Reader
, Result
, Tag
, ValueOrd
, Writer
,
17 use core
::cmp
::Ordering
;
19 #[cfg(feature = "alloc")]
20 use {alloc::vec::Vec, core::slice}
;
22 /// ASN.1 `SET OF` backed by an array.
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>
33 inner
: ArrayVec
<T
, N
>,
36 impl<T
, const N
: usize> SetOf
<T
, N
>
40 /// Create a new [`SetOf`].
41 pub fn new() -> Self {
43 inner
: ArrayVec
::default(),
47 /// Add an element to this [`SetOf`].
49 /// Items MUST be added in lexicographical order according to the
50 /// [`DerOrd`] impl on `T`.
51 pub fn add(&mut self, new_elem
: T
) -> Result
<()> {
52 // Ensure set elements are lexicographically ordered
53 if let Some(last_elem
) = self.inner
.last() {
54 if new_elem
.der_cmp(last_elem
)?
!= Ordering
::Greater
{
55 return Err(ErrorKind
::SetOrdering
.into());
59 self.inner
.add(new_elem
)
62 /// Get the nth element from this [`SetOf`].
63 pub fn get(&self, index
: usize) -> Option
<&T
> {
67 /// Iterate over the elements of this [`SetOf`].
68 pub fn iter(&self) -> SetOfIter
<'_
, T
> {
70 inner
: self.inner
.iter(),
74 /// Is this [`SetOf`] empty?
75 pub fn is_empty(&self) -> bool
{
79 /// Number of elements in this [`SetOf`].
80 pub fn len(&self) -> usize {
85 impl<T
, const N
: usize> Default
for SetOf
<T
, N
>
89 fn default() -> Self {
94 impl<'a
, T
, const N
: usize> DecodeValue
<'a
> for SetOf
<T
, N
>
96 T
: Decode
<'a
> + DerOrd
,
98 fn decode_value
<R
: Reader
<'a
>>(reader
: &mut R
, header
: Header
) -> Result
<Self> {
99 reader
.read_nested(header
.length
, |reader
| {
100 let mut result
= Self::new();
102 while !reader
.is_finished() {
103 result
.inner
.add(T
::decode(reader
)?
)?
;
106 der_sort(result
.inner
.as_mut())?
;
107 validate(result
.inner
.as_ref())?
;
113 impl<'a
, T
, const N
: usize> EncodeValue
for SetOf
<T
, N
>
115 T
: 'a
+ Decode
<'a
> + Encode
+ DerOrd
,
117 fn value_len(&self) -> Result
<Length
> {
119 .fold(Ok(Length
::ZERO
), |len
, elem
| len
+ elem
.encoded_len()?
)
122 fn encode_value(&self, writer
: &mut dyn Writer
) -> Result
<()> {
123 for elem
in self.iter() {
124 elem
.encode(writer
)?
;
131 impl<'a
, T
, const N
: usize> FixedTag
for SetOf
<T
, N
>
133 T
: Decode
<'a
> + DerOrd
,
135 const TAG
: Tag
= Tag
::Set
;
138 impl<T
, const N
: usize> TryFrom
<[T
; N
]> for SetOf
<T
, N
>
144 fn try_from(mut arr
: [T
; N
]) -> Result
<SetOf
<T
, N
>> {
147 let mut result
= SetOf
::new();
157 impl<T
, const N
: usize> ValueOrd
for SetOf
<T
, N
>
161 fn value_cmp(&self, other
: &Self) -> Result
<Ordering
> {
162 iter_cmp(self.iter(), other
.iter())
166 /// Iterator over the elements of an [`SetOf`].
167 #[derive(Clone, Debug)]
168 pub struct SetOfIter
<'a
, T
> {
170 inner
: arrayvec
::Iter
<'a
, T
>,
173 impl<'a
, T
> Iterator
for SetOfIter
<'a
, T
> {
176 fn next(&mut self) -> Option
<&'a T
> {
181 impl<'a
, T
> ExactSizeIterator
for SetOfIter
<'a
, T
> {}
183 /// ASN.1 `SET OF` backed by a [`Vec`].
185 /// This type implements an append-only `SET OF` type which is heap-backed
186 /// and depends on `alloc` support.
187 #[cfg(feature = "alloc")]
188 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
189 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
190 pub struct SetOfVec
<T
>
197 #[cfg(feature = "alloc")]
198 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
199 impl<T
: DerOrd
> Default
for SetOfVec
<T
> {
200 fn default() -> Self {
202 inner
: Default
::default(),
207 #[cfg(feature = "alloc")]
208 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
213 /// Create a new [`SetOfVec`].
214 pub fn new() -> Self {
216 inner
: Vec
::default(),
220 /// Add an element to this [`SetOfVec`].
222 /// Items MUST be added in lexicographical order according to the
223 /// [`DerOrd`] impl on `T`.
224 pub fn add(&mut self, new_elem
: T
) -> Result
<()> {
225 // Ensure set elements are lexicographically ordered
226 if let Some(last_elem
) = self.inner
.last() {
227 if new_elem
.der_cmp(last_elem
)?
!= Ordering
::Greater
{
228 return Err(ErrorKind
::SetOrdering
.into());
232 self.inner
.push(new_elem
);
236 /// Borrow the elements of this [`SetOfVec`] as a slice.
237 pub fn as_slice(&self) -> &[T
] {
238 self.inner
.as_slice()
241 /// Get the nth element from this [`SetOfVec`].
242 pub fn get(&self, index
: usize) -> Option
<&T
> {
243 self.inner
.get(index
)
246 /// Convert this [`SetOfVec`] into the inner [`Vec`].
247 pub fn into_vec(self) -> Vec
<T
> {
251 /// Iterate over the elements of this [`SetOfVec`].
252 pub fn iter(&self) -> slice
::Iter
<'_
, T
> {
256 /// Is this [`SetOfVec`] empty?
257 pub fn is_empty(&self) -> bool
{
258 self.inner
.is_empty()
261 /// Number of elements in this [`SetOfVec`].
262 pub fn len(&self) -> usize {
267 #[cfg(feature = "alloc")]
268 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
269 impl<T
> AsRef
<[T
]> for SetOfVec
<T
>
273 fn as_ref(&self) -> &[T
] {
278 #[cfg(feature = "alloc")]
279 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
280 impl<'a
, T
> DecodeValue
<'a
> for SetOfVec
<T
>
282 T
: Decode
<'a
> + DerOrd
,
284 fn decode_value
<R
: Reader
<'a
>>(reader
: &mut R
, header
: Header
) -> Result
<Self> {
285 reader
.read_nested(header
.length
, |reader
| {
286 let mut inner
= Vec
::new();
288 while !reader
.is_finished() {
289 inner
.push(T
::decode(reader
)?
);
292 der_sort(inner
.as_mut())?
;
293 validate(inner
.as_ref())?
;
299 #[cfg(feature = "alloc")]
300 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
301 impl<'a
, T
> EncodeValue
for SetOfVec
<T
>
303 T
: 'a
+ Decode
<'a
> + Encode
+ DerOrd
,
305 fn value_len(&self) -> Result
<Length
> {
307 .fold(Ok(Length
::ZERO
), |len
, elem
| len
+ elem
.encoded_len()?
)
310 fn encode_value(&self, writer
: &mut dyn Writer
) -> Result
<()> {
311 for elem
in self.iter() {
312 elem
.encode(writer
)?
;
319 #[cfg(feature = "alloc")]
320 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
321 impl<T
> FixedTag
for SetOfVec
<T
>
325 const TAG
: Tag
= Tag
::Set
;
328 #[cfg(feature = "alloc")]
329 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
330 impl<T
> From
<SetOfVec
<T
>> for Vec
<T
>
334 fn from(set
: SetOfVec
<T
>) -> Vec
<T
> {
339 #[cfg(feature = "alloc")]
340 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
341 impl<T
> TryFrom
<Vec
<T
>> for SetOfVec
<T
>
347 fn try_from(mut vec
: Vec
<T
>) -> Result
<SetOfVec
<T
>> {
348 // TODO(tarcieri): use `[T]::sort_by` here?
349 der_sort(vec
.as_mut_slice())?
;
350 Ok(SetOfVec { inner: vec }
)
354 #[cfg(feature = "alloc")]
355 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
356 impl<T
, const N
: usize> TryFrom
<[T
; N
]> for SetOfVec
<T
>
362 fn try_from(arr
: [T
; N
]) -> Result
<SetOfVec
<T
>> {
363 Vec
::from(arr
).try_into()
367 #[cfg(feature = "alloc")]
368 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
369 impl<T
> ValueOrd
for SetOfVec
<T
>
373 fn value_cmp(&self, other
: &Self) -> Result
<Ordering
> {
374 iter_cmp(self.iter(), other
.iter())
378 /// Sort a mut slice according to its [`DerOrd`], returning any errors which
379 /// might occur during the comparison.
381 /// The algorithm is insertion sort, which should perform well when the input
382 /// is mostly sorted to begin with.
384 /// This function is used rather than Rust's built-in `[T]::sort_by` in order
385 /// to support heapless `no_std` targets as well as to enable bubbling up
387 #[allow(clippy::integer_arithmetic)]
388 fn der_sort
<T
: DerOrd
>(slice
: &mut [T
]) -> Result
<()> {
389 for i
in 0..slice
.len() {
392 while j
> 0 && slice
[j
- 1].der_cmp(&slice
[j
])?
== Ordering
::Greater
{
393 slice
.swap(j
- 1, j
);
401 /// Validate the elements of a `SET OF`, ensuring that they are all in order
402 /// and that there are no duplicates.
403 fn validate
<T
: DerOrd
>(slice
: &[T
]) -> Result
<()> {
404 if let Some(len
) = slice
.len().checked_sub(1) {
406 let j
= i
.checked_add(1).ok_or(ErrorKind
::Overflow
)?
;
408 match slice
.get(i
..=j
) {
410 if a
.der_cmp(b
)?
!= Ordering
::Less
{
411 return Err(ErrorKind
::SetOrdering
.into());
414 _
=> return Err(Tag
::Set
.value_error()),
422 #[cfg(all(test, feature = "alloc"))]
424 use super::{SetOf, SetOfVec}
;
428 fn setof_tryfrom_array() {
429 let arr
= [3u16, 2, 1, 65535, 0];
430 let set
= SetOf
::try_from(arr
).unwrap();
432 set
.iter().cloned().collect
::<Vec
<u16>>(),
438 fn setofvec_tryfrom_array() {
439 let arr
= [3u16, 2, 1, 65535, 0];
440 let set
= SetOfVec
::try_from(arr
).unwrap();
441 assert_eq
!(set
.as_ref(), &[0, 1, 2, 3, 65535]);
444 #[cfg(feature = "alloc")]
446 fn setofvec_tryfrom_vec() {
447 let vec
= vec
![3u16, 2, 1, 65535, 0];
448 let set
= SetOfVec
::try_from(vec
).unwrap();
449 assert_eq
!(set
.as_ref(), &[0, 1, 2, 3, 65535]);