1use crate::bit_string::BitString;
2use crate::date::{GeneralizedTime, UTCTime};
3use crate::restricted_string::{BmpString, Ia5String, NumericString, PrintableString, Utf8String};
4use crate::tag::Tag;
5use crate::Asn1Type;
6use oid::ObjectIdentifier;
7use serde::{de, ser, Deserialize, Serialize};
8use std::fmt;
9use std::ops::{Deref, DerefMut};
10
11macro_rules! asn1_wrapper {
14 (struct $wrapper_ty:ident ( $wrapped_ty:ident ), $tag:expr) => {
15 #[derive(Debug, PartialEq, Clone)]
17 pub struct $wrapper_ty(pub $wrapped_ty);
18
19 impls! { $wrapper_ty ( $wrapped_ty ), $tag }
20 };
21 (auto struct $wrapper_ty:ident ( $wrapped_ty:ident ), $tag:expr) => {
22 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
24 pub struct $wrapper_ty(pub $wrapped_ty);
25
26 impls! { $wrapper_ty ( $wrapped_ty ), $tag }
27 };
28 (special tag struct $wrapper_ty:ident < $generic:ident >, $tag:expr) => {
29 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
31 pub struct $wrapper_ty<$generic>(pub $generic);
32
33 impls! { $wrapper_ty < $generic >, $tag }
34 };
35 (auto collection struct $wrapper_ty:ident < T >, $tag:expr) => {
36 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
38 pub struct $wrapper_ty<T>(
39 #[serde(
40 serialize_with = "serialize_vec",
41 deserialize_with = "deserialize_vec",
42 bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>")
43 )]
44 pub Vec<T>,
45 );
46
47 impl<T> Default for $wrapper_ty<T> {
48 fn default() -> Self {
49 Self(Vec::new())
50 }
51 }
52
53 impls! { $wrapper_ty ( Vec < T > ), $tag }
54 };
55}
56
57macro_rules! impls {
58 ($wrapper_ty:ident ( $wrapped_ty:ident ), $tag:expr) => {
59 impl $crate::wrapper::Asn1Type for $wrapper_ty {
60 const TAG: Tag = $tag;
61 const NAME: &'static str = stringify!($wrapper_ty);
62 }
63
64 impl From<$wrapped_ty> for $wrapper_ty {
65 fn from(wrapped: $wrapped_ty) -> Self {
66 Self(wrapped)
67 }
68 }
69
70 impl From<$wrapper_ty> for $wrapped_ty {
71 fn from(wrapper: $wrapper_ty) -> $wrapped_ty {
72 wrapper.0
73 }
74 }
75
76 impl Deref for $wrapper_ty {
77 type Target = $wrapped_ty;
78
79 fn deref(&self) -> &Self::Target {
80 &self.0
81 }
82 }
83
84 impl DerefMut for $wrapper_ty {
85 fn deref_mut(&mut self) -> &mut Self::Target {
86 &mut self.0
87 }
88 }
89
90 impl PartialEq<$wrapped_ty> for $wrapper_ty {
91 fn eq(&self, other: &$wrapped_ty) -> bool {
92 self.0.eq(other)
93 }
94 }
95 };
96 ($wrapper_ty:ident < $generic:ident >, $tag:expr) => {
97 impl<$generic> $crate::wrapper::Asn1Type for $wrapper_ty<$generic> {
98 const TAG: Tag = $tag;
99 const NAME: &'static str = stringify!($wrapper_ty);
100 }
101
102 impl<$generic> Default for $wrapper_ty<$generic>
103 where
104 $generic: Default,
105 {
106 fn default() -> Self {
107 Self($generic::default())
108 }
109 }
110
111 impl<$generic> From<$generic> for $wrapper_ty<$generic> {
112 fn from(wrapped: $generic) -> Self {
113 Self(wrapped)
114 }
115 }
116
117 impl<$generic> Deref for $wrapper_ty<$generic> {
120 type Target = $generic;
121
122 fn deref(&self) -> &Self::Target {
123 &self.0
124 }
125 }
126
127 impl<$generic> DerefMut for $wrapper_ty<$generic> {
128 fn deref_mut(&mut self) -> &mut Self::Target {
129 &mut self.0
130 }
131 }
132
133 impl<$generic> PartialEq<$generic> for $wrapper_ty<$generic>
134 where
135 $generic: PartialEq,
136 {
137 fn eq(&self, other: &$generic) -> bool {
138 self.0.eq(other)
139 }
140 }
141 };
142 ($wrapper_ty:ident ( $wrapped_ty:ident < $generic:ident > ), $tag:expr) => {
143 impl<$generic> $crate::wrapper::Asn1Type for $wrapper_ty<$generic> {
144 const TAG: Tag = $tag;
145 const NAME: &'static str = stringify!($wrapper_ty);
146 }
147
148 impl<$generic> From<$wrapped_ty<$generic>> for $wrapper_ty<$generic> {
149 fn from(wrapped: $wrapped_ty<$generic>) -> Self {
150 Self(wrapped)
151 }
152 }
153
154 impl<$generic> From<$wrapper_ty<$generic>> for $wrapped_ty<$generic> {
155 fn from(wrapper: $wrapper_ty<$generic>) -> Self {
156 wrapper.0
157 }
158 }
159
160 impl<$generic> Deref for $wrapper_ty<$generic> {
161 type Target = $wrapped_ty<$generic>;
162
163 fn deref(&self) -> &Self::Target {
164 &self.0
165 }
166 }
167
168 impl<$generic> DerefMut for $wrapper_ty<$generic> {
169 fn deref_mut(&mut self) -> &mut Self::Target {
170 &mut self.0
171 }
172 }
173
174 impl<$generic> PartialEq<$wrapped_ty<$generic>> for $wrapper_ty<$generic>
175 where
176 $generic: PartialEq,
177 {
178 fn eq(&self, other: &$wrapped_ty<$generic>) -> bool {
179 self.0.eq(other)
180 }
181 }
182 };
183}
184
185macro_rules! define_special_tag {
186 ( $name:ident => $tag:expr ) => {
187 asn1_wrapper! { special tag struct $name<T>, $tag }
188 };
189 ( $( $name:ident => $tag:expr , )+ ) => {
190 $( define_special_tag! { $name => $tag } )+
191 };
192}
193
194asn1_wrapper! { auto struct BitStringAsn1(BitString), Tag::BIT_STRING }
195asn1_wrapper! { auto struct ObjectIdentifierAsn1(ObjectIdentifier), Tag::OID }
196asn1_wrapper! { auto struct Utf8StringAsn1(Utf8String), Tag::UTF8_STRING }
197asn1_wrapper! { auto struct NumericStringAsn1(NumericString), Tag::NUMERIC_STRING }
198asn1_wrapper! { auto struct PrintableStringAsn1(PrintableString), Tag::PRINTABLE_STRING }
199asn1_wrapper! { auto struct Ia5StringAsn1(Ia5String), Tag::IA5_STRING }
200asn1_wrapper! { auto struct BmpStringAsn1(BmpString), Tag::BMP_STRING }
201asn1_wrapper! { auto struct UtcTimeAsn1(UTCTime), Tag::UTC_TIME }
202asn1_wrapper! { auto struct GeneralizedTimeAsn1(GeneralizedTime), Tag::GENERALIZED_TIME }
203asn1_wrapper! { auto struct GeneralStringAsn1(Ia5String), Tag::GENERAL_STRING }
209
210#[deprecated = "Use BmpStringAsn1 instead"]
211pub use BmpStringAsn1 as BMPStringAsn1;
212#[deprecated = "Use Ia5StringAsn1 instead"]
213pub use Ia5StringAsn1 as IA5StringAsn1;
214#[deprecated = "Use UtcTimeAsn1 instead"]
215pub use UtcTimeAsn1 as UTCTimeAsn1;
216
217asn1_wrapper! { auto collection struct Asn1SequenceOf<T>, Tag::SEQUENCE }
218asn1_wrapper! { auto collection struct Asn1SetOf<T>, Tag::SET }
219
220define_special_tag! {
221 ExplicitContextTag0 => Tag::context_specific_constructed(0),
222 ExplicitContextTag1 => Tag::context_specific_constructed(1),
223 ExplicitContextTag2 => Tag::context_specific_constructed(2),
224 ExplicitContextTag3 => Tag::context_specific_constructed(3),
225 ExplicitContextTag4 => Tag::context_specific_constructed(4),
226 ExplicitContextTag5 => Tag::context_specific_constructed(5),
227 ExplicitContextTag6 => Tag::context_specific_constructed(6),
228 ExplicitContextTag7 => Tag::context_specific_constructed(7),
229 ExplicitContextTag8 => Tag::context_specific_constructed(8),
230 ExplicitContextTag9 => Tag::context_specific_constructed(9),
231 ExplicitContextTag10 => Tag::context_specific_constructed(10),
232 ExplicitContextTag11 => Tag::context_specific_constructed(11),
233 ExplicitContextTag12 => Tag::context_specific_constructed(12),
234 ExplicitContextTag13 => Tag::context_specific_constructed(13),
235 ExplicitContextTag14 => Tag::context_specific_constructed(14),
236 ExplicitContextTag15 => Tag::context_specific_constructed(15),
237 ImplicitContextTag0 => Tag::context_specific_primitive(0),
238 ImplicitContextTag1 => Tag::context_specific_primitive(1),
239 ImplicitContextTag2 => Tag::context_specific_primitive(2),
240 ImplicitContextTag3 => Tag::context_specific_primitive(3),
241 ImplicitContextTag4 => Tag::context_specific_primitive(4),
242 ImplicitContextTag5 => Tag::context_specific_primitive(5),
243 ImplicitContextTag6 => Tag::context_specific_primitive(6),
244 ImplicitContextTag7 => Tag::context_specific_primitive(7),
245 ImplicitContextTag8 => Tag::context_specific_primitive(8),
246 ImplicitContextTag9 => Tag::context_specific_primitive(9),
247 ImplicitContextTag10 => Tag::context_specific_primitive(10),
248 ImplicitContextTag11 => Tag::context_specific_primitive(11),
249 ImplicitContextTag12 => Tag::context_specific_primitive(12),
250 ImplicitContextTag13 => Tag::context_specific_primitive(13),
251 ImplicitContextTag14 => Tag::context_specific_primitive(14),
252 ImplicitContextTag15 => Tag::context_specific_primitive(15),
253}
254
255#[allow(clippy::derivable_impls)]
256impl Default for BitStringAsn1 {
257 fn default() -> Self {
258 BitStringAsn1(BitString::default())
259 }
260}
261
262impl Default for Ia5StringAsn1 {
263 fn default() -> Self {
264 Ia5StringAsn1::from(Ia5String::default())
265 }
266}
267
268impl Default for BmpStringAsn1 {
269 fn default() -> Self {
270 BmpStringAsn1::from(BmpString::default())
271 }
272}
273
274fn serialize_vec<S, T>(elems: &[T], serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
275where
276 S: ser::Serializer,
277 T: Serialize,
278{
279 use serde::ser::SerializeSeq;
280
281 let mut seq = serializer.serialize_seq(Some(elems.len()))?;
282 for e in elems {
283 seq.serialize_element(e)?;
284 }
285 seq.end()
286}
287
288fn deserialize_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
289where
290 D: de::Deserializer<'de>,
291 T: Deserialize<'de>,
292{
293 struct Visitor<T>(std::marker::PhantomData<T>);
294
295 impl<'de, T> de::Visitor<'de> for Visitor<T>
296 where
297 T: Deserialize<'de>,
298 {
299 type Value = Vec<T>;
300
301 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
302 formatter.write_str("a valid sequence of T")
303 }
304
305 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
306 where
307 A: de::SeqAccess<'de>,
308 {
309 let mut vec = Vec::new();
310 while let Some(e) = seq.next_element()? {
311 vec.push(e);
312 }
313 Ok(vec)
314 }
315 }
316
317 deserializer.deserialize_seq(Visitor(std::marker::PhantomData))
318}
319
320#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Hash, Clone, Default)]
322pub struct OctetStringAsn1(#[serde(with = "serde_bytes")] pub Vec<u8>);
323
324type VecU8 = Vec<u8>;
325impls! { OctetStringAsn1(VecU8), Tag::OCTET_STRING }
326
327impl fmt::Debug for OctetStringAsn1 {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 write!(f, "OctetString(0x")?;
330 self.0.iter().try_for_each(|byte| write!(f, "{byte:02X}"))?;
331 write!(f, ")")?;
332
333 Ok(())
334 }
335}
336
337#[derive(Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Hash, Clone)]
344pub struct IntegerAsn1(#[serde(with = "serde_bytes")] pub Vec<u8>);
345
346impls! { IntegerAsn1(VecU8), Tag::INTEGER }
347
348fn minimal_encode_start(bytes: &[u8]) -> usize {
350 let mut start = 0;
351 while start + 1 < bytes.len() {
352 if bytes[start] == 0 && (bytes[start + 1] & 0x80) == 0
353 || bytes[start] == 0xFF && (bytes[start + 1] & 0x80) == 0x80
354 {
355 start += 1;
356 } else {
357 break;
358 }
359 }
360 start
361}
362
363impl IntegerAsn1 {
364 pub fn is_positive(&self) -> bool {
365 if self.0.len() > 1 && self.0[0] == 0x00 || self.0.is_empty() {
366 true
367 } else {
368 self.0[0] & 0x80 == 0
369 }
370 }
371
372 pub fn is_negative(&self) -> bool {
373 if self.0.len() > 1 && self.0[0] == 0x00 {
374 false
375 } else if self.0.is_empty() {
376 true
377 } else {
378 self.0[0] & 0x80 != 0
379 }
380 }
381
382 pub fn as_unsigned_bytes_be(&self) -> &[u8] {
383 if self.0.len() > 1 {
384 if self.0[0] == 0x00 {
385 &self.0[1..]
386 } else {
387 &self.0
388 }
389 } else if self.0.is_empty() {
390 &[0]
391 } else {
392 &self.0
393 }
394 }
395
396 pub fn as_signed_bytes_be(&self) -> &[u8] {
397 if self.0.is_empty() {
398 &[0]
399 } else {
400 &self.0
401 }
402 }
403
404 pub fn from_bytes_be_signed(bytes: Vec<u8>) -> Self {
405 let start = minimal_encode_start(&bytes);
406 if start == 0 {
407 Self(bytes)
408 } else {
409 Self(bytes[start..].to_vec())
410 }
411 }
412
413 pub fn from_bytes_be_unsigned(mut bytes: Vec<u8>) -> Self {
420 if !bytes.is_empty() && bytes[0] & 0x80 == 0x80 {
421 bytes.insert(0, 0x00);
422 }
423 let start = minimal_encode_start(&bytes);
424 if start == 0 {
425 Self(bytes)
426 } else {
427 Self(bytes[start..].to_vec())
428 }
429 }
430}
431
432#[cfg(feature = "zeroize")]
433impl zeroize::Zeroize for IntegerAsn1 {
434 fn zeroize(&mut self) {
435 self.0.zeroize();
436 }
437}
438
439impl fmt::Debug for IntegerAsn1 {
440 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
441 write!(f, "Integer(0x")?;
442 self.0.iter().try_for_each(|byte| write!(f, "{byte:02X}"))?;
443 write!(f, ")")?;
444
445 Ok(())
446 }
447}
448
449#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Hash, Clone, Default)]
472pub struct HeaderOnly<T: Asn1Type>(
473 #[serde(
474 serialize_with = "serialize_header_only",
475 deserialize_with = "deserialize_header_only",
476 bound(serialize = "T: Asn1Type", deserialize = "T: Asn1Type")
477 )]
478 pub std::marker::PhantomData<T>,
479);
480
481impl<T: Asn1Type> Asn1Type for HeaderOnly<T> {
482 const TAG: Tag = T::TAG;
483 const NAME: &'static str = "HeaderOnly";
484}
485
486#[allow(clippy::trivially_copy_pass_by_ref)]
487fn serialize_header_only<S, Phantom>(
488 _: &std::marker::PhantomData<Phantom>,
489 serializer: S,
490) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
491where
492 S: ser::Serializer,
493 Phantom: Asn1Type,
494{
495 serializer.serialize_bytes(&[Phantom::TAG.inner(), 0x00][..])
496}
497
498fn deserialize_header_only<'de, D, Phantom>(deserializer: D) -> Result<std::marker::PhantomData<Phantom>, D::Error>
499where
500 D: de::Deserializer<'de>,
501 Phantom: Asn1Type,
502{
503 struct Visitor<T>(std::marker::PhantomData<T>);
504
505 impl<'de, T> de::Visitor<'de> for Visitor<T>
506 where
507 T: Asn1Type,
508 {
509 type Value = std::marker::PhantomData<T>;
510
511 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
512 formatter.write_str("a valid header for empty payload")
513 }
514
515 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
516 where
517 E: de::Error,
518 {
519 if v.len() != 2 {
520 return Err(E::invalid_value(
521 de::Unexpected::Other("invalid ASN.1 header length"),
522 &"a valid buffer representing an ASN.1 header with empty payload (two bytes)",
523 ));
524 }
525
526 if v[0] != T::TAG.inner() {
527 return Err(E::invalid_value(
528 de::Unexpected::Other("invalid ASN.1 header: wrong tag"),
529 &"a valid buffer representing an empty ASN.1 header (two bytes) with the expected tag",
530 ));
531 }
532
533 if v[1] != 0 {
534 return Err(E::invalid_value(
535 de::Unexpected::Other("invalid ASN.1 header: bad payload length"),
536 &"a valid buffer representing an empty ASN.1 header (two bytes) with no payload",
537 ));
538 }
539
540 Ok(std::marker::PhantomData)
541 }
542 }
543
544 deserializer.deserialize_bytes(Visitor(std::marker::PhantomData))
545}
546
547#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Hash, Clone)]
595pub struct BitStringAsn1Container<Encapsulated>(pub Encapsulated);
596
597impls! { BitStringAsn1Container<Encapsulated>, Tag::BIT_STRING }
598
599#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Hash, Clone)]
647pub struct OctetStringAsn1Container<Encapsulated>(pub Encapsulated);
648
649impls! { OctetStringAsn1Container<Encapsulated>, Tag::OCTET_STRING }
650
651#[derive(Debug, PartialEq, Eq, PartialOrd, Hash, Clone)]
707pub struct Optional<T>(pub T);
708
709impl<T: Default> Default for Optional<T> {
710 fn default() -> Self {
711 Optional(T::default())
712 }
713}
714
715impl<T> Optional<T>
716where
717 T: Default + PartialEq,
718{
719 pub fn is_default(&self) -> bool {
720 self.0 == T::default()
721 }
722}
723
724impl<T> From<T> for Optional<T> {
725 fn from(wrapped: T) -> Self {
726 Self(wrapped)
727 }
728}
729
730impl<T> Deref for Optional<T> {
731 type Target = T;
732
733 fn deref(&self) -> &Self::Target {
734 &self.0
735 }
736}
737
738impl<T> DerefMut for Optional<T> {
739 fn deref_mut(&mut self) -> &mut Self::Target {
740 &mut self.0
741 }
742}
743
744impl<T> PartialEq<T> for Optional<T>
745where
746 T: PartialEq,
747{
748 fn eq(&self, other: &T) -> bool {
749 self.0.eq(other)
750 }
751}
752
753impl<T> Serialize for Optional<T>
754where
755 T: Serialize,
756{
757 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
758 where
759 S: ser::Serializer,
760 {
761 self.0.serialize(serializer)
762 }
763}
764
765impl<'de, T> Deserialize<'de> for Optional<T>
766where
767 T: Deserialize<'de> + Default,
768{
769 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
770 where
771 D: de::Deserializer<'de>,
772 {
773 struct Visitor<T>(std::marker::PhantomData<T>);
774
775 impl<'de, T> de::Visitor<'de> for Visitor<T>
776 where
777 T: Deserialize<'de>,
778 {
779 type Value = Optional<T>;
780
781 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
782 write!(formatter, "nothing or a valid DER-encoded T")
783 }
784
785 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
786 where
787 D: de::Deserializer<'de>,
788 {
789 T::deserialize(deserializer).map(Optional::from)
790 }
791 }
792
793 match deserializer.deserialize_newtype_struct("Optional", Visitor(std::marker::PhantomData)) {
794 Err(_) => Ok(Self(T::default())),
795 result => result,
796 }
797 }
798}
799
800#[cfg(test)]
801mod tests {
802 use super::*;
803
804 #[test]
805 fn integer_from_unsigned_bytes_be_no_panic() {
806 IntegerAsn1::from_bytes_be_unsigned(vec![]);
807 }
808
809 #[test]
810 fn minimal_encode_start_positive() {
811 assert_eq!(minimal_encode_start(b""), 0);
814 assert_eq!(minimal_encode_start(b"\x00"), 0);
815 assert_eq!(minimal_encode_start(b"\x00\x00"), 1);
816 assert_eq!(minimal_encode_start(b"\x00\x00\x00"), 2);
817 assert_eq!(minimal_encode_start(b"\x00\x00\x80"), 1);
818 }
819
820 #[test]
821 fn minimal_encode_start_negative() {
822 assert_eq!(minimal_encode_start(b"\xFF"), 0);
823 assert_eq!(minimal_encode_start(b"\xFF\x00"), 0);
824 assert_eq!(minimal_encode_start(b"\xFF\x80"), 1);
825 assert_eq!(minimal_encode_start(b"\xFF\xFF\x00"), 1);
826 assert_eq!(minimal_encode_start(b"\xFF\xFF\x80"), 2);
827 }
828}