Skip to main content

ytls_server/server_ctx/s_handshake/
r_encrypted_extensions.rs

1//! Encrypted Extensions handler for Server Ctx
2
3use crate::{CtxError, ServerHandshakeCtx, TlsServerCtxConfig};
4
5use ytls_traits::CryptoChaCha20Poly1305Processor;
6use ytls_traits::CryptoSha256TranscriptProcessor;
7
8use ytls_traits::CryptoConfig;
9use ytls_traits::CryptoRng;
10use ytls_traits::Tls13KeyScheduleHandshakeSha256;
11use ytls_traits::TlsLeftOut;
12
13use ytls_record::WrappedStaticRecordBuilder;
14use ytls_traits::EncryptedExtensionsBuilder;
15use ytls_traits::WrappedHandshakeBuilder;
16
17impl<Config, Crypto, Rng> EncryptedExtensionsBuilder for ServerHandshakeCtx<Config, Crypto, Rng>
18where
19    Config: TlsServerCtxConfig,
20    Crypto: CryptoConfig,
21    Rng: CryptoRng,
22{
23    // Empty for nowx
24}
25
26impl<Config, Crypto, Rng> ServerHandshakeCtx<Config, Crypto, Rng>
27where
28    Config: TlsServerCtxConfig,
29    Crypto: CryptoConfig,
30    Rng: CryptoRng,
31{
32    #[inline]
33    pub(crate) fn do_encrypted_extensions<L: TlsLeftOut, T: CryptoSha256TranscriptProcessor>(
34        &mut self,
35        left: &mut L,
36        transcript: &mut T,
37    ) -> Result<(), CtxError> {
38        let key: [u8; 32] = match self.handshake_server_key {
39            None => return Err(CtxError::MissingHandshakeKey),
40            Some(k) => k,
41        };
42
43        let nonce: [u8; 12] = match self.handshake_server_iv {
44            None => return Err(CtxError::MissingHandshakeIv),
45            Some(ref mut n) => match n.use_and_incr() {
46                Some(cur) => cur,
47                None => return Err(CtxError::ExhaustedIv),
48            },
49        };
50
51        let cipher = Crypto::aead_chaha20poly1305(&key);
52
53        let mut encrypted_extensions =
54            WrappedStaticRecordBuilder::<8192>::encrypted_extensions(self)
55                .map_err(CtxError::Builder)?;
56
57        transcript.sha256_update(encrypted_extensions.as_hashing_context_ref());
58
59        let tag = if let Ok([additional_data, encrypt_payload]) =
60            encrypted_extensions.as_disjoint_mut_for_aead()
61        {
62            cipher
63                .encrypt_in_place(&nonce, &additional_data, encrypt_payload.as_mut())
64                .map_err(|_| CtxError::Bug("Encrypt failure."))?
65        } else {
66            return Err(CtxError::Bug(
67                "Disjoint for AEAD failed at certificate verify.",
68            ));
69        };
70
71        encrypted_extensions.set_auth_tag(&tag);
72
73        left.send_record_out(encrypted_extensions.as_encoded_bytes());
74        Ok(())
75    }
76}