/src/botan/src/lib/tls/msg_server_hello.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * TLS Server Hello and Server Hello Done |
3 | | * (C) 2004-2011,2015,2016,2019 Jack Lloyd |
4 | | * 2016 Matthias Gierlings |
5 | | * 2017 Harry Reimann, Rohde & Schwarz Cybersecurity |
6 | | * |
7 | | * Botan is released under the Simplified BSD License (see license.txt) |
8 | | */ |
9 | | |
10 | | #include <botan/tls_messages.h> |
11 | | #include <botan/tls_extensions.h> |
12 | | #include <botan/tls_callbacks.h> |
13 | | #include <botan/internal/tls_reader.h> |
14 | | #include <botan/internal/tls_session_key.h> |
15 | | #include <botan/internal/tls_handshake_io.h> |
16 | | #include <botan/internal/tls_handshake_hash.h> |
17 | | #include <botan/internal/stl_util.h> |
18 | | |
19 | | namespace Botan { |
20 | | |
21 | | namespace TLS { |
22 | | |
23 | | namespace { |
24 | | |
25 | | const uint64_t DOWNGRADE_TLS11 = 0x444F574E47524400; |
26 | | //const uint64_t DOWNGRADE_TLS12 = 0x444F574E47524401; |
27 | | |
28 | | std::vector<uint8_t> |
29 | | make_server_hello_random(RandomNumberGenerator& rng, |
30 | | Protocol_Version offered_version, |
31 | | const Policy& policy) |
32 | 21.6k | { |
33 | 21.6k | BOTAN_UNUSED(offered_version, policy); |
34 | 21.6k | auto random = make_hello_random(rng, policy); |
35 | 21.6k | return random; |
36 | 21.6k | } |
37 | | |
38 | | } |
39 | | |
40 | | // New session case |
41 | | Server_Hello::Server_Hello(Handshake_IO& io, |
42 | | Handshake_Hash& hash, |
43 | | const Policy& policy, |
44 | | Callbacks& cb, |
45 | | RandomNumberGenerator& rng, |
46 | | const std::vector<uint8_t>& reneg_info, |
47 | | const Client_Hello& client_hello, |
48 | | const Server_Hello::Settings& server_settings, |
49 | | const std::string next_protocol) : |
50 | | m_version(server_settings.protocol_version()), |
51 | | m_session_id(server_settings.session_id()), |
52 | | m_random(make_server_hello_random(rng, m_version, policy)), |
53 | | m_ciphersuite(server_settings.ciphersuite()), |
54 | | m_comp_method(0) |
55 | 21.6k | { |
56 | 21.6k | if(client_hello.supports_extended_master_secret()) |
57 | 1.88k | m_extensions.add(new Extended_Master_Secret); |
58 | | |
59 | | // Sending the extension back does not commit us to sending a stapled response |
60 | 21.6k | if(client_hello.supports_cert_status_message() && policy.support_cert_status_message()) |
61 | 689 | m_extensions.add(new Certificate_Status_Request); |
62 | | |
63 | 21.6k | Ciphersuite c = Ciphersuite::by_id(m_ciphersuite); |
64 | | |
65 | 21.6k | if(c.cbc_ciphersuite() && client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) |
66 | 349 | { |
67 | 349 | m_extensions.add(new Encrypt_then_MAC); |
68 | 349 | } |
69 | | |
70 | 21.6k | if(c.ecc_ciphersuite() && client_hello.extension_types().count(TLSEXT_EC_POINT_FORMATS)) |
71 | 10.3k | { |
72 | 10.3k | m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression())); |
73 | 10.3k | } |
74 | | |
75 | 21.6k | if(client_hello.secure_renegotiation()) |
76 | 13.3k | m_extensions.add(new Renegotiation_Extension(reneg_info)); |
77 | | |
78 | 21.6k | if(client_hello.supports_session_ticket() && server_settings.offer_session_ticket()) |
79 | 2.67k | m_extensions.add(new Session_Ticket()); |
80 | | |
81 | 21.6k | if(!next_protocol.empty() && client_hello.supports_alpn()) |
82 | 10.6k | m_extensions.add(new Application_Layer_Protocol_Notification(next_protocol)); |
83 | | |
84 | 21.6k | if(m_version.is_datagram_protocol()) |
85 | 0 | { |
86 | 0 | const std::vector<uint16_t> server_srtp = policy.srtp_profiles(); |
87 | 0 | const std::vector<uint16_t> client_srtp = client_hello.srtp_profiles(); |
88 | |
|
89 | 0 | if(!server_srtp.empty() && !client_srtp.empty()) |
90 | 0 | { |
91 | 0 | uint16_t shared = 0; |
92 | | // always using server preferences for now |
93 | 0 | for(auto s_srtp : server_srtp) |
94 | 0 | for(auto c_srtp : client_srtp) |
95 | 0 | { |
96 | 0 | if(shared == 0 && s_srtp == c_srtp) |
97 | 0 | shared = s_srtp; |
98 | 0 | } |
99 | |
|
100 | 0 | if(shared) |
101 | 0 | m_extensions.add(new SRTP_Protection_Profiles(shared)); |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | 21.6k | cb.tls_modify_extensions(m_extensions, SERVER); |
106 | | |
107 | 21.6k | hash.update(io.send(*this)); |
108 | 21.6k | } |
109 | | |
110 | | // Resuming |
111 | | Server_Hello::Server_Hello(Handshake_IO& io, |
112 | | Handshake_Hash& hash, |
113 | | const Policy& policy, |
114 | | Callbacks& cb, |
115 | | RandomNumberGenerator& rng, |
116 | | const std::vector<uint8_t>& reneg_info, |
117 | | const Client_Hello& client_hello, |
118 | | Session& resumed_session, |
119 | | bool offer_session_ticket, |
120 | | const std::string& next_protocol) : |
121 | | m_version(resumed_session.version()), |
122 | | m_session_id(client_hello.session_id()), |
123 | | m_random(make_hello_random(rng, policy)), |
124 | | m_ciphersuite(resumed_session.ciphersuite_code()), |
125 | | m_comp_method(0) |
126 | 0 | { |
127 | 0 | if(client_hello.supports_extended_master_secret()) |
128 | 0 | m_extensions.add(new Extended_Master_Secret); |
129 | |
|
130 | 0 | if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) |
131 | 0 | { |
132 | 0 | Ciphersuite c = resumed_session.ciphersuite(); |
133 | 0 | if(c.cbc_ciphersuite()) |
134 | 0 | m_extensions.add(new Encrypt_then_MAC); |
135 | 0 | } |
136 | |
|
137 | 0 | if(resumed_session.ciphersuite().ecc_ciphersuite() && client_hello.extension_types().count(TLSEXT_EC_POINT_FORMATS)) |
138 | 0 | { |
139 | 0 | m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression())); |
140 | 0 | } |
141 | |
|
142 | 0 | if(client_hello.secure_renegotiation()) |
143 | 0 | m_extensions.add(new Renegotiation_Extension(reneg_info)); |
144 | |
|
145 | 0 | if(client_hello.supports_session_ticket() && offer_session_ticket) |
146 | 0 | m_extensions.add(new Session_Ticket()); |
147 | |
|
148 | 0 | if(!next_protocol.empty() && client_hello.supports_alpn()) |
149 | 0 | m_extensions.add(new Application_Layer_Protocol_Notification(next_protocol)); |
150 | |
|
151 | 0 | cb.tls_modify_extensions(m_extensions, SERVER); |
152 | |
|
153 | 0 | hash.update(io.send(*this)); |
154 | 0 | } |
155 | | |
156 | | /* |
157 | | * Deserialize a Server Hello message |
158 | | */ |
159 | | Server_Hello::Server_Hello(const std::vector<uint8_t>& buf) |
160 | 1.02k | { |
161 | 1.02k | if(buf.size() < 38) |
162 | 42 | throw Decoding_Error("Server_Hello: Packet corrupted"); |
163 | | |
164 | 979 | TLS_Data_Reader reader("ServerHello", buf); |
165 | | |
166 | 979 | const uint8_t major_version = reader.get_byte(); |
167 | 979 | const uint8_t minor_version = reader.get_byte(); |
168 | | |
169 | 979 | m_version = Protocol_Version(major_version, minor_version); |
170 | | |
171 | 979 | m_random = reader.get_fixed<uint8_t>(32); |
172 | | |
173 | 979 | m_session_id = reader.get_range<uint8_t>(1, 0, 32); |
174 | | |
175 | 979 | m_ciphersuite = reader.get_uint16_t(); |
176 | | |
177 | 979 | m_comp_method = reader.get_byte(); |
178 | | |
179 | 979 | m_extensions.deserialize(reader, Connection_Side::SERVER); |
180 | 979 | } |
181 | | |
182 | | /* |
183 | | * Serialize a Server Hello message |
184 | | */ |
185 | | std::vector<uint8_t> Server_Hello::serialize() const |
186 | 21.6k | { |
187 | 21.6k | std::vector<uint8_t> buf; |
188 | | |
189 | 21.6k | buf.push_back(m_version.major_version()); |
190 | 21.6k | buf.push_back(m_version.minor_version()); |
191 | 21.6k | buf += m_random; |
192 | | |
193 | 21.6k | append_tls_length_value(buf, m_session_id, 1); |
194 | | |
195 | 21.6k | buf.push_back(get_byte(0, m_ciphersuite)); |
196 | 21.6k | buf.push_back(get_byte(1, m_ciphersuite)); |
197 | | |
198 | 21.6k | buf.push_back(m_comp_method); |
199 | | |
200 | 21.6k | buf += m_extensions.serialize(Connection_Side::SERVER); |
201 | | |
202 | 21.6k | return buf; |
203 | 21.6k | } |
204 | | |
205 | | bool Server_Hello::random_signals_downgrade() const |
206 | 0 | { |
207 | 0 | const uint64_t last8 = load_be<uint64_t>(m_random.data(), 3); |
208 | 0 | return (last8 == DOWNGRADE_TLS11); |
209 | 0 | } |
210 | | |
211 | | /* |
212 | | * Create a new Server Hello Done message |
213 | | */ |
214 | | Server_Hello_Done::Server_Hello_Done(Handshake_IO& io, |
215 | | Handshake_Hash& hash) |
216 | 21.4k | { |
217 | 21.4k | hash.update(io.send(*this)); |
218 | 21.4k | } |
219 | | |
220 | | /* |
221 | | * Deserialize a Server Hello Done message |
222 | | */ |
223 | | Server_Hello_Done::Server_Hello_Done(const std::vector<uint8_t>& buf) |
224 | 0 | { |
225 | 0 | if(buf.size()) |
226 | 0 | throw Decoding_Error("Server_Hello_Done: Must be empty, and is not"); |
227 | 0 | } |
228 | | |
229 | | /* |
230 | | * Serialize a Server Hello Done message |
231 | | */ |
232 | | std::vector<uint8_t> Server_Hello_Done::serialize() const |
233 | 21.4k | { |
234 | 21.4k | return std::vector<uint8_t>(); |
235 | 21.4k | } |
236 | | |
237 | | } |
238 | | |
239 | | } |