rocket/listener/connection.rs
1use std::io;
2use std::borrow::Cow;
3
4use tokio::io::{AsyncRead, AsyncWrite};
5use tokio_util::either::Either;
6
7use super::Endpoint;
8
9/// A collection of raw certificate data.
10#[derive(Clone)]
11pub struct Certificates<'r>(Cow<'r, [der::CertificateDer<'r>]>);
12
13pub trait Connection: AsyncRead + AsyncWrite + Send + Unpin {
14 fn endpoint(&self) -> io::Result<Endpoint>;
15
16 /// DER-encoded X.509 certificate chain presented by the client, if any.
17 ///
18 /// The certificate order must be as it appears in the TLS protocol: the
19 /// first certificate relates to the peer, the second certifies the first,
20 /// the third certifies the second, and so on.
21 ///
22 /// Defaults to an empty vector to indicate that no certificates were
23 /// presented.
24 fn certificates(&self) -> Option<Certificates<'_>> { None }
25}
26
27impl<A: Connection, B: Connection> Connection for Either<A, B> {
28 fn endpoint(&self) -> io::Result<Endpoint> {
29 match self {
30 Either::Left(c) => c.endpoint(),
31 Either::Right(c) => c.endpoint(),
32 }
33 }
34
35 fn certificates(&self) -> Option<Certificates<'_>> {
36 match self {
37 Either::Left(c) => c.certificates(),
38 Either::Right(c) => c.certificates(),
39 }
40 }
41}
42
43impl Certificates<'_> {
44 pub fn into_owned(self) -> Certificates<'static> {
45 let cow = self.0.iter()
46 .map(|der| der.clone().into_owned())
47 .collect::<Vec<_>>()
48 .into();
49
50 Certificates(cow)
51 }
52}
53
54#[cfg(feature = "mtls")]
55#[cfg_attr(nightly, doc(cfg(feature = "mtls")))]
56mod der {
57 use super::*;
58
59 pub use crate::mtls::CertificateDer;
60
61 impl<'r> Certificates<'r> {
62 pub(crate) fn inner(&self) -> &[CertificateDer<'r>] {
63 &self.0
64 }
65 }
66
67 impl<'r> From<&'r [CertificateDer<'r>]> for Certificates<'r> {
68 fn from(value: &'r [CertificateDer<'r>]) -> Self {
69 Certificates(value.into())
70 }
71 }
72
73 impl From<Vec<CertificateDer<'static>>> for Certificates<'static> {
74 fn from(value: Vec<CertificateDer<'static>>) -> Self {
75 Certificates(value.into())
76 }
77 }
78}
79
80#[cfg(not(feature = "mtls"))]
81mod der {
82 use std::marker::PhantomData;
83
84 /// A thin wrapper over raw, DER-encoded X.509 client certificate data.
85 #[derive(Clone)]
86 pub struct CertificateDer<'r>(PhantomData<&'r [u8]>);
87
88 impl CertificateDer<'_> {
89 pub fn into_owned(self) -> CertificateDer<'static> {
90 CertificateDer(PhantomData)
91 }
92 }
93}