Skip to main content

ytls_server/
server_ctx.rs

1//! Server Ctx
2
3use crate::CtxError;
4use crate::TlsServerCtxConfig;
5
6use ytls_traits::CryptoConfig;
7use ytls_traits::CryptoRng;
8
9pub use ytls_traits::CtxApplicationProcessor;
10pub use ytls_traits::CtxHandshakeProcessor;
11use ytls_traits::{TlsLeftIn, TlsLeftOut, TlsRight};
12
13pub use ytls_traits::HandshakeComplete;
14
15use ytls_keys::KeyStoreAp;
16
17#[cfg(feature = "zeroize")]
18use zeroize::{Zeroize, ZeroizeOnDrop};
19
20mod s_handshake;
21#[doc(inline)]
22pub use s_handshake::*;
23
24mod s_application;
25#[doc(inline)]
26pub use s_application::*;
27
28enum CurCtx<Config, Crypto, Rng> {
29    Handshake(ServerHandshakeCtx<Config, Crypto, Rng>),
30    Application(ServerApplicationCtx<Crypto>),
31}
32
33/// yTLS Server Context
34pub struct TlsServerCtx<Config, Crypto, Rng> {
35    crypto: Crypto,
36    cur: CurCtx<Config, Crypto, Rng>,
37    ks: KeyStoreAp,
38    hs_complete: bool,
39}
40
41impl<Config, Crypto, Rng> TlsServerCtx<Config, Crypto, Rng>
42where
43    Config: TlsServerCtxConfig,
44    Crypto: CryptoConfig + Clone,
45    Rng: CryptoRng,
46{
47    #[inline]
48    pub fn with_required(config: Config, crypto: Crypto, rng: Rng) -> Self {
49        Self {
50            crypto: crypto.clone(),
51            ks: KeyStoreAp::default(),
52            cur: CurCtx::Handshake(ServerHandshakeCtx::with_required(config, crypto, rng)),
53            hs_complete: false,
54        }
55    }
56    /// Indicates Server Ctx is not ready for application data
57    #[inline]
58    pub fn is_handshaking(&self) -> bool {
59        match self.cur {
60            CurCtx::Application(_) => false,
61            _ => true,
62        }
63    }
64    #[inline]
65    pub fn advance_with<Li: TlsLeftIn, Lo: TlsLeftOut, R: TlsRight>(
66        &mut self,
67        li: &mut Li,
68        lo: &mut Lo,
69        r: &mut R,
70    ) -> Result<(), CtxError> {
71        let sw_ap = if let CurCtx::Handshake(ref mut h) = self.cur {
72            match h.spin_handshake(li, lo, &mut self.ks)? {
73                Some(HandshakeComplete) => {
74                    self.hs_complete = true;
75                    true
76                }
77                _ => false,
78            }
79        } else {
80            false
81        };
82
83        if sw_ap {
84            self.cur = CurCtx::Application(ServerApplicationCtx::with_required(
85                self.crypto.clone(),
86                &self.ks,
87            ));
88            self.ks = KeyStoreAp::default();
89        }
90
91        if let CurCtx::Application(ref mut a) = self.cur {
92            a.spin_application(li, lo, r)?;
93        }
94
95        Ok(())
96    }
97}