/src/botan/src/lib/tls/tls13/msg_encrypted_extensions.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * TLS Hello Request and Client Hello Messages |
3 | | * (C) 2022 Jack Lloyd |
4 | | * 2022 René Meusel, Hannes Rantzsch - neXenio GmbH |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #include <botan/tls_messages.h> |
10 | | |
11 | | #include <botan/tls_callbacks.h> |
12 | | #include <botan/tls_exceptn.h> |
13 | | #include <botan/internal/tls_reader.h> |
14 | | |
15 | | namespace Botan::TLS { |
16 | | |
17 | 0 | Encrypted_Extensions::Encrypted_Extensions(const Client_Hello_13& client_hello, const Policy& policy, Callbacks& cb) { |
18 | 0 | const auto& exts = client_hello.extensions(); |
19 | | |
20 | | // RFC 8446 4.2.7 |
21 | | // As of TLS 1.3, servers are permitted to send the "supported_groups" |
22 | | // extension to the client. Clients [...] MAY use the information |
23 | | // learned from a successfully completed handshake to change what groups |
24 | | // they use in their "key_share" extension in subsequent connections. |
25 | 0 | if(exts.has<Supported_Groups>()) { |
26 | 0 | m_extensions.add(new Supported_Groups(policy.key_exchange_groups())); |
27 | 0 | } |
28 | |
|
29 | 0 | const auto record_size_limit = policy.record_size_limit(); |
30 | 0 | const auto max_record_size = MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */; |
31 | 0 | if(exts.has<Record_Size_Limit>()) { |
32 | | // RFC 8449 4 |
33 | | // Endpoints SHOULD advertise the "record_size_limit" extension, even |
34 | | // if they have no need to limit the size of records. [...] For |
35 | | // servers, this allows clients to know that their limit will be |
36 | | // respected. |
37 | 0 | m_extensions.add(new Record_Size_Limit(record_size_limit.value_or(max_record_size))); |
38 | 0 | } else if(record_size_limit.has_value() && record_size_limit.value() < max_record_size) { |
39 | | // RFC 8449 4 |
40 | | // Endpoints SHOULD advertise the "record_size_limit" extension, even if |
41 | | // they have no need to limit the size of records. For clients, this |
42 | | // allows servers to advertise a limit at their discretion. |
43 | 0 | throw TLS_Exception(Alert::MissingExtension, |
44 | 0 | "Server cannot enforce record size limit without the client supporting it"); |
45 | 0 | } |
46 | | |
47 | | // RFC 7250 4.2 |
48 | | // If the TLS server wants to request a certificate from the client |
49 | | // (via the certificate_request message), it MUST include the |
50 | | // client_certificate_type extension in the server hello. |
51 | | // [...] |
52 | | // If the server does not send a certificate_request payload [...], |
53 | | // then the client_certificate_type payload in the server hello MUST be |
54 | | // omitted. |
55 | 0 | if(auto ch_client_cert_types = exts.get<Client_Certificate_Type>(); |
56 | 0 | ch_client_cert_types && policy.request_client_certificate_authentication()) { |
57 | 0 | m_extensions.add(new Client_Certificate_Type(*ch_client_cert_types, policy)); |
58 | 0 | } |
59 | | |
60 | | // RFC 7250 4.2 |
61 | | // The server_certificate_type extension in the client hello indicates the |
62 | | // types of certificates the client is able to process when provided by |
63 | | // the server in a subsequent certificate payload. [...] With the |
64 | | // server_certificate_type extension in the server hello, the TLS server |
65 | | // indicates the certificate type carried in the Certificate payload. |
66 | 0 | if(auto ch_server_cert_types = exts.get<Server_Certificate_Type>()) { |
67 | 0 | m_extensions.add(new Server_Certificate_Type(*ch_server_cert_types, policy)); |
68 | 0 | } |
69 | | |
70 | | // RFC 6066 3 |
71 | | // A server that receives a client hello containing the "server_name" |
72 | | // extension [...] SHALL include an extension of type "server_name" in the |
73 | | // (extended) server hello. The "extension_data" field of this extension |
74 | | // SHALL be empty. |
75 | 0 | if(exts.has<Server_Name_Indicator>()) { |
76 | 0 | m_extensions.add(new Server_Name_Indicator("")); |
77 | 0 | } |
78 | |
|
79 | 0 | if(auto alpn_ext = exts.get<Application_Layer_Protocol_Notification>()) { |
80 | 0 | const auto next_protocol = cb.tls_server_choose_app_protocol(alpn_ext->protocols()); |
81 | 0 | if(!next_protocol.empty()) { |
82 | 0 | m_extensions.add(new Application_Layer_Protocol_Notification(next_protocol)); |
83 | 0 | } |
84 | 0 | } |
85 | | |
86 | | // TODO: Implement handling for (at least) |
87 | | // * SRTP |
88 | |
|
89 | 0 | cb.tls_modify_extensions(m_extensions, Connection_Side::Server, type()); |
90 | 0 | } |
91 | | |
92 | 8.54k | Encrypted_Extensions::Encrypted_Extensions(const std::vector<uint8_t>& buf) { |
93 | 8.54k | TLS_Data_Reader reader("encrypted extensions reader", buf); |
94 | | |
95 | | // Encrypted Extensions contains a list of extensions. This list may legally |
96 | | // be empty. However, in that case we should at least see a two-byte length |
97 | | // field that reads 0x00 0x00. |
98 | 8.54k | if(buf.size() < 2) { |
99 | 11 | throw TLS_Exception(Alert::DecodeError, "Server sent an empty Encrypted Extensions message"); |
100 | 11 | } |
101 | | |
102 | 8.53k | m_extensions.deserialize(reader, Connection_Side::Server, type()); |
103 | | |
104 | | // RFC 8446 4.2 |
105 | | // If an implementation receives an extension which it recognizes and |
106 | | // which is not specified for the message in which it appears, it MUST |
107 | | // abort the handshake with an "illegal_parameter" alert. |
108 | | // |
109 | | // Note that we cannot encounter any extensions that we don't recognize here, |
110 | | // since only extensions we previously offered are allowed in EE. |
111 | 8.53k | const auto allowed_exts = std::set<Extension_Code>{ |
112 | | // Allowed extensions listed in RFC 8446 and implemented in Botan |
113 | 8.53k | Extension_Code::ServerNameIndication, |
114 | | // MAX_FRAGMENT_LENGTH |
115 | 8.53k | Extension_Code::SupportedGroups, |
116 | 8.53k | Extension_Code::UseSrtp, |
117 | | // HEARTBEAT |
118 | 8.53k | Extension_Code::ApplicationLayerProtocolNegotiation, |
119 | | // RFC 7250 |
120 | 8.53k | Extension_Code::ClientCertificateType, |
121 | 8.53k | Extension_Code::ServerCertificateType, |
122 | | // EARLY_DATA |
123 | | |
124 | | // Allowed extensions not listed in RFC 8446 but acceptable as Botan implements them |
125 | 8.53k | Extension_Code::RecordSizeLimit, |
126 | 8.53k | }; |
127 | 8.53k | if(m_extensions.contains_implemented_extensions_other_than(allowed_exts)) { |
128 | 323 | throw TLS_Exception(Alert::IllegalParameter, "Encrypted Extensions contained an extension that is not allowed"); |
129 | 323 | } |
130 | 8.53k | } |
131 | | |
132 | 0 | std::vector<uint8_t> Encrypted_Extensions::serialize() const { |
133 | 0 | return m_extensions.serialize(Connection_Side::Server); |
134 | 0 | } |
135 | | |
136 | | } // namespace Botan::TLS |