ytls_server/server_ctx/s_handshake/
r_server_certificates.rs1use 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}