Coverage Report

Created: 2026-01-30 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/src/msgs/base.rs
Line
Count
Source
1
use alloc::vec::Vec;
2
use core::fmt;
3
use core::marker::PhantomData;
4
5
use pki_types::CertificateDer;
6
use zeroize::Zeroize;
7
8
use crate::error::InvalidMessage;
9
use crate::msgs::codec;
10
use crate::msgs::codec::{Codec, Reader};
11
12
/// An externally length'd payload
13
#[derive(Clone, Eq, PartialEq)]
14
pub enum Payload<'a> {
15
    Borrowed(&'a [u8]),
16
    Owned(Vec<u8>),
17
}
18
19
impl<'a> Codec<'a> for Payload<'a> {
20
0
    fn encode(&self, bytes: &mut Vec<u8>) {
21
0
        bytes.extend_from_slice(self.bytes());
22
0
    }
23
24
0
    fn read(r: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
25
0
        Ok(Self::read(r))
26
0
    }
27
}
28
29
impl<'a> Payload<'a> {
30
0
    pub fn bytes(&self) -> &[u8] {
31
0
        match self {
32
0
            Self::Borrowed(bytes) => bytes,
33
0
            Self::Owned(bytes) => bytes,
34
        }
35
0
    }
36
37
0
    pub fn into_owned(self) -> Payload<'static> {
38
0
        Payload::Owned(self.into_vec())
39
0
    }
40
41
0
    pub fn into_vec(self) -> Vec<u8> {
42
0
        match self {
43
0
            Self::Borrowed(bytes) => bytes.to_vec(),
44
0
            Self::Owned(bytes) => bytes,
45
        }
46
0
    }
47
48
0
    pub fn read(r: &mut Reader<'a>) -> Self {
49
0
        Self::Borrowed(r.rest())
50
0
    }
51
}
52
53
impl Payload<'static> {
54
0
    pub fn new(bytes: impl Into<Vec<u8>>) -> Self {
55
0
        Self::Owned(bytes.into())
56
0
    }
Unexecuted instantiation: <rustls::msgs::base::Payload>::new::<alloc::vec::Vec<u8>>
Unexecuted instantiation: <rustls::msgs::base::Payload>::new::<&[u8]>
57
58
0
    pub fn empty() -> Self {
59
0
        Self::Borrowed(&[])
60
0
    }
61
}
62
63
impl<'a> Codec<'a> for CertificateDer<'a> {
64
0
    fn encode(&self, bytes: &mut Vec<u8>) {
65
0
        codec::u24(self.as_ref().len() as u32).encode(bytes);
66
0
        bytes.extend(self.as_ref());
67
0
    }
68
69
0
    fn read(r: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
70
0
        let len = codec::u24::read(r)?.0 as usize;
71
0
        let mut sub = r.sub(len)?;
72
0
        let body = sub.rest();
73
0
        Ok(Self::from(body))
74
0
    }
75
}
76
77
impl fmt::Debug for Payload<'_> {
78
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79
0
        hex(f, self.bytes())
80
0
    }
81
}
82
83
/// An arbitrary, unknown-content, u24-length-prefixed payload
84
#[derive(Clone, Eq, PartialEq)]
85
pub(crate) struct PayloadU24<'a>(pub(crate) Payload<'a>);
86
87
impl PayloadU24<'_> {
88
0
    pub(crate) fn into_owned(self) -> PayloadU24<'static> {
89
0
        PayloadU24(self.0.into_owned())
90
0
    }
91
}
92
93
impl<'a> Codec<'a> for PayloadU24<'a> {
94
0
    fn encode(&self, bytes: &mut Vec<u8>) {
95
0
        let inner = self.0.bytes();
96
0
        codec::u24(inner.len() as u32).encode(bytes);
97
0
        bytes.extend_from_slice(inner);
98
0
    }
99
100
0
    fn read(r: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
101
0
        let len = codec::u24::read(r)?.0 as usize;
102
0
        let mut sub = r.sub(len)?;
103
0
        Ok(Self(Payload::read(&mut sub)))
104
0
    }
105
}
106
107
impl fmt::Debug for PayloadU24<'_> {
108
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109
0
        self.0.fmt(f)
110
0
    }
111
}
112
113
/// An arbitrary, unknown-content, u16-length-prefixed payload
114
///
115
/// The `C` type parameter controls whether decoded values may
116
/// be empty.
117
#[derive(Clone, Eq, PartialEq)]
118
pub struct PayloadU16<C: Cardinality = MaybeEmpty>(pub(crate) Vec<u8>, PhantomData<C>);
119
120
impl<C: Cardinality> PayloadU16<C> {
121
0
    pub fn new(bytes: Vec<u8>) -> Self {
122
0
        debug_assert!(bytes.len() >= C::MIN);
123
0
        Self(bytes, PhantomData)
124
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU16<rustls::msgs::base::NonEmpty>>::new
Unexecuted instantiation: <rustls::msgs::base::PayloadU16>::new
125
}
126
127
impl PayloadU16<MaybeEmpty> {
128
0
    pub(crate) fn empty() -> Self {
129
0
        Self::new(Vec::new())
130
0
    }
131
}
132
133
impl<C: Cardinality> Codec<'_> for PayloadU16<C> {
134
0
    fn encode(&self, bytes: &mut Vec<u8>) {
135
0
        debug_assert!(self.0.len() >= C::MIN);
136
0
        (self.0.len() as u16).encode(bytes);
137
0
        bytes.extend_from_slice(&self.0);
138
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU16<rustls::msgs::base::NonEmpty> as rustls::msgs::codec::Codec>::encode
Unexecuted instantiation: <rustls::msgs::base::PayloadU16 as rustls::msgs::codec::Codec>::encode
139
140
0
    fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
141
0
        let len = u16::read(r)? as usize;
142
0
        if len < C::MIN {
143
0
            return Err(InvalidMessage::IllegalEmptyValue);
144
0
        }
145
0
        let mut sub = r.sub(len)?;
146
0
        let body = sub.rest().to_vec();
147
0
        Ok(Self(body, PhantomData))
148
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU16<rustls::msgs::base::NonEmpty> as rustls::msgs::codec::Codec>::read
Unexecuted instantiation: <rustls::msgs::base::PayloadU16 as rustls::msgs::codec::Codec>::read
149
}
150
151
impl<C: Cardinality> fmt::Debug for PayloadU16<C> {
152
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153
0
        hex(f, &self.0)
154
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU16<rustls::msgs::base::NonEmpty> as core::fmt::Debug>::fmt
Unexecuted instantiation: <rustls::msgs::base::PayloadU16 as core::fmt::Debug>::fmt
155
}
156
157
/// An arbitrary, unknown-content, u8-length-prefixed payload
158
///
159
/// `C` controls the minimum length accepted when decoding.
160
#[derive(Clone, Eq, PartialEq)]
161
pub(crate) struct PayloadU8<C: Cardinality = MaybeEmpty>(pub(crate) Vec<u8>, PhantomData<C>);
162
163
impl<C: Cardinality> PayloadU8<C> {
164
0
    pub(crate) fn encode_slice(slice: &[u8], bytes: &mut Vec<u8>) {
165
0
        (slice.len() as u8).encode(bytes);
166
0
        bytes.extend_from_slice(slice);
167
0
    }
168
169
0
    pub(crate) fn new(bytes: Vec<u8>) -> Self {
170
0
        debug_assert!(bytes.len() >= C::MIN);
171
0
        Self(bytes, PhantomData)
172
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU8<rustls::msgs::base::NonEmpty>>::new
Unexecuted instantiation: <rustls::msgs::base::PayloadU8>::new
173
}
174
175
impl PayloadU8<MaybeEmpty> {
176
0
    pub(crate) fn empty() -> Self {
177
0
        Self(Vec::new(), PhantomData)
178
0
    }
179
}
180
181
impl<C: Cardinality> Codec<'_> for PayloadU8<C> {
182
0
    fn encode(&self, bytes: &mut Vec<u8>) {
183
0
        debug_assert!(self.0.len() >= C::MIN);
184
0
        (self.0.len() as u8).encode(bytes);
185
0
        bytes.extend_from_slice(&self.0);
186
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU8<rustls::msgs::base::NonEmpty> as rustls::msgs::codec::Codec>::encode
Unexecuted instantiation: <rustls::msgs::base::PayloadU8 as rustls::msgs::codec::Codec>::encode
187
188
0
    fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
189
0
        let len = u8::read(r)? as usize;
190
0
        if len < C::MIN {
191
0
            return Err(InvalidMessage::IllegalEmptyValue);
192
0
        }
193
0
        let mut sub = r.sub(len)?;
194
0
        let body = sub.rest().to_vec();
195
0
        Ok(Self(body, PhantomData))
196
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU8<rustls::msgs::base::NonEmpty> as rustls::msgs::codec::Codec>::read
Unexecuted instantiation: <rustls::msgs::base::PayloadU8 as rustls::msgs::codec::Codec>::read
197
}
198
199
impl<C: Cardinality> Zeroize for PayloadU8<C> {
200
0
    fn zeroize(&mut self) {
201
0
        self.0.zeroize();
202
0
    }
203
}
204
205
impl<C: Cardinality> fmt::Debug for PayloadU8<C> {
206
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207
0
        hex(f, &self.0)
208
0
    }
Unexecuted instantiation: <rustls::msgs::base::PayloadU8<rustls::msgs::base::NonEmpty> as core::fmt::Debug>::fmt
Unexecuted instantiation: <rustls::msgs::base::PayloadU8 as core::fmt::Debug>::fmt
209
}
210
211
pub trait Cardinality: Clone + Eq + PartialEq {
212
    const MIN: usize;
213
}
214
215
#[derive(Clone, Eq, PartialEq)]
216
pub struct MaybeEmpty;
217
218
impl Cardinality for MaybeEmpty {
219
    const MIN: usize = 0;
220
}
221
222
#[derive(Clone, Eq, PartialEq)]
223
pub struct NonEmpty;
224
225
impl Cardinality for NonEmpty {
226
    const MIN: usize = 1;
227
}
228
229
// Format an iterator of u8 into a hex string
230
0
pub(super) fn hex<'a>(
231
0
    f: &mut fmt::Formatter<'_>,
232
0
    payload: impl IntoIterator<Item = &'a u8>,
233
0
) -> fmt::Result {
234
0
    for b in payload {
235
0
        write!(f, "{b:02x}")?;
236
    }
237
0
    Ok(())
238
0
}
Unexecuted instantiation: rustls::msgs::base::hex::<&[u8; 32]>
Unexecuted instantiation: rustls::msgs::base::hex::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: rustls::msgs::base::hex::<&[u8]>