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
//! Some traits to de-/encode DER objects via type-specific zero-copy views as well as direct
//! de-/encode implementations for some native Rust types

mod boolean;
mod integer;
mod null;
mod octet_string;
mod sequence;
mod utf8_string;

use crate::{ Asn1DerError, DerObject, Source, Sink, error::ErrorChain };
pub use crate::typed::{
	boolean::Boolean, integer::Integer, null::Null,
	octet_string::OctetString, sequence::Sequence, utf8_string::Utf8String
};
#[cfg(not(any(feature = "no_std", feature = "no_panic")))]
	pub use sequence::SequenceVec;


/// A trait for DER type views
pub trait DerTypeView<'a>: Sized {
	/// The tag for this type
	const TAG: u8;
	/// Provides raw access to the underlying `DerObject`
	fn object(&self) -> DerObject<'a>;
}


/// A trait for DER decodable types
pub trait DerDecodable<'a>: Sized {
	/// Loads `object` as `Self`
	fn load(object: DerObject<'a>) -> Result<Self, Asn1DerError>;
	/// Decodes an object as `Self`
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn decode(raw: &'a[u8]) -> Result<Self, Asn1DerError> {
		Self::decode_at(raw, 0)
	}
	/// Decodes an object as `Self`
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn decode_at(raw: &'a[u8], header_start: usize) -> Result<Self, Asn1DerError> {
		let object = DerObject::decode_at(raw, header_start)
			.propagate(e!("Failed to decode object"))?;
		Self::load(object).propagate(e!("Failed to load object"))
	}
	/// Reads an object from `source` by parsing the length field and copying the necessary bytes
	/// into `sink` and decoding it from `sink`
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn decode_from_source<A: Source, B: Sink + Into<&'a[u8]>>(source: &mut A, sink: B)
		-> Result<Self, Asn1DerError>
	{
		let object = DerObject::decode_from_source(source, sink)
			.propagate(e!("Failed to decode object"))?;
		Self::load(object).propagate(e!("Failed to load object"))
	}
}
impl<'a> DerDecodable<'a> for DerObject<'a> {
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn load(object: DerObject<'a>) -> Result<Self, Asn1DerError> {
		Ok(object)
	}
}


/// A trait for DER encodable types
pub trait DerEncodable: Sized {
	/// Encodes `self` into `sink`
	fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError>;
}
impl<'a> DerEncodable for DerObject<'a> {
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
		self.encode(sink).propagate(e!("Failed to encode object"))
	}
}
impl<T: DerEncodable> DerEncodable for &T {
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
		(*self).encode(sink)
	}
}
impl<T: DerEncodable> DerEncodable for &mut T {
	#[cfg_attr(feature = "no_panic", no_panic::no_panic)]
	fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
		(*self as &T).encode(sink)
	}
}