1use crate::{CtxError, ServerHandshakeCtx, TlsServerCtxConfig};
4
5use ytls_traits::CryptoChaCha20Poly1305Processor;
6use ytls_traits::CryptoSha256TranscriptProcessor;
7use ytls_traits::CryptoSignerP256Processor;
8
9use ytls_traits::Tls13KeyScheduleHandshakeSha256;
10
11use ytls_traits::CryptoConfig;
12use ytls_traits::CryptoRng;
13use ytls_traits::TlsLeftOut;
14
15use ytls_record::WrappedStaticRecordBuilder;
16use ytls_traits::ServerCertificateVerifyBuilder;
17use ytls_traits::WrappedHandshakeBuilder;
18
19impl<Config, Crypto, Rng> ServerCertificateVerifyBuilder for ServerHandshakeCtx<Config, Crypto, Rng>
20where
21 Config: TlsServerCtxConfig,
22 Crypto: CryptoConfig,
23 Rng: CryptoRng,
24{
25 #[inline]
26 fn signature_algorithm(&self) -> [u8; 2] {
27 [0x04, 0x03]
29 }
30 #[inline]
31 fn sign_cert_verify(&self) -> &[u8] {
32 match self.signature_cert_verify {
33 Some(ref s) => &s[..self.signature_cert_verify_len],
34 None => &[],
35 }
36 }
37}
38
39impl<Config, Crypto, Rng> ServerHandshakeCtx<Config, Crypto, Rng>
40where
41 Config: TlsServerCtxConfig,
42 Crypto: CryptoConfig,
43 Rng: CryptoRng,
44{
45 #[inline]
46 pub(crate) fn do_server_certificate_verify<
47 L: TlsLeftOut,
48 T: CryptoSha256TranscriptProcessor,
49 >(
50 &mut self,
51 left: &mut L,
52 transcript: &mut T,
53 ) -> Result<(), CtxError> {
54 let key: [u8; 32] = match self.handshake_server_key {
55 None => return Err(CtxError::MissingHandshakeKey),
56 Some(k) => k,
57 };
58
59 let nonce: [u8; 12] = match self.handshake_server_iv {
60 None => return Err(CtxError::MissingHandshakeIv),
61 Some(ref mut n) => match n.use_and_incr() {
62 Some(cur) => cur,
63 None => return Err(CtxError::ExhaustedIv),
64 },
65 };
66
67 let ctx_transcript = transcript.sha256_fork();
69 let ctx_hash_input = ctx_transcript.sha256_finalize();
70 self.cert_verify_hash = Some(ctx_hash_input);
71
72 let h = match self.cert_verify_hash {
73 Some(h) => h,
74 None => return Err(CtxError::Bug("Missing certificate verify hash.")),
75 };
76
77 let verify: [u8; 130] = [
84 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
86 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
87 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
88 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
89 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
90 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65,
93 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56,
94 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13],
97 h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25],
98 h[26], h[27], h[28], h[29], h[30], h[31],
99 ];
100
101 let raw_signing_key = self.config.server_private_key();
102 let signer = match Crypto::sign_p256_init(raw_signing_key) {
103 Some(signer) => signer,
104 None => return Err(CtxError::PrivateKey),
105 };
106 let mut c_bytes: [u8; 100] = [0; 100];
107 let c_bytes_len = match signer.sign_p256(&verify, &mut c_bytes) {
108 None => return Err(CtxError::Crypto),
109 Some(out_len) => out_len,
110 };
111
112 self.signature_cert_verify = Some(c_bytes);
113 self.signature_cert_verify_len = c_bytes_len;
114
115 let cipher = Crypto::aead_chaha20poly1305(&key);
116
117 let mut server_certificate_verify =
118 WrappedStaticRecordBuilder::<8192>::server_certificate_verify(self)
119 .map_err(CtxError::Builder)?;
120
121 transcript.sha256_update(server_certificate_verify.as_hashing_context_ref());
122
123 let tag = if let Ok([additional_data, encrypt_payload]) =
124 server_certificate_verify.as_disjoint_mut_for_aead()
125 {
126 cipher
127 .encrypt_in_place(&nonce, &additional_data, encrypt_payload.as_mut())
128 .map_err(|_| CtxError::Bug("Encrypt failure."))?
129 } else {
130 return Err(CtxError::Bug(
131 "Disjoint for AEAD failed at certificate verify.",
132 ));
133 };
134
135 server_certificate_verify.set_auth_tag(&tag);
136
137 left.send_record_out(server_certificate_verify.as_encoded_bytes());
138 Ok(())
139 }
140}