Skip to main content

ytls_server/server_ctx/s_handshake/
r_server_certificates.rs

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