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    #[inline]
57    pub fn advance_with<Li: TlsLeftIn, Lo: TlsLeftOut, R: TlsRight>(
58        &mut self,
59        li: &mut Li,
60        lo: &mut Lo,
61        r: &mut R,
62    ) -> Result<(), CtxError> {
63        let sw_ap = if let CurCtx::Handshake(ref mut h) = self.cur {
64            match h.spin_handshake(li, lo, &mut self.ks)? {
65                Some(HandshakeComplete) => {
66                    self.hs_complete = true;
67                    true
68                }
69                _ => false,
70            }
71        } else {
72            false
73        };
74
75        if sw_ap {
76            self.cur = CurCtx::Application(ServerApplicationCtx::with_required(
77                self.crypto.clone(),
78                &self.ks,
79            ));
80            self.ks = KeyStoreAp::default();
81        }
82
83        if let CurCtx::Application(ref mut a) = self.cur {
84            a.spin_application(li, lo, r)?;
85        }
86
87        Ok(())
88    }
89}