/src/botan/src/lib/tls/tls12/tls_server_impl_12.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * TLS Server |
3 | | * (C) 2004-2011,2012,2016 Jack Lloyd |
4 | | * 2016 Matthias Gierlings |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | |
10 | | #include <botan/tls_server.h> |
11 | | #include <botan/tls_messages.h> |
12 | | #include <botan/tls_version.h> |
13 | | #include <botan/ocsp.h> |
14 | | #include <botan/internal/tls_handshake_state.h> |
15 | | #include <botan/internal/stl_util.h> |
16 | | #include <botan/internal/tls_server_impl_12.h> |
17 | | #include <botan/tls_magic.h> |
18 | | |
19 | | namespace Botan::TLS { |
20 | | |
21 | | class Server_Handshake_State final : public Handshake_State |
22 | | { |
23 | | public: |
24 | | Server_Handshake_State(std::unique_ptr<Handshake_IO> io, Callbacks& cb) |
25 | 23.4k | : Handshake_State(std::move(io), cb) {} |
26 | | |
27 | 14.3k | Private_Key* server_rsa_kex_key() { return m_server_rsa_kex_key; } |
28 | | void set_server_rsa_kex_key(Private_Key* key) |
29 | 0 | { m_server_rsa_kex_key = key; } |
30 | | |
31 | | bool allow_session_resumption() const |
32 | 20.3k | { return m_allow_session_resumption; } |
33 | | void set_allow_session_resumption(bool allow_session_resumption) |
34 | 0 | { m_allow_session_resumption = allow_session_resumption; } |
35 | | |
36 | | const std::vector<X509_Certificate>& resume_peer_certs() const |
37 | 322 | { return m_resume_peer_certs; } |
38 | | |
39 | | void set_resume_certs(const std::vector<X509_Certificate>& certs) |
40 | 0 | { m_resume_peer_certs = certs; } |
41 | | |
42 | 0 | void mark_as_resumption() { m_is_a_resumption = true; } |
43 | | |
44 | 29 | bool is_a_resumption() const { return m_is_a_resumption; } |
45 | | |
46 | | private: |
47 | | // Used by the server only, in case of RSA key exchange. Not owned |
48 | | Private_Key* m_server_rsa_kex_key = nullptr; |
49 | | |
50 | | /* |
51 | | * Used by the server to know if resumption should be allowed on |
52 | | * a server-initiated renegotiation |
53 | | */ |
54 | | bool m_allow_session_resumption = true; |
55 | | |
56 | | bool m_is_a_resumption = false; |
57 | | |
58 | | std::vector<X509_Certificate> m_resume_peer_certs; |
59 | | }; |
60 | | |
61 | | namespace { |
62 | | |
63 | | bool check_for_resume(Session& session_info, |
64 | | Session_Manager& session_manager, |
65 | | Credentials_Manager& credentials, |
66 | | Callbacks& cb, |
67 | | const Client_Hello_12* client_hello, |
68 | | std::chrono::seconds session_ticket_lifetime) |
69 | 20.3k | { |
70 | 20.3k | const std::vector<uint8_t>& client_session_id = client_hello->session_id(); |
71 | 20.3k | const std::vector<uint8_t>& session_ticket = client_hello->session_ticket(); |
72 | | |
73 | 20.3k | if(session_ticket.empty()) |
74 | 16.1k | { |
75 | 16.1k | if(client_session_id.empty()) // not resuming |
76 | 16.0k | return false; |
77 | | |
78 | | // not found |
79 | 30 | if(!session_manager.load_from_session_id(client_session_id, session_info)) |
80 | 30 | return false; |
81 | 30 | } |
82 | 4.27k | else |
83 | 4.27k | { |
84 | | // If a session ticket was sent, ignore client session ID |
85 | 4.27k | try |
86 | 4.27k | { |
87 | 4.27k | session_info = Session::decrypt( |
88 | 4.27k | session_ticket, |
89 | 4.27k | credentials.psk("tls-server", "session-ticket", "")); |
90 | | |
91 | 4.27k | if(session_ticket_lifetime != std::chrono::seconds(0) && |
92 | 4.27k | cb.tls_current_timestamp() - session_info.start_time() > session_ticket_lifetime) |
93 | 0 | return false; // ticket has expired |
94 | 4.27k | } |
95 | 4.27k | catch(...) |
96 | 4.27k | { |
97 | 4.27k | return false; |
98 | 4.27k | } |
99 | 4.27k | } |
100 | | |
101 | | // wrong version |
102 | 0 | if(client_hello->legacy_version() != session_info.version()) |
103 | 0 | return false; |
104 | | |
105 | | // client didn't send original ciphersuite |
106 | 0 | if(!value_exists(client_hello->ciphersuites(), |
107 | 0 | session_info.ciphersuite_code())) |
108 | 0 | return false; |
109 | | |
110 | | // client sent a different SNI hostname |
111 | 0 | if(!client_hello->sni_hostname().empty() && |
112 | 0 | client_hello->sni_hostname() != session_info.server_info().hostname()) |
113 | 0 | return false; |
114 | | |
115 | | // Checking extended_master_secret on resume (RFC 7627 section 5.3) |
116 | 0 | if(client_hello->supports_extended_master_secret() != session_info.supports_extended_master_secret()) |
117 | 0 | { |
118 | 0 | if(!session_info.supports_extended_master_secret()) |
119 | 0 | { |
120 | 0 | return false; // force new handshake with extended master secret |
121 | 0 | } |
122 | 0 | else |
123 | 0 | { |
124 | | /* |
125 | | Client previously negotiated session with extended master secret, |
126 | | but has now attempted to resume without the extension: abort |
127 | | */ |
128 | 0 | throw TLS_Exception(Alert::HandshakeFailure, |
129 | 0 | "Client resumed extended ms session without sending extension"); |
130 | 0 | } |
131 | 0 | } |
132 | | |
133 | | // Checking encrypt_then_mac on resume (RFC 7366 section 3.1) |
134 | 0 | if(!client_hello->supports_encrypt_then_mac() && session_info.supports_encrypt_then_mac()) |
135 | 0 | { |
136 | | /* |
137 | | Client previously negotiated session with Encrypt-then-MAC, |
138 | | but has now attempted to resume without the extension: abort |
139 | | */ |
140 | 0 | throw TLS_Exception(Alert::HandshakeFailure, |
141 | 0 | "Client resumed Encrypt-then-MAC session without sending extension"); |
142 | 0 | } |
143 | | |
144 | 0 | return true; |
145 | 0 | } |
146 | | |
147 | | /* |
148 | | * Choose which ciphersuite to use |
149 | | */ |
150 | | uint16_t choose_ciphersuite( |
151 | | const Policy& policy, |
152 | | Protocol_Version version, |
153 | | const std::map<std::string, std::vector<X509_Certificate>>& cert_chains, |
154 | | const Client_Hello_12& client_hello) |
155 | 20.3k | { |
156 | 20.3k | const bool our_choice = policy.server_uses_own_ciphersuite_preferences(); |
157 | 20.3k | const std::vector<uint16_t>& client_suites = client_hello.ciphersuites(); |
158 | 20.3k | const std::vector<uint16_t> server_suites = policy.ciphersuite_list(version); |
159 | | |
160 | 20.3k | if(server_suites.empty()) |
161 | 0 | throw TLS_Exception(Alert::HandshakeFailure, |
162 | 0 | "Policy forbids us from negotiating any ciphersuite"); |
163 | | |
164 | 20.3k | const bool have_shared_ecc_curve = |
165 | 20.3k | (policy.choose_key_exchange_group(client_hello.supported_ecc_curves(), {}) != Group_Params::NONE); |
166 | | |
167 | | /* |
168 | | Walk down one list in preference order |
169 | | */ |
170 | 20.3k | std::vector<uint16_t> pref_list = server_suites; |
171 | 20.3k | std::vector<uint16_t> other_list = client_suites; |
172 | | |
173 | 20.3k | if(!our_choice) |
174 | 0 | std::swap(pref_list, other_list); |
175 | | |
176 | 20.3k | for(auto suite_id : pref_list) |
177 | 1.04M | { |
178 | 1.04M | if(!value_exists(other_list, suite_id)) |
179 | 1.02M | continue; |
180 | | |
181 | 20.8k | const auto suite = Ciphersuite::by_id(suite_id); |
182 | | |
183 | 20.8k | if(!suite.has_value() || !suite->valid()) |
184 | 0 | { |
185 | 0 | continue; |
186 | 0 | } |
187 | | |
188 | 20.8k | if(have_shared_ecc_curve == false && suite->ecc_ciphersuite()) |
189 | 546 | { |
190 | 546 | continue; |
191 | 546 | } |
192 | | |
193 | | // For non-anon ciphersuites |
194 | 20.3k | if(suite->signature_used()) |
195 | 293 | { |
196 | 293 | const std::string sig_algo = suite->sig_algo(); |
197 | | |
198 | | // Do we have any certificates for this sig? |
199 | 293 | if(cert_chains.count(sig_algo) == 0) |
200 | 95 | { |
201 | 95 | continue; |
202 | 95 | } |
203 | | |
204 | 198 | const std::vector<Signature_Scheme> allowed = |
205 | 198 | policy.allowed_signature_schemes(); |
206 | | |
207 | 198 | std::vector<Signature_Scheme> client_sig_methods = |
208 | 198 | client_hello.signature_schemes(); |
209 | | |
210 | | /* |
211 | | Contrary to the wording of draft-ietf-tls-md5-sha1-deprecate we do |
212 | | not enforce that clients do not offer support SHA-1 or MD5 |
213 | | signatures; we just ignore it. |
214 | | */ |
215 | 198 | bool we_support_some_hash_by_client = false; |
216 | | |
217 | 198 | for(Signature_Scheme scheme : client_sig_methods) |
218 | 16.6k | { |
219 | 16.6k | if(!scheme.is_available()) |
220 | 11.8k | continue; |
221 | | |
222 | 4.75k | if(scheme.algorithm_name() == suite->sig_algo() && |
223 | 4.75k | policy.allowed_signature_hash(scheme.hash_function_name())) |
224 | 4.27k | { |
225 | 4.27k | we_support_some_hash_by_client = true; |
226 | 4.27k | } |
227 | 4.75k | } |
228 | | |
229 | 198 | if(we_support_some_hash_by_client == false) |
230 | 57 | { |
231 | 57 | throw TLS_Exception(Alert::HandshakeFailure, |
232 | 57 | "Policy does not accept any hash function supported by client"); |
233 | 57 | } |
234 | 198 | } |
235 | | |
236 | 20.1k | return suite_id; |
237 | 20.3k | } |
238 | | |
239 | 156 | throw TLS_Exception(Alert::HandshakeFailure, |
240 | 156 | "Can't agree on a ciphersuite with client"); |
241 | 20.3k | } |
242 | | |
243 | | std::map<std::string, std::vector<X509_Certificate>> |
244 | | get_server_certs(const std::string& hostname, |
245 | | const std::vector<Signature_Scheme>& cert_sig_schemes, |
246 | | Credentials_Manager& creds) |
247 | 20.3k | { |
248 | 20.3k | const char* cert_types[] = { "RSA", "ECDSA", "DSA", nullptr }; |
249 | | |
250 | 20.3k | std::map<std::string, std::vector<X509_Certificate>> cert_chains; |
251 | | |
252 | 81.5k | for(size_t i = 0; cert_types[i]; ++i) |
253 | 61.1k | { |
254 | 61.1k | const std::vector<X509_Certificate> certs = |
255 | 61.1k | creds.cert_chain_single_type(cert_types[i], to_algorithm_identifiers(cert_sig_schemes), "tls-server", hostname); |
256 | | |
257 | 61.1k | if(!certs.empty()) |
258 | 20.3k | cert_chains[cert_types[i]] = certs; |
259 | 61.1k | } |
260 | | |
261 | 20.3k | return cert_chains; |
262 | 20.3k | } |
263 | | |
264 | | } |
265 | | |
266 | | Server_Impl_12::Server_Impl_12(Callbacks& callbacks, |
267 | | Session_Manager& session_manager, |
268 | | Credentials_Manager& creds, |
269 | | const Policy& policy, |
270 | | RandomNumberGenerator& rng, |
271 | | bool is_datagram, |
272 | | size_t io_buf_sz) : |
273 | | Channel_Impl_12(callbacks, session_manager, rng, policy, |
274 | | true, is_datagram, io_buf_sz), |
275 | | m_creds(creds) |
276 | 6.05k | { |
277 | 6.05k | } |
278 | | |
279 | | Server_Impl_12::Server_Impl_12(const Channel_Impl::Downgrade_Information& downgrade_info) : |
280 | | Channel_Impl_12(downgrade_info.callbacks, |
281 | | downgrade_info.session_manager, |
282 | | downgrade_info.rng, |
283 | | downgrade_info.policy, |
284 | | true /* is_server*/, |
285 | | false /* TLS 1.3 does not support DTLS yet */, |
286 | | downgrade_info.io_buffer_size), |
287 | | m_creds(downgrade_info.creds) |
288 | 0 | { |
289 | 0 | } |
290 | | |
291 | | std::unique_ptr<Handshake_State> Server_Impl_12::new_handshake_state(std::unique_ptr<Handshake_IO> io) |
292 | 23.4k | { |
293 | 23.4k | std::unique_ptr<Handshake_State> state(new Server_Handshake_State(std::move(io), callbacks())); |
294 | 23.4k | state->set_expected_next(Handshake_Type::ClientHello); |
295 | 23.4k | return state; |
296 | 23.4k | } |
297 | | |
298 | | std::vector<X509_Certificate> |
299 | | Server_Impl_12::get_peer_cert_chain(const Handshake_State& state_base) const |
300 | 322 | { |
301 | 322 | const Server_Handshake_State& state = dynamic_cast<const Server_Handshake_State&>(state_base); |
302 | 322 | if(!state.resume_peer_certs().empty()) |
303 | 0 | return state.resume_peer_certs(); |
304 | | |
305 | 322 | if(state.client_certs()) |
306 | 0 | return state.client_certs()->cert_chain(); |
307 | 322 | return std::vector<X509_Certificate>(); |
308 | 322 | } |
309 | | |
310 | | /* |
311 | | * Send a hello request to the client |
312 | | */ |
313 | | void Server_Impl_12::initiate_handshake(Handshake_State& state, |
314 | | bool force_full_renegotiation) |
315 | 0 | { |
316 | 0 | dynamic_cast<Server_Handshake_State&>(state). |
317 | 0 | set_allow_session_resumption(!force_full_renegotiation); |
318 | |
|
319 | 0 | Hello_Request hello_req(state.handshake_io()); |
320 | 0 | } |
321 | | |
322 | | namespace { |
323 | | |
324 | | Protocol_Version select_version(const TLS::Policy& policy, |
325 | | Protocol_Version client_offer, |
326 | | Protocol_Version active_version, |
327 | | const std::vector<Protocol_Version>& supported_versions) |
328 | 22.6k | { |
329 | 22.6k | const bool is_datagram = client_offer.is_datagram_protocol(); |
330 | 22.6k | const bool initial_handshake = (active_version.valid() == false); |
331 | | |
332 | 22.6k | if(!supported_versions.empty()) |
333 | 425 | { |
334 | 425 | if(is_datagram) |
335 | 405 | { |
336 | 405 | if(policy.allow_dtls12() && value_exists(supported_versions, Protocol_Version(Protocol_Version::DTLS_V12))) |
337 | 375 | return Protocol_Version::DTLS_V12; |
338 | 30 | throw TLS_Exception(Alert::ProtocolVersion, "No shared DTLS version"); |
339 | 405 | } |
340 | 20 | else |
341 | 20 | { |
342 | 20 | if(policy.allow_tls12() && value_exists(supported_versions, Protocol_Version(Protocol_Version::TLS_V12))) |
343 | 13 | return Protocol_Version::TLS_V12; |
344 | 7 | throw TLS_Exception(Alert::ProtocolVersion, "No shared TLS version"); |
345 | 20 | } |
346 | 425 | } |
347 | | |
348 | 22.1k | if(!initial_handshake) |
349 | 0 | { |
350 | | /* |
351 | | * If this is a renegotiation, and the client has offered a |
352 | | * later version than what it initially negotiated, negotiate |
353 | | * the old version. This matches OpenSSL's behavior. If the |
354 | | * client is offering a version earlier than what it initially |
355 | | * negotiated, reject as a probable attack. |
356 | | */ |
357 | 0 | if(active_version > client_offer) |
358 | 0 | { |
359 | 0 | throw TLS_Exception(Alert::ProtocolVersion, |
360 | 0 | "Client negotiated " + |
361 | 0 | active_version.to_string() + |
362 | 0 | " then renegotiated with " + |
363 | 0 | client_offer.to_string()); |
364 | 0 | } |
365 | 0 | else |
366 | 0 | { |
367 | 0 | return active_version; |
368 | 0 | } |
369 | 0 | } |
370 | | |
371 | 22.1k | if(is_datagram) |
372 | 1.80k | { |
373 | 1.80k | if(policy.allow_dtls12() && client_offer >= Protocol_Version::DTLS_V12) |
374 | 1.79k | return Protocol_Version::DTLS_V12; |
375 | 1.80k | } |
376 | 20.3k | else |
377 | 20.3k | { |
378 | 20.3k | if(policy.allow_tls12() && client_offer >= Protocol_Version::TLS_V12) |
379 | 20.3k | return Protocol_Version::TLS_V12; |
380 | 20.3k | } |
381 | | |
382 | 8 | throw TLS_Exception(Alert::ProtocolVersion, |
383 | 8 | "Client version " + client_offer.to_string() + " is unacceptable by policy"); |
384 | 22.1k | } |
385 | | } |
386 | | |
387 | | /* |
388 | | * Process a Client Hello Message |
389 | | */ |
390 | | void Server_Impl_12::process_client_hello_msg(const Handshake_State* active_state, |
391 | | Server_Handshake_State& pending_state, |
392 | | const std::vector<uint8_t>& contents, |
393 | | bool epoch0_restart) |
394 | 23.7k | { |
395 | 23.7k | BOTAN_ASSERT_IMPLICATION(epoch0_restart, active_state != nullptr, "Can't restart with a dead connection"); |
396 | | |
397 | 23.7k | const bool initial_handshake = epoch0_restart || !active_state; |
398 | | |
399 | 23.7k | if(initial_handshake == false && policy().allow_client_initiated_renegotiation() == false) |
400 | 0 | { |
401 | 0 | if(policy().abort_connection_on_undesired_renegotiation()) |
402 | 0 | throw TLS_Exception(Alert::NoRenegotiation, "Server policy prohibits renegotiation"); |
403 | 0 | else |
404 | 0 | send_warning_alert(Alert::NoRenegotiation); |
405 | 0 | return; |
406 | 0 | } |
407 | | |
408 | 23.7k | if(!policy().allow_insecure_renegotiation() && |
409 | 23.7k | !(initial_handshake || secure_renegotiation_supported())) |
410 | 0 | { |
411 | 0 | send_warning_alert(Alert::NoRenegotiation); |
412 | 0 | return; |
413 | 0 | } |
414 | | |
415 | 23.7k | if(pending_state.handshake_io().have_more_data()) |
416 | 23 | throw TLS_Exception(Alert::UnexpectedMessage, |
417 | 23 | "Have data remaining in buffer after ClientHello"); |
418 | | |
419 | 23.7k | pending_state.client_hello(new Client_Hello_12(contents)); |
420 | 23.7k | const Protocol_Version client_offer = pending_state.client_hello()->legacy_version(); |
421 | 23.7k | const bool datagram = client_offer.is_datagram_protocol(); |
422 | | |
423 | 23.7k | if(datagram) |
424 | 2.22k | { |
425 | 2.22k | if(client_offer.major_version() == 0xFF) |
426 | 16 | throw TLS_Exception(Alert::ProtocolVersion, "Client offered DTLS version with major version 0xFF"); |
427 | 2.22k | } |
428 | 21.5k | else |
429 | 21.5k | { |
430 | 21.5k | if(client_offer.major_version() < 3) |
431 | 8 | throw TLS_Exception(Alert::ProtocolVersion, "Client offered TLS version with major version under 3"); |
432 | 21.4k | if(client_offer.major_version() == 3 && client_offer.minor_version() == 0) |
433 | 1 | throw TLS_Exception(Alert::ProtocolVersion, "Client offered SSLv3 which is not supported"); |
434 | 21.4k | } |
435 | | |
436 | | /* |
437 | | * BoGo test suite expects that we will send the hello verify with a record |
438 | | * version matching the version that is eventually negotiated. This is wrong |
439 | | * but harmless, so go with it. Also doing the version negotiation step first |
440 | | * allows to immediately close the connection with an alert if the client has |
441 | | * offered a version that we are not going to negotiate anyway, instead of |
442 | | * making them first do the cookie exchange and then telling them no. |
443 | | * |
444 | | * There is no issue with amplification here, since the alert is just 2 bytes. |
445 | | */ |
446 | 23.6k | const Protocol_Version negotiated_version = |
447 | 23.6k | select_version(policy(), client_offer, |
448 | 23.6k | active_state ? active_state->version() : Protocol_Version(), |
449 | 23.6k | pending_state.client_hello()->supported_versions()); |
450 | | |
451 | 23.6k | pending_state.set_version(negotiated_version); |
452 | | |
453 | 23.6k | const auto compression_methods = pending_state.client_hello()->compression_methods(); |
454 | 23.6k | if(!value_exists(compression_methods, uint8_t(0))) |
455 | 40 | throw TLS_Exception(Alert::IllegalParameter, "Client did not offer NULL compression"); |
456 | | |
457 | 23.6k | if(initial_handshake && datagram) |
458 | 2.14k | { |
459 | 2.14k | SymmetricKey cookie_secret; |
460 | | |
461 | 2.14k | try |
462 | 2.14k | { |
463 | 2.14k | cookie_secret = m_creds.psk("tls-server", "dtls-cookie-secret", ""); |
464 | 2.14k | } |
465 | 2.14k | catch(...) {} |
466 | | |
467 | 2.14k | if(cookie_secret.size() > 0) |
468 | 2.14k | { |
469 | 2.14k | const std::string client_identity = callbacks().tls_peer_network_identity(); |
470 | 2.14k | Hello_Verify_Request verify(pending_state.client_hello()->cookie_input_data(), client_identity, cookie_secret); |
471 | | |
472 | 2.14k | if(pending_state.client_hello()->cookie() != verify.cookie()) |
473 | 2.14k | { |
474 | 2.14k | if(epoch0_restart) |
475 | 0 | pending_state.handshake_io().send_under_epoch(verify, 0); |
476 | 2.14k | else |
477 | 2.14k | pending_state.handshake_io().send(verify); |
478 | | |
479 | 2.14k | pending_state.client_hello(static_cast<Client_Hello_12*>(nullptr)); |
480 | 2.14k | pending_state.set_expected_next(Handshake_Type::ClientHello); |
481 | 2.14k | return; |
482 | 2.14k | } |
483 | 2.14k | } |
484 | 0 | else if(epoch0_restart) |
485 | 0 | { |
486 | 0 | throw TLS_Exception(Alert::HandshakeFailure, "Reuse of DTLS association requires DTLS cookie secret be set"); |
487 | 0 | } |
488 | 2.14k | } |
489 | | |
490 | 21.5k | if(epoch0_restart) |
491 | 0 | { |
492 | | // If we reached here then we were able to verify the cookie |
493 | 0 | reset_active_association_state(); |
494 | 0 | } |
495 | | |
496 | 21.5k | secure_renegotiation_check(pending_state.client_hello()); |
497 | | |
498 | 21.5k | callbacks().tls_examine_extensions(pending_state.client_hello()->extensions(), Connection_Side::Client, Handshake_Type::ClientHello); |
499 | | |
500 | 21.5k | Session session_info; |
501 | 21.5k | const bool resuming = |
502 | 21.5k | pending_state.allow_session_resumption() && |
503 | 21.5k | check_for_resume(session_info, |
504 | 20.3k | session_manager(), |
505 | 20.3k | m_creds, |
506 | 20.3k | callbacks(), |
507 | 20.3k | pending_state.client_hello(), |
508 | 20.3k | policy().session_ticket_lifetime()); |
509 | | |
510 | 21.5k | bool have_session_ticket_key = false; |
511 | | |
512 | 21.5k | try |
513 | 21.5k | { |
514 | 21.5k | have_session_ticket_key = |
515 | 21.5k | m_creds.psk("tls-server", "session-ticket", "").length() > 0; |
516 | 21.5k | } |
517 | 21.5k | catch(...) {} |
518 | | |
519 | 21.5k | m_next_protocol = ""; |
520 | 20.3k | if(pending_state.client_hello()->supports_alpn()) |
521 | 2.61k | { |
522 | 2.61k | m_next_protocol = callbacks().tls_server_choose_app_protocol(pending_state.client_hello()->next_protocols()); |
523 | 2.61k | } |
524 | | |
525 | 20.3k | if(resuming) |
526 | 0 | { |
527 | 0 | this->session_resume(pending_state, have_session_ticket_key, session_info); |
528 | 0 | } |
529 | 20.3k | else // new session |
530 | 20.3k | { |
531 | 20.3k | this->session_create(pending_state, have_session_ticket_key); |
532 | 20.3k | } |
533 | 20.3k | } |
534 | | |
535 | | void Server_Impl_12::process_certificate_msg(Server_Handshake_State& pending_state, |
536 | | const std::vector<uint8_t>& contents) |
537 | 0 | { |
538 | 0 | pending_state.client_certs(new Certificate_12(contents, policy())); |
539 | | |
540 | | // CERTIFICATE_REQUIRED would make more sense but BoGo expects handshake failure alert |
541 | 0 | if(pending_state.client_certs()->empty() && policy().require_client_certificate_authentication()) |
542 | 0 | throw TLS_Exception(Alert::HandshakeFailure, "Policy requires client send a certificate, but it did not"); |
543 | | |
544 | 0 | pending_state.set_expected_next(Handshake_Type::ClientKeyExchange); |
545 | 0 | } |
546 | | |
547 | | void Server_Impl_12::process_client_key_exchange_msg(Server_Handshake_State& pending_state, |
548 | | const std::vector<uint8_t>& contents) |
549 | 14.3k | { |
550 | 14.3k | if(pending_state.received_handshake_msg(Handshake_Type::Certificate) && !pending_state.client_certs()->empty()) |
551 | 0 | pending_state.set_expected_next(Handshake_Type::CertificateVerify); |
552 | 14.3k | else |
553 | 14.3k | pending_state.set_expected_next(Handshake_Type::HandshakeCCS); |
554 | | |
555 | 14.3k | pending_state.client_kex(new Client_Key_Exchange(contents, pending_state, |
556 | 14.3k | pending_state.server_rsa_kex_key(), |
557 | 14.3k | m_creds, policy(), rng())); |
558 | | |
559 | 14.3k | pending_state.compute_session_keys(); |
560 | 14.3k | } |
561 | | |
562 | | void Server_Impl_12::process_change_cipher_spec_msg(Server_Handshake_State& pending_state) |
563 | 580 | { |
564 | 580 | pending_state.set_expected_next(Handshake_Type::Finished); |
565 | 580 | change_cipher_spec_reader(Connection_Side::Server); |
566 | 580 | } |
567 | | |
568 | | void Server_Impl_12::process_certificate_verify_msg(Server_Handshake_State& pending_state, |
569 | | Handshake_Type type, |
570 | | const std::vector<uint8_t>& contents) |
571 | 0 | { |
572 | 0 | pending_state.client_verify(new Certificate_Verify_12(contents)); |
573 | |
|
574 | 0 | const std::vector<X509_Certificate>& client_certs = |
575 | 0 | pending_state.client_certs()->cert_chain(); |
576 | |
|
577 | 0 | if(client_certs.empty()) |
578 | 0 | throw TLS_Exception(Alert::DecodeError, "No client certificate sent"); |
579 | | |
580 | 0 | if(!client_certs[0].allowed_usage(Key_Constraints::DigitalSignature)) |
581 | 0 | throw TLS_Exception(Alert::BadCertificate, "Client certificate does not support signing"); |
582 | | |
583 | 0 | const bool sig_valid = |
584 | 0 | pending_state.client_verify()->verify(client_certs[0], pending_state, policy()); |
585 | |
|
586 | 0 | pending_state.hash().update(pending_state.handshake_io().format(contents, type)); |
587 | | |
588 | | /* |
589 | | * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for |
590 | | * "A handshake cryptographic operation failed, including being |
591 | | * unable to correctly verify a signature, ..." |
592 | | */ |
593 | 0 | if(!sig_valid) |
594 | 0 | throw TLS_Exception(Alert::DecryptError, "Client cert verify failed"); |
595 | | |
596 | 0 | try |
597 | 0 | { |
598 | 0 | const std::string sni_hostname = pending_state.client_hello()->sni_hostname(); |
599 | 0 | auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-server", sni_hostname); |
600 | |
|
601 | 0 | callbacks().tls_verify_cert_chain(client_certs, |
602 | 0 | {}, // ocsp |
603 | 0 | trusted_CAs, |
604 | 0 | Usage_Type::TLS_CLIENT_AUTH, |
605 | 0 | sni_hostname, |
606 | 0 | policy()); |
607 | 0 | } |
608 | 0 | catch(std::exception& e) |
609 | 0 | { |
610 | 0 | throw TLS_Exception(Alert::BadCertificate, e.what()); |
611 | 0 | } |
612 | | |
613 | 0 | pending_state.set_expected_next(Handshake_Type::HandshakeCCS); |
614 | 0 | } |
615 | | |
616 | | void Server_Impl_12::process_finished_msg(Server_Handshake_State& pending_state, |
617 | | Handshake_Type type, |
618 | | const std::vector<uint8_t>& contents) |
619 | 323 | { |
620 | 323 | pending_state.set_expected_next(Handshake_Type::None); |
621 | | |
622 | 323 | if(pending_state.handshake_io().have_more_data()) |
623 | 1 | throw TLS_Exception(Alert::UnexpectedMessage, |
624 | 1 | "Have data remaining in buffer after Finished"); |
625 | | |
626 | 322 | pending_state.client_finished(new Finished_12(contents)); |
627 | | |
628 | 322 | if(!pending_state.client_finished()->verify(pending_state, Connection_Side::Client)) |
629 | 0 | throw TLS_Exception(Alert::DecryptError, |
630 | 0 | "Finished message didn't verify"); |
631 | | |
632 | 322 | if(!pending_state.server_finished()) |
633 | 322 | { |
634 | | // already sent finished if resuming, so this is a new session |
635 | | |
636 | 322 | pending_state.hash().update(pending_state.handshake_io().format(contents, type)); |
637 | | |
638 | 322 | Session session_info( |
639 | 322 | pending_state.server_hello()->session_id(), |
640 | 322 | pending_state.session_keys().master_secret(), |
641 | 322 | pending_state.server_hello()->legacy_version(), |
642 | 322 | pending_state.server_hello()->ciphersuite(), |
643 | 322 | Connection_Side::Server, |
644 | 322 | pending_state.server_hello()->supports_extended_master_secret(), |
645 | 322 | pending_state.server_hello()->supports_encrypt_then_mac(), |
646 | 322 | get_peer_cert_chain(pending_state), |
647 | 322 | std::vector<uint8_t>(), |
648 | 322 | Server_Information(pending_state.client_hello()->sni_hostname()), |
649 | 322 | pending_state.server_hello()->srtp_profile(), |
650 | 322 | callbacks().tls_current_timestamp()); |
651 | | |
652 | 322 | if(save_session(session_info)) |
653 | 322 | { |
654 | 322 | if(pending_state.server_hello()->supports_session_ticket()) |
655 | 173 | { |
656 | 173 | try |
657 | 173 | { |
658 | 173 | const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", ""); |
659 | | |
660 | 173 | pending_state.new_session_ticket( |
661 | 173 | new New_Session_Ticket_12(pending_state.handshake_io(), |
662 | 173 | pending_state.hash(), |
663 | 173 | session_info.encrypt(ticket_key, rng()), |
664 | 173 | policy().session_ticket_lifetime())); |
665 | 173 | } |
666 | 173 | catch(...) {} |
667 | 173 | } |
668 | 149 | else |
669 | 149 | session_manager().save(session_info); |
670 | 322 | } |
671 | | |
672 | 322 | if(!pending_state.new_session_ticket() && |
673 | 322 | pending_state.server_hello()->supports_session_ticket()) |
674 | 0 | { |
675 | 0 | pending_state.new_session_ticket( |
676 | 0 | new New_Session_Ticket_12(pending_state.handshake_io(), pending_state.hash())); |
677 | 0 | } |
678 | | |
679 | 322 | pending_state.handshake_io().send(Change_Cipher_Spec()); |
680 | | |
681 | 322 | change_cipher_spec_writer(Connection_Side::Server); |
682 | | |
683 | 322 | pending_state.server_finished(new Finished_12(pending_state.handshake_io(), pending_state, Connection_Side::Server)); |
684 | 322 | } |
685 | | |
686 | 322 | activate_session(); |
687 | 322 | } |
688 | | |
689 | | /* |
690 | | * Process a handshake message |
691 | | */ |
692 | | void Server_Impl_12::process_handshake_msg(const Handshake_State* active_state, |
693 | | Handshake_State& state_base, |
694 | | Handshake_Type type, |
695 | | const std::vector<uint8_t>& contents, |
696 | | bool epoch0_restart) |
697 | 39.1k | { |
698 | 39.1k | Server_Handshake_State& state = dynamic_cast<Server_Handshake_State&>(state_base); |
699 | 39.1k | state.confirm_transition_to(type); |
700 | | |
701 | | /* |
702 | | * The change cipher spec message isn't technically a handshake |
703 | | * message so it's not included in the hash. The finished and |
704 | | * certificate verify messages are verified based on the current |
705 | | * state of the hash *before* this message so we delay adding them |
706 | | * to the hash computation until we've processed them below. |
707 | | */ |
708 | 39.1k | if(type != Handshake_Type::HandshakeCCS && |
709 | 39.1k | type != Handshake_Type::Finished && |
710 | 39.1k | type != Handshake_Type::CertificateVerify) |
711 | 38.0k | { |
712 | 38.0k | state.hash().update(state.handshake_io().format(contents, type)); |
713 | 38.0k | } |
714 | | |
715 | 39.1k | switch(type) |
716 | 39.1k | { |
717 | 23.7k | case Handshake_Type::ClientHello: |
718 | 23.7k | return this->process_client_hello_msg(active_state, state, contents, epoch0_restart); |
719 | | |
720 | 0 | case Handshake_Type::Certificate: |
721 | 0 | return this->process_certificate_msg(state, contents); |
722 | | |
723 | 14.3k | case Handshake_Type::ClientKeyExchange: |
724 | 14.3k | return this->process_client_key_exchange_msg(state, contents); |
725 | | |
726 | 0 | case Handshake_Type::CertificateVerify: |
727 | 0 | return this->process_certificate_verify_msg(state, type, contents); |
728 | | |
729 | 580 | case Handshake_Type::HandshakeCCS: |
730 | 580 | return this->process_change_cipher_spec_msg(state); |
731 | | |
732 | 323 | case Handshake_Type::Finished: |
733 | 323 | return this->process_finished_msg(state, type, contents); |
734 | | |
735 | 0 | default: |
736 | 0 | throw Unexpected_Message("Unknown handshake message received"); |
737 | 39.1k | } |
738 | 39.1k | } |
739 | | |
740 | | void Server_Impl_12::session_resume(Server_Handshake_State& pending_state, |
741 | | bool have_session_ticket_key, |
742 | | Session& session_info) |
743 | 0 | { |
744 | | // Only offer a resuming client a new ticket if they didn't send one this time, |
745 | | // ie, resumed via server-side resumption. TODO: also send one if expiring soon? |
746 | |
|
747 | 0 | const bool offer_new_session_ticket = |
748 | 0 | (pending_state.client_hello()->supports_session_ticket() && |
749 | 0 | pending_state.client_hello()->session_ticket().empty() && |
750 | 0 | have_session_ticket_key); |
751 | |
|
752 | 0 | pending_state.server_hello(new Server_Hello_12( |
753 | 0 | pending_state.handshake_io(), |
754 | 0 | pending_state.hash(), |
755 | 0 | policy(), |
756 | 0 | callbacks(), |
757 | 0 | rng(), |
758 | 0 | secure_renegotiation_data_for_server_hello(), |
759 | 0 | *pending_state.client_hello(), |
760 | 0 | session_info, |
761 | 0 | offer_new_session_ticket, |
762 | 0 | m_next_protocol)); |
763 | |
|
764 | 0 | secure_renegotiation_check(pending_state.server_hello()); |
765 | |
|
766 | 0 | pending_state.mark_as_resumption(); |
767 | 0 | pending_state.compute_session_keys(session_info.master_secret()); |
768 | 0 | pending_state.set_resume_certs(session_info.peer_certs()); |
769 | |
|
770 | 0 | if(!save_session(session_info)) |
771 | 0 | { |
772 | 0 | session_manager().remove_entry(session_info.session_id()); |
773 | |
|
774 | 0 | if(pending_state.server_hello()->supports_session_ticket()) // send an empty ticket |
775 | 0 | { |
776 | 0 | pending_state.new_session_ticket( |
777 | 0 | new New_Session_Ticket_12(pending_state.handshake_io(), |
778 | 0 | pending_state.hash())); |
779 | 0 | } |
780 | 0 | } |
781 | |
|
782 | 0 | if(pending_state.server_hello()->supports_session_ticket() && !pending_state.new_session_ticket()) |
783 | 0 | { |
784 | 0 | try |
785 | 0 | { |
786 | 0 | const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", ""); |
787 | |
|
788 | 0 | pending_state.new_session_ticket( |
789 | 0 | new New_Session_Ticket_12(pending_state.handshake_io(), |
790 | 0 | pending_state.hash(), |
791 | 0 | session_info.encrypt(ticket_key, rng()), |
792 | 0 | policy().session_ticket_lifetime())); |
793 | 0 | } |
794 | 0 | catch(...) {} |
795 | |
|
796 | 0 | if(!pending_state.new_session_ticket()) |
797 | 0 | { |
798 | 0 | pending_state.new_session_ticket( |
799 | 0 | new New_Session_Ticket_12(pending_state.handshake_io(), pending_state.hash())); |
800 | 0 | } |
801 | 0 | } |
802 | |
|
803 | 0 | pending_state.handshake_io().send(Change_Cipher_Spec()); |
804 | |
|
805 | 0 | change_cipher_spec_writer(Connection_Side::Server); |
806 | |
|
807 | 0 | pending_state.server_finished(new Finished_12(pending_state.handshake_io(), pending_state, Connection_Side::Server)); |
808 | 0 | pending_state.set_expected_next(Handshake_Type::HandshakeCCS); |
809 | 0 | } |
810 | | |
811 | | void Server_Impl_12::session_create(Server_Handshake_State& pending_state, |
812 | | bool have_session_ticket_key) |
813 | 20.3k | { |
814 | 20.3k | std::map<std::string, std::vector<X509_Certificate>> cert_chains; |
815 | | |
816 | 20.3k | const std::string sni_hostname = pending_state.client_hello()->sni_hostname(); |
817 | | |
818 | | // RFC 8446 1.3 |
819 | | // The "signature_algorithms_cert" extension allows a client to indicate |
820 | | // which signature algorithms it can validate in X.509 certificates. |
821 | | // |
822 | | // RFC 8446 4.2.3 |
823 | | // TLS 1.2 implementations SHOULD also process this extension. |
824 | 20.3k | const auto cert_signature_schemes = pending_state.client_hello()->certificate_signature_schemes(); |
825 | 20.3k | cert_chains = get_server_certs(sni_hostname, cert_signature_schemes, m_creds); |
826 | | |
827 | 20.3k | if(!sni_hostname.empty() && cert_chains.empty()) |
828 | 0 | { |
829 | 0 | cert_chains = get_server_certs("", cert_signature_schemes, m_creds); |
830 | | |
831 | | /* |
832 | | * Only send the unrecognized_name alert if we couldn't |
833 | | * find any certs for the requested name but did find at |
834 | | * least one cert to use in general. That avoids sending an |
835 | | * unrecognized_name when a server is configured for purely |
836 | | * anonymous/PSK operation. |
837 | | */ |
838 | 0 | if(!cert_chains.empty()) |
839 | 0 | send_warning_alert(Alert::UnrecognizedName); |
840 | 0 | } |
841 | | |
842 | 20.3k | const uint16_t ciphersuite = choose_ciphersuite(policy(), pending_state.version(), |
843 | 20.3k | cert_chains, |
844 | 20.3k | *pending_state.client_hello()); |
845 | | |
846 | 20.3k | Server_Hello_12::Settings srv_settings( |
847 | 20.3k | make_hello_random(rng(), callbacks(), policy()), // new session ID |
848 | 20.3k | pending_state.version(), |
849 | 20.3k | ciphersuite, |
850 | 20.3k | have_session_ticket_key); |
851 | | |
852 | 20.3k | pending_state.server_hello(new Server_Hello_12( |
853 | 20.3k | pending_state.handshake_io(), |
854 | 20.3k | pending_state.hash(), |
855 | 20.3k | policy(), |
856 | 20.3k | callbacks(), |
857 | 20.3k | rng(), |
858 | 20.3k | secure_renegotiation_data_for_server_hello(), |
859 | 20.3k | *pending_state.client_hello(), |
860 | 20.3k | srv_settings, |
861 | 20.3k | m_next_protocol)); |
862 | | |
863 | 20.3k | secure_renegotiation_check(pending_state.server_hello()); |
864 | | |
865 | 20.3k | const Ciphersuite& pending_suite = pending_state.ciphersuite(); |
866 | | |
867 | 20.3k | Private_Key* private_key = nullptr; |
868 | | |
869 | 20.3k | if(pending_suite.signature_used() || pending_suite.kex_method() == Kex_Algo::STATIC_RSA) |
870 | 220 | { |
871 | 220 | const std::string algo_used = |
872 | 220 | pending_suite.signature_used() ? pending_suite.sig_algo() : "RSA"; |
873 | | |
874 | 220 | BOTAN_ASSERT(!cert_chains[algo_used].empty(), |
875 | 220 | "Attempting to send empty certificate chain"); |
876 | | |
877 | 220 | pending_state.server_certs(new Certificate_12(pending_state.handshake_io(), |
878 | 220 | pending_state.hash(), |
879 | 220 | cert_chains[algo_used])); |
880 | | |
881 | 220 | if(pending_state.client_hello()->supports_cert_status_message() && pending_state.is_a_resumption() == false) |
882 | 29 | { |
883 | 29 | auto csr = pending_state.client_hello()->extensions().get<Certificate_Status_Request>(); |
884 | | // csr is non-null if client_hello()->supports_cert_status_message() |
885 | 29 | BOTAN_ASSERT_NOMSG(csr != nullptr); |
886 | 29 | const auto resp_bytes = callbacks().tls_provide_cert_status(cert_chains[algo_used], *csr); |
887 | 29 | if(!resp_bytes.empty()) |
888 | 0 | { |
889 | 0 | pending_state.server_cert_status(new Certificate_Status( |
890 | 0 | pending_state.handshake_io(), |
891 | 0 | pending_state.hash(), |
892 | 0 | resp_bytes |
893 | 0 | )); |
894 | 0 | } |
895 | 29 | } |
896 | | |
897 | 220 | private_key = m_creds.private_key_for( |
898 | 220 | pending_state.server_certs()->cert_chain()[0], |
899 | 220 | "tls-server", |
900 | 220 | sni_hostname); |
901 | | |
902 | 220 | if(!private_key) |
903 | 220 | throw Internal_Error("No private key located for associated server cert"); |
904 | 220 | } |
905 | | |
906 | 20.1k | if(pending_suite.kex_method() == Kex_Algo::STATIC_RSA) |
907 | 0 | { |
908 | 0 | pending_state.set_server_rsa_kex_key(private_key); |
909 | 0 | } |
910 | 20.1k | else |
911 | 20.1k | { |
912 | 20.1k | pending_state.server_kex(new Server_Key_Exchange(pending_state.handshake_io(), |
913 | 20.1k | pending_state, policy(), |
914 | 20.1k | m_creds, rng(), private_key)); |
915 | 20.1k | } |
916 | | |
917 | 20.1k | auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-server", sni_hostname); |
918 | | |
919 | 20.1k | std::vector<X509_DN> client_auth_CAs; |
920 | | |
921 | 20.1k | for(auto store : trusted_CAs) |
922 | 0 | { |
923 | 0 | auto subjects = store->all_subjects(); |
924 | 0 | client_auth_CAs.insert(client_auth_CAs.end(), subjects.begin(), subjects.end()); |
925 | 0 | } |
926 | | |
927 | 20.1k | const bool request_cert = |
928 | 20.1k | (client_auth_CAs.empty() == false) || |
929 | 20.1k | policy().request_client_certificate_authentication(); |
930 | | |
931 | 20.1k | if(request_cert && pending_state.ciphersuite().signature_used()) |
932 | 0 | { |
933 | 0 | pending_state.cert_req( |
934 | 0 | new Certificate_Request_12(pending_state.handshake_io(), |
935 | 0 | pending_state.hash(), |
936 | 0 | policy(), |
937 | 0 | client_auth_CAs)); |
938 | | |
939 | | /* |
940 | | SSLv3 allowed clients to skip the Certificate message entirely |
941 | | if they wanted. In TLS v1.0 and later clients must send a |
942 | | (possibly empty) Certificate message |
943 | | */ |
944 | 0 | pending_state.set_expected_next(Handshake_Type::Certificate); |
945 | 0 | } |
946 | 20.1k | else |
947 | 20.1k | { |
948 | 20.1k | pending_state.set_expected_next(Handshake_Type::ClientKeyExchange); |
949 | 20.1k | } |
950 | | |
951 | 20.1k | pending_state.server_hello_done(new Server_Hello_Done(pending_state.handshake_io(), pending_state.hash())); |
952 | 20.1k | } |
953 | | } |