/rust/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.10/src/encode.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Trait definition for [`Encode`]. |
2 | | |
3 | | use crate::{Header, Length, Result, SliceWriter, Tagged, Writer}; |
4 | | use core::marker::PhantomData; |
5 | | |
6 | | #[cfg(feature = "alloc")] |
7 | | use {alloc::boxed::Box, alloc::vec::Vec}; |
8 | | |
9 | | #[cfg(feature = "pem")] |
10 | | use { |
11 | | crate::PemWriter, |
12 | | alloc::string::String, |
13 | | pem_rfc7468::{self as pem, LineEnding, PemLabel}, |
14 | | }; |
15 | | |
16 | | #[cfg(any(feature = "alloc", feature = "pem"))] |
17 | | use crate::ErrorKind; |
18 | | |
19 | | #[cfg(doc)] |
20 | | use crate::Tag; |
21 | | |
22 | | /// Encoding trait. |
23 | | pub trait Encode { |
24 | | /// Compute the length of this value in bytes when encoded as ASN.1 DER. |
25 | | fn encoded_len(&self) -> Result<Length>; |
26 | | |
27 | | /// Encode this value as ASN.1 DER using the provided [`Writer`]. |
28 | | fn encode(&self, encoder: &mut impl Writer) -> Result<()>; |
29 | | |
30 | | /// Encode this value to the provided byte slice, returning a sub-slice |
31 | | /// containing the encoded message. |
32 | 0 | fn encode_to_slice<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { |
33 | 0 | let mut writer = SliceWriter::new(buf); |
34 | 0 | self.encode(&mut writer)?; |
35 | 0 | writer.finish() |
36 | 0 | } Unexecuted instantiation: <td_shim::secure_boot::RsaPublicKeyDer as der::encode::Encode>::encode_to_slice Unexecuted instantiation: <_ as der::encode::Encode>::encode_to_slice |
37 | | |
38 | | /// Encode this message as ASN.1 DER, appending it to the provided |
39 | | /// byte vector. |
40 | | #[cfg(feature = "alloc")] |
41 | 0 | fn encode_to_vec(&self, buf: &mut Vec<u8>) -> Result<Length> { |
42 | 0 | let expected_len = usize::try_from(self.encoded_len()?)?; |
43 | 0 | let initial_len = buf.len(); |
44 | 0 | buf.resize(initial_len + expected_len, 0u8); |
45 | 0 |
|
46 | 0 | let buf_slice = &mut buf[initial_len..]; |
47 | 0 | let actual_len = self.encode_to_slice(buf_slice)?.len(); |
48 | 0 |
|
49 | 0 | if expected_len != actual_len { |
50 | | return Err(ErrorKind::Incomplete { |
51 | 0 | expected_len: expected_len.try_into()?, |
52 | 0 | actual_len: actual_len.try_into()?, |
53 | | } |
54 | 0 | .into()); |
55 | 0 | } |
56 | 0 |
|
57 | 0 | actual_len.try_into() |
58 | 0 | } |
59 | | |
60 | | /// Encode this type as DER, returning a byte vector. |
61 | | #[cfg(feature = "alloc")] |
62 | 0 | fn to_der(&self) -> Result<Vec<u8>> { |
63 | 0 | let mut buf = Vec::new(); |
64 | 0 | self.encode_to_vec(&mut buf)?; |
65 | 0 | Ok(buf) |
66 | 0 | } |
67 | | } |
68 | | |
69 | | impl<T> Encode for T |
70 | | where |
71 | | T: EncodeValue + Tagged, |
72 | | { |
73 | | /// Compute the length of this value in bytes when encoded as ASN.1 DER. |
74 | 0 | fn encoded_len(&self) -> Result<Length> { |
75 | 0 | self.value_len().and_then(|len| len.for_tlv()) Unexecuted instantiation: <der::asn1::integer::uint::UintRef as der::encode::Encode>::encoded_len::{closure#0} Unexecuted instantiation: <u8 as der::encode::Encode>::encoded_len::{closure#0} |
76 | 0 | } Unexecuted instantiation: <der::asn1::integer::uint::UintRef as der::encode::Encode>::encoded_len Unexecuted instantiation: <u8 as der::encode::Encode>::encoded_len |
77 | | |
78 | | /// Encode this value as ASN.1 DER using the provided [`Writer`]. |
79 | 0 | fn encode(&self, writer: &mut impl Writer) -> Result<()> { |
80 | 0 | self.header()?.encode(writer)?; |
81 | 0 | self.encode_value(writer) |
82 | 0 | } Unexecuted instantiation: <td_shim::secure_boot::RsaPublicKeyDer as der::encode::Encode>::encode::<der::writer::slice::SliceWriter> Unexecuted instantiation: <der::asn1::integer::uint::UintRef as der::encode::Encode>::encode::<der::writer::slice::SliceWriter> Unexecuted instantiation: <_ as der::encode::Encode>::encode::<_> |
83 | | } |
84 | | |
85 | | /// Dummy implementation for [`PhantomData`] which allows deriving |
86 | | /// implementations on structs with phantom fields. |
87 | | impl<T> Encode for PhantomData<T> |
88 | | where |
89 | | T: ?Sized, |
90 | | { |
91 | 0 | fn encoded_len(&self) -> Result<Length> { |
92 | 0 | Ok(Length::ZERO) |
93 | 0 | } |
94 | | |
95 | 0 | fn encode(&self, _writer: &mut impl Writer) -> Result<()> { |
96 | 0 | Ok(()) |
97 | 0 | } |
98 | | } |
99 | | |
100 | | /// PEM encoding trait. |
101 | | /// |
102 | | /// This trait is automatically impl'd for any type which impls both |
103 | | /// [`Encode`] and [`PemLabel`]. |
104 | | #[cfg(feature = "pem")] |
105 | | pub trait EncodePem: Encode + PemLabel { |
106 | | /// Try to encode this type as PEM. |
107 | | fn to_pem(&self, line_ending: LineEnding) -> Result<String>; |
108 | | } |
109 | | |
110 | | #[cfg(feature = "pem")] |
111 | | impl<T: Encode + PemLabel> EncodePem for T { |
112 | | fn to_pem(&self, line_ending: LineEnding) -> Result<String> { |
113 | | let der_len = usize::try_from(self.encoded_len()?)?; |
114 | | let pem_len = pem::encapsulated_len(Self::PEM_LABEL, line_ending, der_len)?; |
115 | | |
116 | | let mut buf = vec![0u8; pem_len]; |
117 | | let mut writer = PemWriter::new(Self::PEM_LABEL, line_ending, &mut buf)?; |
118 | | self.encode(&mut writer)?; |
119 | | |
120 | | let actual_len = writer.finish()?; |
121 | | buf.truncate(actual_len); |
122 | | Ok(String::from_utf8(buf)?) |
123 | | } |
124 | | } |
125 | | |
126 | | /// Encode the value part of a Tag-Length-Value encoded field, sans the [`Tag`] |
127 | | /// and [`Length`]. |
128 | | pub trait EncodeValue { |
129 | | /// Get the [`Header`] used to encode this value. |
130 | 0 | fn header(&self) -> Result<Header> |
131 | 0 | where |
132 | 0 | Self: Tagged, |
133 | 0 | { |
134 | 0 | Header::new(self.tag(), self.value_len()?) |
135 | 0 | } Unexecuted instantiation: <td_shim::secure_boot::RsaPublicKeyDer as der::encode::EncodeValue>::header Unexecuted instantiation: <der::asn1::integer::uint::UintRef as der::encode::EncodeValue>::header Unexecuted instantiation: <alloc::vec::Vec<u8> as der::encode::EncodeValue>::header Unexecuted instantiation: <u8 as der::encode::EncodeValue>::header |
136 | | |
137 | | /// Compute the length of this value (sans [`Tag`]+[`Length`] header) when |
138 | | /// encoded as ASN.1 DER. |
139 | | fn value_len(&self) -> Result<Length>; |
140 | | |
141 | | /// Encode value (sans [`Tag`]+[`Length`] header) as ASN.1 DER using the |
142 | | /// provided [`Writer`]. |
143 | | fn encode_value(&self, encoder: &mut impl Writer) -> Result<()>; |
144 | | } |
145 | | |
146 | | #[cfg(feature = "alloc")] |
147 | | impl<T> EncodeValue for Box<T> |
148 | | where |
149 | | T: EncodeValue, |
150 | | { |
151 | 0 | fn value_len(&self) -> Result<Length> { |
152 | 0 | T::value_len(self) |
153 | 0 | } |
154 | 0 | fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { |
155 | 0 | T::encode_value(self, writer) |
156 | 0 | } |
157 | | } |