rustls/msgs/
base.rs

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