1 use crate::{
2     bit_string::BitString,
3     date::{GeneralizedTime, UTCTime},
4     restricted_string::{IA5String, NumericString, PrintableString, Utf8String},
5     tag::Tag,
6     Asn1Type,
7 };
8 use oid::ObjectIdentifier;
9 use serde::{de, ser, Deserialize, Serialize};
10 use std::{
11     fmt,
12     ops::{Deref, DerefMut},
13 };
14 
15 /// Generate a thin ASN1 wrapper type with associated tag
16 /// and name for serialization and deserialization purpose.
17 macro_rules! asn1_wrapper {
18     (struct $wrapper_ty:ident ( $wrapped_ty:ident ), $tag:expr) => {
19         /// Wrapper type
20         #[derive(Debug, PartialEq, Clone)]
21         pub struct $wrapper_ty(pub $wrapped_ty);
22 
23         impls! { $wrapper_ty ( $wrapped_ty ), $tag }
24     };
25     (auto struct $wrapper_ty:ident ( $wrapped_ty:ident ), $tag:expr) => {
26         /// Wrapper type
27         #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
28         pub struct $wrapper_ty(pub $wrapped_ty);
29 
30         impls! { $wrapper_ty ( $wrapped_ty ), $tag }
31     };
32     (special tag struct $wrapper_ty:ident < $generic:ident >, $tag:expr) => {
33         /// Wrapper type for special tag
34         #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
35         pub struct $wrapper_ty<$generic>(pub $generic);
36 
37         impls! { $wrapper_ty < $generic >, $tag }
38     };
39     (auto collection struct $wrapper_ty:ident < T >, $tag:expr) => {
40         /// Asn1 wrapper around a collection of elements of the same type.
41         #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
42         pub struct $wrapper_ty<T>(
43             #[serde(
44                 serialize_with = "serialize_vec",
45                 deserialize_with = "deserialize_vec",
46                 bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>")
47             )]
48             pub Vec<T>,
49         );
50 
51         impls! { $wrapper_ty ( Vec < T > ), $tag }
52     };
53 }
54 
55 macro_rules! impls {
56     ($wrapper_ty:ident ( $wrapped_ty:ident ), $tag:expr) => {
57         impl $crate::wrapper::Asn1Type for $wrapper_ty {
58             const TAG: Tag = $tag;
59             const NAME: &'static str = stringify!($wrapper_ty);
60         }
61 
62         impl From<$wrapped_ty> for $wrapper_ty {
63             fn from(wrapped: $wrapped_ty) -> Self {
64                 Self(wrapped)
65             }
66         }
67 
68         impl Into<$wrapped_ty> for $wrapper_ty {
69             fn into(self) -> $wrapped_ty {
70                 self.0
71             }
72         }
73 
74         impl Deref for $wrapper_ty {
75             type Target = $wrapped_ty;
76 
77             fn deref(&self) -> &Self::Target {
78                 &self.0
79             }
80         }
81 
82         impl DerefMut for $wrapper_ty {
83             fn deref_mut(&mut self) -> &mut Self::Target {
84                 &mut self.0
85             }
86         }
87 
88         impl PartialEq<$wrapped_ty> for $wrapper_ty {
89             fn eq(&self, other: &$wrapped_ty) -> bool {
90                 self.0.eq(other)
91             }
92         }
93     };
94     ($wrapper_ty:ident < $generic:ident >, $tag:expr) => {
95         impl<$generic> $crate::wrapper::Asn1Type for $wrapper_ty<$generic> {
96             const TAG: Tag = $tag;
97             const NAME: &'static str = stringify!($wrapper_ty);
98         }
99 
100         impl<$generic> Default for $wrapper_ty<$generic>
101         where
102             $generic: Default,
103         {
104             fn default() -> Self {
105                 Self($generic::default())
106             }
107         }
108 
109         impl<$generic> From<$generic> for $wrapper_ty<$generic> {
110             fn from(wrapped: $generic) -> Self {
111                 Self(wrapped)
112             }
113         }
114 
115         //-- Into cannot be defined to convert into a generic type (E0119) --
116 
117         impl<$generic> Deref for $wrapper_ty<$generic> {
118             type Target = $generic;
119 
120             fn deref(&self) -> &Self::Target {
121                 &self.0
122             }
123         }
124 
125         impl<$generic> DerefMut for $wrapper_ty<$generic> {
126             fn deref_mut(&mut self) -> &mut Self::Target {
127                 &mut self.0
128             }
129         }
130 
131         impl<$generic> PartialEq<$generic> for $wrapper_ty<$generic>
132         where
133             $generic: PartialEq,
134         {
135             fn eq(&self, other: &$generic) -> bool {
136                 self.0.eq(other)
137             }
138         }
139     };
140     ($wrapper_ty:ident ( $wrapped_ty:ident < $generic:ident > ), $tag:expr) => {
141         impl<$generic> $crate::wrapper::Asn1Type for $wrapper_ty<$generic> {
142             const TAG: Tag = $tag;
143             const NAME: &'static str = stringify!($wrapper_ty);
144         }
145 
146         impl<$generic> From<$wrapped_ty<$generic>> for $wrapper_ty<$generic> {
147             fn from(wrapped: $wrapped_ty<$generic>) -> Self {
148                 Self(wrapped)
149             }
150         }
151 
152         impl<$generic> Into<$wrapped_ty<$generic>> for $wrapper_ty<$generic> {
153             fn into(self) -> $wrapped_ty<$generic> {
154                 self.0
155             }
156         }
157 
158         impl<$generic> Deref for $wrapper_ty<$generic> {
159             type Target = $wrapped_ty<$generic>;
160 
161             fn deref(&self) -> &Self::Target {
162                 &self.0
163             }
164         }
165 
166         impl<$generic> DerefMut for $wrapper_ty<$generic> {
167             fn deref_mut(&mut self) -> &mut Self::Target {
168                 &mut self.0
169             }
170         }
171 
172         impl<$generic> PartialEq<$wrapped_ty<$generic>> for $wrapper_ty<$generic>
173         where
174             $generic: PartialEq,
175         {
176             fn eq(&self, other: &$wrapped_ty<$generic>) -> bool {
177                 self.0.eq(other)
178             }
179         }
180     };
181 }
182 
183 macro_rules! define_special_tag {
184     ( $name:ident => $tag:expr ) => {
185         asn1_wrapper! { special tag struct $name<T>, $tag }
186     };
187     ( $( $name:ident => $tag:expr , )+ ) => {
188         $( define_special_tag! { $name => $tag } )+
189     };
190 }
191 
192 asn1_wrapper! { auto struct BitStringAsn1(BitString),               Tag::BIT_STRING }
193 asn1_wrapper! { auto struct ObjectIdentifierAsn1(ObjectIdentifier), Tag::OID }
194 asn1_wrapper! { auto struct Utf8StringAsn1(Utf8String),             Tag::UTF8_STRING }
195 asn1_wrapper! { auto struct NumericStringAsn1(NumericString),       Tag::NUMERIC_STRING }
196 asn1_wrapper! { auto struct PrintableStringAsn1(PrintableString),   Tag::PRINTABLE_STRING }
197 asn1_wrapper! { auto struct IA5StringAsn1(IA5String),               Tag::IA5_STRING }
198 asn1_wrapper! { auto struct UTCTimeAsn1(UTCTime),                   Tag::UTC_TIME }
199 asn1_wrapper! { auto struct GeneralizedTimeAsn1(GeneralizedTime),   Tag::GENERALIZED_TIME }
200 
201 asn1_wrapper! { auto collection struct Asn1SequenceOf<T>, Tag::SEQUENCE }
202 asn1_wrapper! { auto collection struct Asn1SetOf<T>,      Tag::SET }
203 
204 define_special_tag! {
205     ApplicationTag0  => Tag::APP_0,
206     ApplicationTag1  => Tag::APP_1,
207     ApplicationTag2  => Tag::APP_2,
208     ApplicationTag3  => Tag::APP_3,
209     ApplicationTag4  => Tag::APP_4,
210     ApplicationTag5  => Tag::APP_5,
211     ApplicationTag6  => Tag::APP_6,
212     ApplicationTag7  => Tag::APP_7,
213     ApplicationTag8  => Tag::APP_8,
214     ApplicationTag9  => Tag::APP_9,
215     ApplicationTag10 => Tag::APP_10,
216     ApplicationTag11 => Tag::APP_11,
217     ApplicationTag12 => Tag::APP_12,
218     ApplicationTag13 => Tag::APP_13,
219     ApplicationTag14 => Tag::APP_14,
220     ApplicationTag15 => Tag::APP_15,
221     ContextTag0      => Tag::CTX_0,
222     ContextTag1      => Tag::CTX_1,
223     ContextTag2      => Tag::CTX_2,
224     ContextTag3      => Tag::CTX_3,
225     ContextTag4      => Tag::CTX_4,
226     ContextTag5      => Tag::CTX_5,
227     ContextTag6      => Tag::CTX_6,
228     ContextTag7      => Tag::CTX_7,
229     ContextTag8      => Tag::CTX_8,
230     ContextTag9      => Tag::CTX_9,
231     ContextTag10     => Tag::CTX_10,
232     ContextTag11     => Tag::CTX_11,
233     ContextTag12     => Tag::CTX_12,
234     ContextTag13     => Tag::CTX_13,
235     ContextTag14     => Tag::CTX_14,
236     ContextTag15     => Tag::CTX_15,
237 }
238 
serialize_vec<S, T>(elems: &[T], serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer, T: Serialize,239 fn serialize_vec<S, T>(elems: &[T], serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
240 where
241     S: ser::Serializer,
242     T: Serialize,
243 {
244     use serde::ser::SerializeSeq;
245 
246     let mut seq = serializer.serialize_seq(Some(elems.len()))?;
247     for e in elems {
248         seq.serialize_element(e)?;
249     }
250     seq.end()
251 }
252 
deserialize_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error> where D: de::Deserializer<'de>, T: Deserialize<'de>,253 fn deserialize_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
254 where
255     D: de::Deserializer<'de>,
256     T: Deserialize<'de>,
257 {
258     struct Visitor<T>(std::marker::PhantomData<T>);
259 
260     impl<'de, T> de::Visitor<'de> for Visitor<T>
261     where
262         T: Deserialize<'de>,
263     {
264         type Value = Vec<T>;
265 
266         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
267             formatter.write_str("a valid sequence of T")
268         }
269 
270         fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
271         where
272             A: de::SeqAccess<'de>,
273         {
274             let mut vec = Vec::new();
275             while let Some(e) = seq.next_element()? {
276                 vec.push(e);
277             }
278             Ok(vec)
279         }
280     }
281 
282     deserializer.deserialize_seq(Visitor(std::marker::PhantomData))
283 }
284 
285 /// A Vec<u8> wrapper for Asn1 encoding as OctetString.
286 #[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Hash, Clone)]
287 pub struct OctetStringAsn1(#[serde(with = "serde_bytes")] pub Vec<u8>);
288 
289 type VecU8 = Vec<u8>;
290 impls! { OctetStringAsn1(VecU8), Tag::OCTET_STRING }
291 
292 /// A BigInt wrapper for Asn1 encoding.
293 ///
294 /// Simply use primitive integer types if you don't need big integer.
295 ///
296 /// For underlying implementation,
297 /// see this [Microsoft's documentation](https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer).
298 #[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Hash, Clone)]
299 pub struct IntegerAsn1(#[serde(with = "serde_bytes")] pub Vec<u8>);
300 
301 impls! { IntegerAsn1(VecU8), Tag::INTEGER }
302 
303 impl IntegerAsn1 {
is_positive(&self) -> bool304     pub fn is_positive(&self) -> bool {
305         if self.0.len() > 1 && self.0[0] == 0x00 || self.0.is_empty() {
306             true
307         } else {
308             self.0[0] & 0x80 == 0
309         }
310     }
311 
is_negative(&self) -> bool312     pub fn is_negative(&self) -> bool {
313         if self.0.len() > 1 && self.0[0] == 0x00 {
314             false
315         } else if self.0.is_empty() {
316             true
317         } else {
318             self.0[0] & 0x80 != 0
319         }
320     }
321 
as_unsigned_bytes_be(&self) -> &[u8]322     pub fn as_unsigned_bytes_be(&self) -> &[u8] {
323         if self.0.len() > 1 {
324             if self.0[0] == 0x00 {
325                 &self.0[1..]
326             } else {
327                 &self.0
328             }
329         } else if self.0.is_empty() {
330             &[0]
331         } else {
332             &self.0
333         }
334     }
335 
as_signed_bytes_be(&self) -> &[u8]336     pub fn as_signed_bytes_be(&self) -> &[u8] {
337         if self.0.is_empty() {
338             &[0]
339         } else {
340             &self.0
341         }
342     }
343 
from_bytes_be_signed(bytes: Vec<u8>) -> Self344     pub fn from_bytes_be_signed(bytes: Vec<u8>) -> Self {
345         Self(bytes)
346     }
347 
348     /// Build an ASN.1 Integer from unsigned big endian bytes.
349     ///
350     /// If high order bit is set to 1, this shift all elements to the right
351     /// and add a leading 0x00 byte indicating the number is positive.
352     /// Prefer `from_signed_bytes_be` if you can build a signed bytes string without
353     /// overhead on you side.
from_bytes_be_unsigned(mut bytes: Vec<u8>) -> Self354     pub fn from_bytes_be_unsigned(mut bytes: Vec<u8>) -> Self {
355         if !bytes.is_empty() && bytes[0] & 0x80 == 0x80 {
356             bytes.insert(0, 0x00);
357         }
358         Self(bytes)
359     }
360 }
361 
362 /// A wrapper encoding/decoding only the header of the provided Asn1Wrapper with a length of 0.
363 ///
364 /// Examples:
365 /// ```
366 /// use picky_asn1::wrapper::{ApplicationTag0, HeaderOnly};
367 /// use serde::{Serialize, Deserialize};
368 ///
369 /// let tag_only = HeaderOnly::<ApplicationTag0<()>>::default();
370 /// let buffer = [0xA0, 0x00];
371 ///
372 /// let encoded = picky_asn1_der::to_vec(&tag_only).expect("couldn't serialize");
373 /// assert_eq!(
374 ///     encoded,
375 ///     buffer,
376 /// );
377 ///
378 /// let decoded: HeaderOnly<ApplicationTag0<()>> = picky_asn1_der::from_bytes(&buffer).expect("couldn't deserialize");
379 /// assert_eq!(
380 ///     decoded,
381 ///     tag_only,
382 /// );
383 /// ```
384 #[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Hash, Clone, Default)]
385 pub struct HeaderOnly<T: Asn1Type>(
386     #[serde(
387         serialize_with = "serialize_header_only",
388         deserialize_with = "deserialize_header_only",
389         bound(serialize = "T: Asn1Type", deserialize = "T: Asn1Type")
390     )]
391     pub std::marker::PhantomData<T>,
392 );
393 
394 impl<T: Asn1Type> Asn1Type for HeaderOnly<T> {
395     const TAG: Tag = T::TAG;
396     const NAME: &'static str = "HeaderOnly";
397 }
398 
399 #[allow(clippy::trivially_copy_pass_by_ref)]
serialize_header_only<S, Phantom>( _: &std::marker::PhantomData<Phantom>, serializer: S, ) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer, Phantom: Asn1Type,400 fn serialize_header_only<S, Phantom>(
401     _: &std::marker::PhantomData<Phantom>,
402     serializer: S,
403 ) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
404 where
405     S: ser::Serializer,
406     Phantom: Asn1Type,
407 {
408     serializer.serialize_bytes(&[Phantom::TAG.number(), 0x00][..])
409 }
410 
deserialize_header_only<'de, D, Phantom>(deserializer: D) -> Result<std::marker::PhantomData<Phantom>, D::Error> where D: de::Deserializer<'de>, Phantom: Asn1Type,411 fn deserialize_header_only<'de, D, Phantom>(deserializer: D) -> Result<std::marker::PhantomData<Phantom>, D::Error>
412 where
413     D: de::Deserializer<'de>,
414     Phantom: Asn1Type,
415 {
416     struct Visitor<T>(std::marker::PhantomData<T>);
417 
418     impl<'de, T> de::Visitor<'de> for Visitor<T>
419     where
420         T: Asn1Type,
421     {
422         type Value = std::marker::PhantomData<T>;
423 
424         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
425             formatter.write_str("a valid header for empty payload")
426         }
427 
428         fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
429         where
430             E: de::Error,
431         {
432             if v.len() != 2 {
433                 return Err(E::invalid_value(
434                     de::Unexpected::Other("invalid ASN.1 header length"),
435                     &"a valid buffer representing an  ASN.1 header with empty payload (two bytes)",
436                 ));
437             }
438 
439             if v[0] != T::TAG.number() {
440                 return Err(E::invalid_value(
441                     de::Unexpected::Other("invalid ASN.1 header: wrong tag"),
442                     &"a valid buffer representing an empty ASN.1 header (two bytes) with the expected tag",
443                 ));
444             }
445 
446             if v[1] != 0 {
447                 return Err(E::invalid_value(
448                     de::Unexpected::Other("invalid ASN.1 header: bad payload length"),
449                     &"a valid buffer representing an empty ASN.1 header (two bytes) with no payload",
450                 ));
451             }
452 
453             Ok(std::marker::PhantomData)
454         }
455     }
456 
457     deserializer.deserialize_bytes(Visitor(std::marker::PhantomData))
458 }
459 
460 /// A BitString encapsulating things.
461 ///
462 /// Same as `OctetStringAsn1Container` but using a BitString instead.
463 ///
464 /// Useful to perform a full serialization / deserialization in one pass
465 /// instead of using `BitStringAsn1` manually.
466 ///
467 /// Examples
468 /// ```
469 /// use picky_asn1::wrapper::BitStringAsn1Container;
470 /// use serde::{Serialize, Deserialize};
471 ///
472 /// #[derive(Serialize, Deserialize, Debug, PartialEq)]
473 /// struct MyType {
474 ///     a: u32,
475 ///     b: u16,
476 ///     c: u16,
477 /// }
478 ///
479 /// type MyTypeEncapsulated = BitStringAsn1Container<MyType>;
480 ///
481 /// let encapsulated: MyTypeEncapsulated = MyType {
482 ///     a: 83910,
483 ///     b: 3839,
484 ///     c: 4023,
485 /// }.into();
486 ///
487 /// let buffer = [
488 ///     0x03, 0x10, 0x00, // bit string part
489 ///     0x30, 0x0d, // sequence
490 ///     0x02, 0x03, 0x01, 0x47, 0xc6, // integer a
491 ///     0x02, 0x02, 0x0e, 0xff, // integer b
492 ///     0x02, 0x02, 0x0f, 0xb7, // integer c
493 /// ];
494 ///
495 /// let encoded = picky_asn1_der::to_vec(&encapsulated).expect("couldn't serialize");
496 /// assert_eq!(
497 ///     encoded,
498 ///     buffer,
499 /// );
500 ///
501 /// let decoded: MyTypeEncapsulated = picky_asn1_der::from_bytes(&buffer).expect("couldn't deserialize");
502 /// assert_eq!(
503 ///     decoded,
504 ///     encapsulated,
505 /// );
506 /// ```
507 #[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Hash, Clone)]
508 pub struct BitStringAsn1Container<Encapsulated>(pub Encapsulated);
509 
510 impls! { BitStringAsn1Container<Encapsulated>, Tag::BIT_STRING }
511 
512 /// An OctetString encapsulating things.
513 ///
514 /// Same as `BitStringAsn1Container` but using an OctetString instead.
515 ///
516 /// Useful to perform a full serialization / deserialization in one pass
517 /// instead of using `OctetStringAsn1` manually.
518 ///
519 /// Examples
520 /// ```
521 /// use picky_asn1::wrapper::OctetStringAsn1Container;
522 /// use serde::{Serialize, Deserialize};
523 ///
524 /// #[derive(Serialize, Deserialize, Debug, PartialEq)]
525 /// struct MyType {
526 ///     a: u32,
527 ///     b: u16,
528 ///     c: u16,
529 /// }
530 ///
531 /// type MyTypeEncapsulated = OctetStringAsn1Container<MyType>;
532 ///
533 /// let encapsulated: MyTypeEncapsulated = MyType {
534 ///     a: 83910,
535 ///     b: 3839,
536 ///     c: 4023,
537 /// }.into();
538 ///
539 /// let buffer = [
540 ///     0x04, 0x0F, // octet string part
541 ///     0x30, 0x0d, // sequence
542 ///     0x02, 0x03, 0x01, 0x47, 0xc6, // integer a
543 ///     0x02, 0x02, 0x0e, 0xff, // integer b
544 ///     0x02, 0x02, 0x0f, 0xb7, // integer c
545 /// ];
546 ///
547 /// let encoded = picky_asn1_der::to_vec(&encapsulated).expect("couldn't serialize");
548 /// assert_eq!(
549 ///     encoded,
550 ///     buffer,
551 /// );
552 ///
553 /// let decoded: MyTypeEncapsulated = picky_asn1_der::from_bytes(&buffer).expect("couldn't deserialize");
554 /// assert_eq!(
555 ///     decoded,
556 ///     encapsulated,
557 /// );
558 /// ```
559 #[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Hash, Clone)]
560 pub struct OctetStringAsn1Container<Encapsulated>(pub Encapsulated);
561 
562 impls! { OctetStringAsn1Container<Encapsulated>, Tag::OCTET_STRING }
563 
564 /// Wrapper for ASN.1 implicits (optionals) fields
565 ///
566 /// Wrapped type has to implement the Default trait to be deserializable (on deserialization failure
567 /// a default value is returned).
568 ///
569 /// Examples:
570 /// ```
571 /// use picky_asn1::wrapper::{Implicit, ApplicationTag0};
572 /// use serde::{Serialize, Deserialize};
573 ///
574 /// #[derive(Serialize, Deserialize, Debug, PartialEq)]
575 /// struct MyWrapper(u8);
576 ///
577 /// impl Default for MyWrapper {
578 ///     fn default() -> Self {
579 ///         Self(10)
580 ///     }
581 /// }
582 ///
583 /// #[derive(Serialize, Deserialize, Debug, PartialEq)]
584 /// struct ComplexType {
585 ///     // skip if default to reduce encoded size
586 ///     #[serde(skip_serializing_if = "implicit_field_is_default")]
587 ///     optional_field: Implicit<MyWrapper>,
588 ///     // behind application tag 0 to distinguish from optional_field that is a ASN.1 integer too.
589 ///     explicit_field: ApplicationTag0<u8>,
590 /// }
591 ///
592 /// fn implicit_field_is_default(wrapper: &Implicit<MyWrapper>) -> bool {
593 ///     wrapper.0 == MyWrapper::default()
594 /// }
595 ///
596 /// let complex_type = ComplexType {
597 ///     optional_field: MyWrapper::default().into(),
598 ///     explicit_field: 5.into(),
599 /// };
600 ///
601 /// let buffer = [
602 ///     0x30, 0x05, // sequence
603 ///     // optional field isn't present
604 ///     0xA0, 0x03, 0x02, 0x01, 0x05, // explicit field
605 /// ];
606 ///
607 /// let encoded = picky_asn1_der::to_vec(&complex_type).expect("couldn't serialize");
608 /// assert_eq!(
609 ///     encoded,
610 ///     buffer,
611 /// );
612 ///
613 /// let decoded: ComplexType = picky_asn1_der::from_bytes(&buffer).expect("couldn't deserialize");
614 /// assert_eq!(
615 ///     decoded,
616 ///     complex_type,
617 /// );
618 /// ```
619 #[derive(Debug, PartialEq, PartialOrd, Hash, Clone)]
620 pub struct Implicit<T>(pub T);
621 
622 impl<T> From<T> for Implicit<T> {
from(wrapped: T) -> Self623     fn from(wrapped: T) -> Self {
624         Self(wrapped)
625     }
626 }
627 
628 impl<T> Deref for Implicit<T> {
629     type Target = T;
630 
deref(&self) -> &Self::Target631     fn deref(&self) -> &Self::Target {
632         &self.0
633     }
634 }
635 
636 impl<T> DerefMut for Implicit<T> {
deref_mut(&mut self) -> &mut Self::Target637     fn deref_mut(&mut self) -> &mut Self::Target {
638         &mut self.0
639     }
640 }
641 
642 impl<T> PartialEq<T> for Implicit<T>
643 where
644     T: PartialEq,
645 {
eq(&self, other: &T) -> bool646     fn eq(&self, other: &T) -> bool {
647         self.0.eq(other)
648     }
649 }
650 
651 impl<T> Serialize for Implicit<T>
652 where
653     T: Serialize,
654 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,655     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
656     where
657         S: ser::Serializer,
658     {
659         self.0.serialize(serializer)
660     }
661 }
662 
663 impl<'de, T> Deserialize<'de> for Implicit<T>
664 where
665     T: Deserialize<'de> + Default,
666 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,667     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
668     where
669         D: de::Deserializer<'de>,
670     {
671         struct Visitor<T>(std::marker::PhantomData<T>);
672 
673         impl<'de, T> de::Visitor<'de> for Visitor<T>
674         where
675             T: Deserialize<'de>,
676         {
677             type Value = Implicit<T>;
678 
679             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
680                 write!(formatter, "nothing or a valid DER-encoded T")
681             }
682 
683             fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
684             where
685                 D: de::Deserializer<'de>,
686             {
687                 T::deserialize(deserializer).map(Implicit::from)
688             }
689         }
690 
691         match deserializer.deserialize_newtype_struct("Implicit", Visitor(std::marker::PhantomData)) {
692             Err(_) => Ok(Self(T::default())),
693             result => result,
694         }
695     }
696 }
697 
698 #[cfg(test)]
699 mod tests {
700     use super::*;
701 
702     #[test]
integer_from_unsigned_bytes_be_no_panic()703     fn integer_from_unsigned_bytes_be_no_panic() {
704         IntegerAsn1::from_bytes_be_unsigned(vec![]);
705     }
706 }
707