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