ytls_server/
server_ctx.rs1use 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
33pub 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}