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