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