picky_asn1_der/lib.rs
1//! [](https://crates.io/crates/picky-asn1-der)
2//! [](https://docs.rs/picky-asn1-der)
3//! 
4//!
5//! # picky-asn1-der
6//!
7//! Portions of project [serde_asn1_der](https://github.com/KizzyCode/serde_asn1_der) are held by
8//! Keziah Biermann, 2019 as part of this project.
9//!
10//! This crate implements an ASN.1-DER subset for serde.
11//!
12//! The following types have built-in support:
13//! - `bool`: The ASN.1-BOOLEAN-type
14//! - `u8`, `u16`, `u32`, `u64`, `u128`, `usize`: The ASN.1-INTEGER-type
15//! - `()`: The ASN.1-NULL-type
16//! - `&[u8]`, `Vec<u8>`: The ASN.1-OctetString-type
17//! - `&str`, `String`: The ASN.1-UTF8String-type
18//!
19//! More advanced types are supported through wrappers:
20//! - Integer (as big integer)
21//! - Bit String
22//! - Object Identifier
23//! - Utf8 String
24//! - Numeric String
25//! - Printable String
26//! - IA5 String
27//! - Generalized Time
28//! - UTC Time
29//! - Application Tags from 0 to 15
30//! - Context Tags from 0 to 15
31//!
32//! Everything sequence-like combined out of this types is also supported out of the box.
33//!
34//! ```rust
35//! use serde::{Serialize, Deserialize};
36//!
37//! #[derive(Serialize, Deserialize)] // Now our struct supports all DER-conversion-traits
38//! struct Address {
39//! street: String,
40//! house_number: u128,
41//! postal_code: u128,
42//! state: String,
43//! country: String
44//! }
45//!
46//! #[derive(Serialize, Deserialize)] // Now our struct supports all DER-conversion-traits too
47//! struct Customer {
48//! name: String,
49//! e_mail_address: String,
50//! postal_address: Address
51//! }
52//! ```
53//!
54//!
55//! # Example
56//! ```rust
57//! use serde::{Serialize, Deserialize};
58//!
59//! #[derive(Serialize, Deserialize)]
60//! struct TestStruct {
61//! number: u8,
62//! #[serde(with = "serde_bytes")]
63//! vec: Vec<u8>,
64//! tuple: (usize, ())
65//! }
66//!
67//! let plain = TestStruct{ number: 7, vec: b"Testolope".to_vec(), tuple: (4, ()) };
68//! let serialized = picky_asn1_der::to_vec(&plain).unwrap();
69//! let deserialized: TestStruct = picky_asn1_der::from_bytes(&serialized).unwrap();
70//! ```
71
72#[macro_use]
73mod debug_log;
74
75pub mod application_tag;
76mod de;
77pub(crate) mod misc;
78mod raw_der;
79mod ser;
80
81pub use crate::de::{Deserializer, from_bytes, from_reader, from_reader_with_max_len};
82pub use crate::raw_der::Asn1RawDer;
83pub use crate::ser::{Serializer, to_byte_buf, to_bytes, to_vec, to_writer};
84
85use std::error::Error;
86use std::fmt::{self, Display, Formatter};
87use std::io;
88
89/// A `picky_asn1_der`-related error
90#[derive(Debug)]
91pub enum Asn1DerError {
92 /// The data is truncated
93 TruncatedData,
94
95 /// The data is invalid
96 InvalidData,
97
98 /// The value may be valid but is unsupported (e.g. an integer that is too large)
99 UnsupportedValue,
100
101 /// The data type is not supported by the (de-)serializer
102 UnsupportedType,
103
104 /// The provided sink is unable to accept all bytes
105 InvalidSink,
106
107 /// A custom message produced by `serde`
108 Message(String),
109
110 /// Some other underlying error (e.g. an IO error)
111 Other(Box<dyn Error + Send + Sync + 'static>),
112}
113
114impl Display for Asn1DerError {
115 fn fmt(&self, t: &mut Formatter) -> fmt::Result {
116 write!(t, "{self:?}")
117 }
118}
119
120impl Error for Asn1DerError {
121 fn source(&self) -> Option<&(dyn Error + 'static)> {
122 match self {
123 Asn1DerError::Other(source) => Some(source.as_ref()),
124 _ => None,
125 }
126 }
127}
128
129impl serde::de::Error for Asn1DerError {
130 fn custom<T: Display>(msg: T) -> Self {
131 Asn1DerError::Message(msg.to_string())
132 }
133}
134
135impl serde::ser::Error for Asn1DerError {
136 fn custom<T: Display>(msg: T) -> Self {
137 Asn1DerError::Message(msg.to_string())
138 }
139}
140
141impl From<io::Error> for Asn1DerError {
142 fn from(io_error: io::Error) -> Self {
143 match io_error.kind() {
144 io::ErrorKind::UnexpectedEof => Asn1DerError::TruncatedData,
145 io::ErrorKind::WriteZero => Asn1DerError::InvalidSink,
146 _ => Asn1DerError::Other(Box::new(io_error)),
147 }
148 }
149}
150
151pub type Result<T> = std::result::Result<T, Asn1DerError>;