1 | use crate::crypto; |
2 | use crate::crypto::hash; |
3 | use crate::suites::{CipherSuiteCommon, SupportedCipherSuite}; |
4 | |
5 | use alloc::vec::Vec; |
6 | use core::fmt; |
7 | |
8 | pub(crate) mod key_schedule; |
9 | |
10 | /// A TLS 1.3 cipher suite supported by rustls. |
11 | pub struct Tls13CipherSuite { |
12 | /// Common cipher suite fields. |
13 | pub common: CipherSuiteCommon, |
14 | |
15 | /// How to complete HKDF with the suite's hash function. |
16 | /// |
17 | /// If you have a HKDF implementation, you should directly implement the `crypto::tls13::Hkdf` |
18 | /// trait (and associated). |
19 | /// |
20 | /// If not, you can implement the [`crypto::hmac::Hmac`] trait (and associated), and then use |
21 | /// [`crypto::tls13::HkdfUsingHmac`]. |
22 | pub hkdf_provider: &'static dyn crypto::tls13::Hkdf, |
23 | |
24 | /// How to produce a [MessageDecrypter] or [MessageEncrypter] |
25 | /// from raw key material. |
26 | /// |
27 | /// [MessageDecrypter]: crate::crypto::cipher::MessageDecrypter |
28 | /// [MessageEncrypter]: crate::crypto::cipher::MessageEncrypter |
29 | pub aead_alg: &'static dyn crypto::cipher::Tls13AeadAlgorithm, |
30 | |
31 | /// How to create QUIC header and record protection algorithms |
32 | /// for this suite. |
33 | /// |
34 | /// Provide `None` to opt out of QUIC support for this suite. It will |
35 | /// not be offered in QUIC handshakes. |
36 | pub quic: Option<&'static dyn crate::quic::Algorithm>, |
37 | } |
38 | |
39 | impl Tls13CipherSuite { |
40 | /// Can a session using suite self resume from suite prev? |
41 | pub fn can_resume_from(&self, prev: &'static Self) -> Option<&'static Self> { |
42 | (prev.common.hash_provider.algorithm() == self.common.hash_provider.algorithm()) |
43 | .then(|| prev) |
44 | } |
45 | } |
46 | |
47 | impl From<&'static Tls13CipherSuite> for SupportedCipherSuite { |
48 | fn from(s: &'static Tls13CipherSuite) -> Self { |
49 | Self::Tls13(s) |
50 | } |
51 | } |
52 | |
53 | impl PartialEq for Tls13CipherSuite { |
54 | fn eq(&self, other: &Self) -> bool { |
55 | self.common.suite == other.common.suite |
56 | } |
57 | } |
58 | |
59 | impl fmt::Debug for Tls13CipherSuite { |
60 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
61 | f&mut DebugStruct<'_, '_>.debug_struct("Tls13CipherSuite" ) |
62 | .field(name:"suite" , &self.common.suite) |
63 | .finish() |
64 | } |
65 | } |
66 | |
67 | /// Constructs the signature message specified in section 4.4.3 of RFC8446. |
68 | pub(crate) fn construct_client_verify_message(handshake_hash: &hash::Output) -> Vec<u8> { |
69 | construct_verify_message(handshake_hash, context_string_with_0:b"TLS 1.3, client CertificateVerify \x00" ) |
70 | } |
71 | |
72 | /// Constructs the signature message specified in section 4.4.3 of RFC8446. |
73 | pub(crate) fn construct_server_verify_message(handshake_hash: &hash::Output) -> Vec<u8> { |
74 | construct_verify_message(handshake_hash, context_string_with_0:b"TLS 1.3, server CertificateVerify \x00" ) |
75 | } |
76 | |
77 | fn construct_verify_message( |
78 | handshake_hash: &hash::Output, |
79 | context_string_with_0: &[u8], |
80 | ) -> Vec<u8> { |
81 | let mut msg: Vec = Vec::new(); |
82 | msg.resize(new_len:64, value:0x20u8); |
83 | msg.extend_from_slice(context_string_with_0); |
84 | msg.extend_from_slice(handshake_hash.as_ref()); |
85 | msg |
86 | } |
87 | |