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 fn server_name(&self) -> Option<&str> { None }
27}
28
29impl<A: Connection, B: Connection> Connection for Either<A, B> {
30 fn endpoint(&self) -> io::Result<Endpoint> {
31 match self {
32 Either::Left(c) => c.endpoint(),
33 Either::Right(c) => c.endpoint(),
34 }
35 }
36
37 fn certificates(&self) -> Option<Certificates<'_>> {
38 match self {
39 Either::Left(c) => c.certificates(),
40 Either::Right(c) => c.certificates(),
41 }
42 }
43}
44
45impl Certificates<'_> {
46 pub fn into_owned(self) -> Certificates<'static> {
47 let cow = self.0.iter()
48 .map(|der| der.clone().into_owned())
49 .collect::<Vec<_>>()
50 .into();
51
52 Certificates(cow)
53 }
54}
55
56#[cfg(feature = "mtls")]
57#[cfg_attr(nightly, doc(cfg(feature = "mtls")))]
58mod der {
59 use super::*;
60
61 pub use crate::mtls::CertificateDer;
62
63 impl<'r> Certificates<'r> {
64 pub(crate) fn inner(&self) -> &[CertificateDer<'r>] {
65 &self.0
66 }
67 }
68
69 impl<'r> From<&'r [CertificateDer<'r>]> for Certificates<'r> {
70 fn from(value: &'r [CertificateDer<'r>]) -> Self {
71 Certificates(value.into())
72 }
73 }
74
75 impl From<Vec<CertificateDer<'static>>> for Certificates<'static> {
76 fn from(value: Vec<CertificateDer<'static>>) -> Self {
77 Certificates(value.into())
78 }
79 }
80}
81
82#[cfg(not(feature = "mtls"))]
83mod der {
84 use std::marker::PhantomData;
85
86 /// A thin wrapper over raw, DER-encoded X.509 client certificate data.
87 #[derive(Clone)]
88 pub struct CertificateDer<'r>(PhantomData<&'r [u8]>);
89
90 impl CertificateDer<'_> {
91 pub fn into_owned(self) -> CertificateDer<'static> {
92 CertificateDer(PhantomData)
93 }
94 }
95}