Coverage Report

Created: 2025-07-18 06:08

/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
}