Botan 3.12.0
Crypto and TLS for C&
tls_server_impl_13.cpp
Go to the documentation of this file.
1/*
2* TLS Server - implementation for TLS 1.3
3* (C) 2022 Jack Lloyd
4* 2022 René Meusel - Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/internal/tls_server_impl_13.h>
10
11#include <botan/credentials_manager.h>
12#include <botan/rng.h>
13#include <botan/tls_callbacks.h>
14#include <botan/tls_extensions_13.h>
15#include <botan/tls_policy.h>
16#include <botan/x509cert.h>
17#include <botan/internal/loadstor.h>
18#include <botan/internal/stl_util.h>
19#include <botan/internal/tls_cipher_state.h>
20
21namespace Botan::TLS {
22
23Server_Impl_13::Server_Impl_13(const std::shared_ptr<Callbacks>& callbacks,
24 const std::shared_ptr<Session_Manager>& session_manager,
25 const std::shared_ptr<Credentials_Manager>& credentials_manager,
26 const std::shared_ptr<const Policy>& policy,
27 const std::shared_ptr<RandomNumberGenerator>& rng) :
29 m_handshake(std::make_unique<Pending_Handshake>()) {
30#if defined(BOTAN_HAS_TLS_12)
31 if(policy->allow_tls12()) {
32 expect_downgrade({}, {});
33 }
34#endif
35
36 m_handshake->transitions.set_expected_next(Handshake_Type::ClientHello);
37}
38
40 if(m_active_state.has_value()) {
41 return m_active_state->application_protocol();
42 }
43
44 return "";
45}
46
47std::vector<X509_Certificate> Server_Impl_13::peer_cert_chain() const {
48 if(m_active_state.has_value()) {
49 return m_active_state->peer_certs();
50 }
51
52 if(m_handshake) {
53 if(m_handshake->state.has_client_certificate_msg() &&
54 m_handshake->state.client_certificate().has_certificate_chain()) {
55 return m_handshake->state.client_certificate().cert_chain();
56 }
57
58 if(m_handshake->resumed_session.has_value()) {
59 return m_handshake->resumed_session->peer_certs();
60 }
61 }
62
63 return {};
64}
65
66std::shared_ptr<const Public_Key> Server_Impl_13::peer_raw_public_key() const {
67 if(m_active_state.has_value()) {
68 return m_active_state->peer_raw_public_key();
69 }
70
71 if(m_handshake) {
72 if(m_handshake->state.has_client_certificate_msg() &&
73 m_handshake->state.client_certificate().is_raw_public_key()) {
74 return m_handshake->state.client_certificate().public_key();
75 }
76
77 if(m_handshake->resumed_session.has_value()) {
78 return m_handshake->resumed_session->peer_raw_public_key();
79 }
80 }
81
82 return nullptr;
83}
84
85std::optional<std::string> Server_Impl_13::external_psk_identity() const {
86 if(m_active_state.has_value()) {
87 return m_active_state->psk_identity();
88 } else if(m_handshake) {
89 return m_handshake->psk_identity;
90 } else {
91 return std::nullopt;
92 }
93}
94
96 // RFC 8446 4.2.9
97 // This extension also restricts the modes for use with PSK resumption.
98 // Servers SHOULD NOT send NewSessionTicket with tickets that are not
99 // compatible with the advertised modes; however, if a server does so,
100 // the impact will just be that the client's attempts at resumption fail.
101 //
102 // Note: Applications can overrule this by calling send_new_session_tickets()
103 // regardless of this method indicating no support for tickets.
104 //
105 // TODO: Implement other PSK KE modes than PSK_DHE_KE
106 return is_handshake_complete() && m_active_state.has_value() && m_active_state->peer_supports_psk_dhe_ke();
107}
108
109size_t Server_Impl_13::send_new_session_tickets(const size_t tickets) {
112
113 if(tickets == 0) {
114 return 0;
115 }
116
117 auto flight = aggregate_post_handshake_messages();
118 size_t tickets_created = 0;
119
121
122 for(size_t i = 0; i < tickets; ++i) {
123 auto nonce = m_cipher_state->next_ticket_nonce();
124 const uint32_t ticket_age_add = load_be(rng().random_array<4>());
125 const Session session(m_cipher_state->psk(nonce),
126 std::nullopt, // early data not yet implemented
127 ticket_age_add,
128 policy().session_ticket_lifetime(),
129 m_active_state->version(),
130 m_active_state->ciphersuite_code(),
134 Server_Information(m_active_state->sni_hostname()),
135 callbacks().tls_current_timestamp());
136
137 if(callbacks().tls_should_persist_resumption_information(session)) {
138 if(auto handle = session_manager().establish(session)) {
139 flight.add(New_Session_Ticket_13(std::move(nonce), session, handle.value(), callbacks()));
140 ++tickets_created;
141 }
142 }
143 }
144
145 if(flight.contains_messages()) {
146 flight.send();
147 }
148
149 return tickets_created;
150}
151
152void Server_Impl_13::process_handshake_msg(Handshake_Message_13 message) {
153 BOTAN_STATE_CHECK(m_handshake != nullptr);
154
155 std::visit(
156 [&](auto msg) {
157 // first verify that the message was expected by the state machine...
158 m_handshake->transitions.confirm_transition_to(msg.get().type());
159
160 // ... then allow the library user to abort on their discretion
161 callbacks().tls_inspect_handshake_msg(msg.get());
162
163 // ... finally handle the message
164 handle(msg.get());
165 },
166 m_handshake->state.received(std::move(message)));
167}
168
169void Server_Impl_13::process_post_handshake_msg(Post_Handshake_Message_13 message) {
170 BOTAN_STATE_CHECK(is_handshake_complete());
171
172 const auto msg = specialize_to<Client_Post_Handshake_13_Message>(std::move(message));
173 if(!msg) {
174 throw TLS_Exception(Alert::UnexpectedMessage, "Received an unexpected post-handshake message");
175 }
176
177 std::visit([&](auto&& m) { handle(m); }, *msg);
178}
179
180void Server_Impl_13::process_dummy_change_cipher_spec() {
181 // RFC 8446 5.
182 // If an implementation detects a change_cipher_spec record received before
183 // the first ClientHello message or after the peer's Finished message, it MUST be
184 // treated as an unexpected record type [("unexpected_message" alert)].
185 if(!m_handshake || !m_handshake->state.has_client_hello() || m_handshake->state.has_client_finished()) {
186 throw TLS_Exception(Alert::UnexpectedMessage, "Received an unexpected dummy Change Cipher Spec");
187 }
188
189 // RFC 8446 5.
190 // An implementation may receive an unencrypted record of type change_cipher_spec [...]
191 // at any time after the first ClientHello message has been sent or received
192 // and before the peer's Finished message has been received [...]
193 // and MUST simply drop it without further processing.
194 //
195 // ... no further processing.
196}
197
199 return m_active_state.has_value() || (m_handshake != nullptr && m_handshake->state.has_client_finished());
200}
201
202void Server_Impl_13::maybe_log_secret(std::string_view label, std::span<const uint8_t> secret) const {
203 if(policy().allow_ssl_key_log_file()) {
204 if(m_active_state.has_value()) {
205 callbacks().tls_ssl_key_log_data(label, m_active_state->client_random(), secret);
206 } else {
207 callbacks().tls_ssl_key_log_data(label, m_handshake->state.client_hello().random(), secret);
208 }
209 }
210}
211
212void Server_Impl_13::downgrade() {
213 BOTAN_ASSERT_NOMSG(expects_downgrade());
214
215 request_downgrade();
216
217 // After this, no further messages are expected here because this instance
218 // will be replaced by a Server_Impl_12.
219 m_handshake->transitions.set_expected_next({});
220}
221
222void Server_Impl_13::maybe_handle_compatibility_mode() {
223 BOTAN_ASSERT_NOMSG(m_handshake->state.has_client_hello());
224 BOTAN_ASSERT_NOMSG(m_handshake->state.has_hello_retry_request() || m_handshake->state.has_server_hello());
225
226 // RFC 8446 Appendix D.4 (Middlebox Compatibility Mode)
227 // The server sends a dummy change_cipher_spec record immediately after
228 // its first handshake message. This may either be after a ServerHello or
229 // a HelloRetryRequest.
230 //
231 // This "compatibility mode" is partially negotiated: the client can opt
232 // to provide a session ID or not, and the server has to echo it. Either
233 // side can send change_cipher_spec at any time during the handshake, as
234 // they must be ignored by the peer, but if the client sends a non-empty
235 // session ID, the server MUST send the change_cipher_spec as described
236 // [above].
237 //
238 // Technically, the usage of compatibility mode is fully up to the client
239 // sending a non-empty session ID. Nevertheless, when the policy requests
240 // it we send a CCS regardless. Note that this is perfectly legal and also
241 // satisfies some BoGo tests that expect this behaviour.
242 //
243 // Send a CCS immediately after the _first_ handshake message. I.e. either
244 // after Hello Retry Request (exclusively) or after a Server Hello that was
245 // not preseded by a Hello Retry Request.
246 const bool just_after_first_handshake_message =
247 m_handshake->state.has_hello_retry_request() ^ m_handshake->state.has_server_hello();
248 const bool client_requested_compatibility_mode = !m_handshake->state.client_hello().session_id().empty();
249
250 if(just_after_first_handshake_message &&
251 (policy().tls_13_middlebox_compatibility_mode() || client_requested_compatibility_mode)) {
252 send_dummy_change_cipher_spec();
253 }
254}
255
256void Server_Impl_13::handle_reply_to_client_hello(Server_Hello_13 server_hello) {
257 const auto& client_hello = m_handshake->state.client_hello();
258 const auto& exts = client_hello.extensions();
259
260 const bool uses_psk = server_hello.extensions().has<PSK>();
261
262 const auto cipher_opt = Ciphersuite::by_id(server_hello.ciphersuite());
263 BOTAN_ASSERT_NOMSG(cipher_opt.has_value());
264 const auto& cipher = cipher_opt.value();
265 m_transcript_hash.set_algorithm(cipher.prf_algo());
266
267 std::unique_ptr<Cipher_State> psk_cipher_state;
268 if(uses_psk) {
269 auto* psk_extension = server_hello.extensions().get<PSK>();
270
271 psk_cipher_state = std::visit(
272 overloaded{[&, this](Session session) {
273 m_handshake->resumed_session = std::move(session);
274 return Cipher_State::init_with_psk(Connection_Side::Server,
275 Cipher_State::PSK_Type::Resumption,
276 m_handshake->resumed_session->extract_master_secret(),
277 cipher.prf_algo());
278 },
279 [&, this](ExternalPSK psk) {
280 m_handshake->psk_identity = psk.identity();
281 const auto psk_type =
282 psk.is_imported() ? Cipher_State::PSK_Type::Imported : Cipher_State::PSK_Type::External;
283 return Cipher_State::init_with_psk(
284 Connection_Side::Server, psk_type, psk.extract_master_secret(), cipher.prf_algo());
285 }},
286 psk_extension->take_session_to_resume_or_psk());
287
288 // RFC 8446 4.2.11
289 // Prior to accepting PSK key establishment, the server MUST validate
290 // the corresponding binder value (see Section 4.2.11.2 below). If this
291 // value is not present or does not validate, the server MUST abort the
292 // handshake.
293 // Servers SHOULD NOT attempt to validate multiple binders; rather,
294 // they SHOULD select a single PSK and validate solely the binder that
295 // corresponds to that PSK.
296 //
297 // Note: PSK selection was performed earlier, resulting in the existence
298 // of this extension in the first place.
299 if(!exts.get<PSK>()->validate_binder(*psk_extension,
300 psk_cipher_state->psk_binder_mac(m_transcript_hash.truncated()))) {
301 throw TLS_Exception(Alert::DecryptError, "PSK binder does not check out");
302 }
303
304 // RFC 8446 4.2.10
305 // For PSKs provisioned via NewSessionTicket, a server MUST validate
306 // that the ticket age for the selected PSK identity [...] is within a
307 // small tolerance of the time since the ticket was issued. If it is
308 // not, the server SHOULD proceed with the handshake but reject 0-RTT,
309 // and SHOULD NOT take any other action that assumes that this
310 // ClientHello is fresh.
311 //
312 // TODO: When implementing Early Data (0-RTT) we should take the above
313 // paragraph into account. Note that there are BoGo tests that
314 // validate this behaviour. Namely: TLS13-TicketAgeSkew-*
315 }
316
317 // This sends the server_hello to the peer.
318 // NOTE: the server_hello variable is moved into the handshake state. Later
319 // references to the Server Hello will need to consult the handshake
320 // state object!
321 send_handshake_message(m_handshake->state.sending(std::move(server_hello)));
322 maybe_handle_compatibility_mode();
323
324 // Setup encryption for all the remaining handshake messages
325 m_cipher_state = [&] {
326 // Currently, PSK without DHE is not implemented...
327 auto* const my_keyshare = m_handshake->state.server_hello().extensions().get<Key_Share>();
328 BOTAN_ASSERT_NONNULL(my_keyshare);
329
330 if(uses_psk) {
331 BOTAN_ASSERT_NONNULL(psk_cipher_state);
332 psk_cipher_state->advance_with_client_hello(m_transcript_hash.previous(), *this);
333 psk_cipher_state->advance_with_server_hello(
334 cipher, my_keyshare->take_shared_secret(), m_transcript_hash.current(), *this);
335
336 return std::move(psk_cipher_state);
337 } else {
338 return Cipher_State::init_with_server_hello(
339 m_side, my_keyshare->take_shared_secret(), cipher, m_transcript_hash.current(), *this);
340 }
341 }();
342
343 // Decide up front whether we will request client authentication so the
344 // EncryptedExtensions can attach client_certificate_type when applicable
345 // (RFC 7250 4.2 requires the two messages to agree).
346 auto certificate_request =
347 uses_psk ? std::nullopt
348 : Certificate_Request_13::maybe_create(client_hello, credentials_manager(), callbacks(), policy());
349
350 auto flight = aggregate_handshake_messages();
351 const bool is_resumption = m_handshake->resumed_session.has_value();
352 const bool requesting_client_auth = certificate_request.has_value();
353
354 flight.add(m_handshake->state.sending(
355 Encrypted_Extensions(client_hello, policy(), callbacks(), is_resumption, requesting_client_auth)));
356
357 if(!uses_psk) {
358 // RFC 8446 4.3.2
359 // A server which is authenticating with a certificate MAY optionally
360 // request a certificate from the client. This message, if sent, MUST
361 // follow EncryptedExtensions.
362 if(certificate_request.has_value()) {
363 flight.add(m_handshake->state.sending(std::move(certificate_request.value())));
364 }
365
366 const auto& enc_exts = m_handshake->state.encrypted_extensions().extensions();
367
368 // RFC 7250 4.2
369 // This client_certificate_type extension in the server hello then
370 // indicates the type of certificates the client is requested to provide
371 // in a subsequent certificate payload.
372 //
373 // Note: TLS 1.3 carries this extension in the Encrypted Extensions
374 // message instead of the Server Hello.
375 if(auto* client_cert_type = enc_exts.get<Client_Certificate_Type>()) {
376 set_selected_certificate_type(client_cert_type->selected_certificate_type());
377 }
378
379 // RFC 8446 4.4.2
380 // If the corresponding certificate type extension [...] was not
381 // negotiated in EncryptedExtensions, or the X.509 certificate type
382 // was negotiated, then each CertificateEntry contains a DER-encoded
383 // X.509 certificate.
384 const auto cert_type = [&] {
385 if(auto* server_cert_type = enc_exts.get<Server_Certificate_Type>()) {
386 return server_cert_type->selected_certificate_type();
387 } else {
388 return Certificate_Type::X509;
389 }
390 }();
391
392 flight
393 .add(m_handshake->state.sending(Certificate_13(client_hello, credentials_manager(), callbacks(), cert_type)))
394 .add(m_handshake->state.sending(Certificate_Verify_13(m_handshake->state.server_certificate(),
395 client_hello.signature_schemes(),
396 client_hello.sni_hostname(),
397 m_transcript_hash.current(),
398 Connection_Side::Server,
399 credentials_manager(),
400 policy(),
401 callbacks(),
402 rng())));
403 }
404
405 flight.add(m_handshake->state.sending(Finished_13(m_cipher_state.get(), m_transcript_hash.current())));
406
407 if(client_hello.extensions().has<Record_Size_Limit>() &&
408 m_handshake->state.encrypted_extensions().extensions().has<Record_Size_Limit>()) {
409 // RFC 8449 4.
410 // When the "record_size_limit" extension is negotiated, an endpoint
411 // MUST NOT generate a protected record with plaintext that is larger
412 // than the RecordSizeLimit value it receives from its peer.
413 // Unprotected messages are not subject to this limit.
414 //
415 // Hence, the limit is set just before we start sending encrypted records.
416 //
417 // RFC 8449 4.
418 // The record size limit only applies to records sent toward the
419 // endpoint that advertises the limit. An endpoint can send records
420 // that are larger than the limit it advertises as its own limit.
421 //
422 // Hence, the "outgoing" limit is what the client requested and the
423 // "incoming" limit is what we will request in the Encrypted Extensions.
424 auto* const outgoing_limit = client_hello.extensions().get<Record_Size_Limit>();
425 auto* const incoming_limit = m_handshake->state.encrypted_extensions().extensions().get<Record_Size_Limit>();
426 set_record_size_limits(outgoing_limit->limit(), incoming_limit->limit());
427 }
428
429 flight.send();
430
431 m_cipher_state->advance_with_server_finished(m_transcript_hash.current(), *this);
432
433 if(m_handshake->state.has_certificate_request()) {
434 // RFC 8446 4.4.2
435 // The client MUST send a Certificate message if and only if the server
436 // has requested client authentication via a CertificateRequest message
437 // [...]. If the server requests client authentication but no
438 // suitable certificate is available, the client MUST send a Certificate
439 // message containing no certificates [...].
440 m_handshake->transitions.set_expected_next(Handshake_Type::Certificate);
441 } else {
442 m_handshake->transitions.set_expected_next(Handshake_Type::Finished);
443 }
444}
445
446void Server_Impl_13::handle_reply_to_client_hello(Hello_Retry_Request hello_retry_request) {
447 auto cipher = Ciphersuite::by_id(hello_retry_request.ciphersuite());
448 BOTAN_ASSERT_NOMSG(cipher.has_value()); // should work, since we chose that suite
449
450 send_handshake_message(m_handshake->state.sending(std::move(hello_retry_request)));
451 maybe_handle_compatibility_mode();
452
453 m_transcript_hash = Transcript_Hash_State::recreate_after_hello_retry_request(cipher->prf_algo(), m_transcript_hash);
454
455 m_handshake->transitions.set_expected_next(Handshake_Type::ClientHello);
456}
457
458void Server_Impl_13::handle(const Client_Hello_12_Shim& ch) {
459 // The detailed handling of the TLS 1.2 compliant Client Hello is left to
460 // the TLS 1.2 server implementation.
461 BOTAN_UNUSED(ch);
462 BOTAN_ASSERT_NONNULL(m_handshake);
463
464 // After we sent a Hello Retry Request we must not accept a downgrade.
465 if(m_handshake->state.has_hello_retry_request()) {
466 throw TLS_Exception(Alert::UnexpectedMessage, "Received a TLS 1.2 Client Hello after Hello Retry Request");
467 }
468
469 // RFC 8446 Appendix D.2
470 // If the "supported_versions" extension is absent and the server only
471 // supports versions greater than ClientHello.legacy_version, the server
472 // MUST abort the handshake with a "protocol_version" alert.
473 //
474 // If we're not expecting a downgrade, we only support TLS 1.3.
475 if(!expects_downgrade()) {
476 throw TLS_Exception(Alert::ProtocolVersion, "Received a legacy Client Hello");
477 }
478
479 downgrade();
480}
481
482void Server_Impl_13::handle(const Client_Hello_13& client_hello) {
483 BOTAN_ASSERT_NONNULL(m_handshake);
484
485 const auto& exts = client_hello.extensions();
486
487 const bool is_initial_client_hello = !m_handshake->state.has_hello_retry_request();
488
489 if(is_initial_client_hello) {
490 const auto preferred_version = client_hello.highest_supported_version(policy());
491 if(!preferred_version) {
492 throw TLS_Exception(Alert::ProtocolVersion, "No shared TLS version");
493 }
494
495 // RFC 8446 4.2.2
496 // Clients MUST NOT use cookies in their initial ClientHello in subsequent
497 // connections.
498 if(exts.has<Cookie>()) {
499 throw TLS_Exception(Alert::IllegalParameter, "Received a Cookie in the initial client hello");
500 }
501 }
502
503 // TODO: Implement support for PSK. For now, we ignore any such extensions
504 // and always revert to a standard key exchange.
505 if(!exts.has<Supported_Groups>()) {
506 throw Not_Implemented("PSK-only handshake NYI");
507 }
508
509 // RFC 8446 9.2
510 // If containing a "supported_groups" extension, [Client Hello] MUST
511 // also contain a "key_share" extension, and vice versa.
512 //
513 // This was validated before in the Client_Hello_13 constructor.
514 BOTAN_ASSERT_NOMSG(exts.has<Key_Share>());
515
516 if(!is_initial_client_hello) {
517 const auto& hrr_exts = m_handshake->state.hello_retry_request().extensions();
518 const auto offered_groups = exts.get<Key_Share>()->offered_groups();
519 const auto* hrr_key_share = hrr_exts.get<Key_Share>();
520 BOTAN_ASSERT_NONNULL(hrr_key_share);
521 const auto selected_group = hrr_key_share->selected_group();
522 if(offered_groups.size() != 1 || offered_groups.at(0) != selected_group) {
523 throw TLS_Exception(Alert::IllegalParameter, "Client did not comply with the requested key exchange group");
524 }
525 }
526
527 callbacks().tls_examine_extensions(exts, Connection_Side::Client, client_hello.type());
528 std::visit([this](auto msg) { handle_reply_to_client_hello(std::move(msg)); },
529 Server_Hello_13::create(client_hello,
530 is_initial_client_hello,
531 session_manager(),
532 credentials_manager(),
533 rng(),
534 policy(),
535 callbacks()));
536}
537
538void Server_Impl_13::handle(const Certificate_13& certificate_msg) {
539 BOTAN_ASSERT_NONNULL(m_handshake);
540
541 // RFC 8446 4.3.2
542 // certificate_request_context: [...] This field SHALL be zero length
543 // unless used for the post-handshake authentication exchanges [...].
544 if(!is_handshake_complete() && !certificate_msg.request_context().empty()) {
545 throw TLS_Exception(Alert::DecodeError, "Received a client certificate message with non-empty request context");
546 }
547
548 // RFC 8446 4.4.2
549 // Extensions in the Certificate message from the client MUST correspond
550 // to extensions in the CertificateRequest message from the server.
551 certificate_msg.validate_extensions(m_handshake->state.certificate_request().extensions().extension_types(),
552 callbacks());
553
554 // RFC 8446 4.4.2.4
555 // If the client does not send any certificates (i.e., it sends an empty
556 // Certificate message), the server MAY at its discretion either continue
557 // the handshake without client authentication or abort the handshake with
558 // a "certificate_required" alert.
559 if(certificate_msg.empty()) {
560 if(policy().require_client_certificate_authentication()) {
561 throw TLS_Exception(Alert::CertificateRequired, "Policy requires client send a certificate, but it did not");
562 }
563
564 // RFC 8446 4.4.2
565 // A Finished message MUST be sent regardless of whether the
566 // Certificate message is empty.
567 m_handshake->transitions.set_expected_next(Handshake_Type::Finished);
568 } else {
569 // RFC 8446 4.4.2.4
570 // [...], if some aspect of the certificate chain was unacceptable
571 // (e.g., it was not signed by a known, trusted CA), the server MAY at
572 // its discretion either continue the handshake (considering the client
573 // unauthenticated) or abort the handshake.
574 //
575 // TODO: We could make this dependent on Policy::require_client_auth().
576 // Though, apps may also override Callbacks::tls_verify_cert_chain()
577 // and 'ignore' validation issues to a certain extent.
578
579 const bool use_ocsp = m_handshake->state.certificate_request().extensions().has<Certificate_Status_Request>();
580 certificate_msg.verify(
581 callbacks(), policy(), credentials_manager(), m_handshake->state.client_hello().sni_hostname(), use_ocsp);
582
583 // RFC 8446 4.4.3
584 // Clients MUST send this message whenever authenticating via a
585 // certificate (i.e., when the Certificate message
586 // is non-empty). When sent, this message MUST appear immediately after
587 // the Certificate message [...].
588 m_handshake->transitions.set_expected_next(Handshake_Type::CertificateVerify);
589 }
590}
591
592void Server_Impl_13::handle(const Certificate_Verify_13& certificate_verify_msg) {
593 BOTAN_ASSERT_NONNULL(m_handshake);
594
595 // RFC 8446 4.4.3
596 // If sent by a client, the signature algorithm used in the signature
597 // MUST be one of those present in the supported_signature_algorithms
598 // field of the "signature_algorithms" extension in the
599 // CertificateRequest message.
600 const auto offered = m_handshake->state.certificate_request().signature_schemes();
601 if(!value_exists(offered, certificate_verify_msg.signature_scheme())) {
602 throw TLS_Exception(Alert::IllegalParameter,
603 "We did not offer the usage of " + certificate_verify_msg.signature_scheme().to_string() +
604 " as a signature scheme");
605 }
606
607 BOTAN_ASSERT_NOMSG(m_handshake->state.has_client_certificate_msg() &&
608 !m_handshake->state.client_certificate().empty());
609 const bool sig_valid = certificate_verify_msg.verify(
610 *m_handshake->state.client_certificate().public_key(), callbacks(), m_transcript_hash.previous());
611
612 // RFC 8446 4.4.3
613 // If the verification fails, the receiver MUST terminate the handshake
614 // with a "decrypt_error" alert.
615 if(!sig_valid) {
616 throw TLS_Exception(Alert::DecryptError, "Client certificate verification failed");
617 }
618
619 m_handshake->transitions.set_expected_next(Handshake_Type::Finished);
620}
621
622void Server_Impl_13::handle(const Finished_13& finished_msg) {
623 BOTAN_ASSERT_NONNULL(m_handshake);
624
625 // RFC 8446 4.4.4
626 // Recipients of Finished messages MUST verify that the contents are
627 // correct and if incorrect MUST terminate the connection with a
628 // "decrypt_error" alert.
629 if(!finished_msg.verify(m_cipher_state.get(), m_transcript_hash.previous())) {
630 throw TLS_Exception(Alert::DecryptError, "Finished message didn't verify");
631 }
632
633 m_handshake->state.confirm_peer_finished_verified();
634
635 // Give the application a chance for a final veto before fully
636 // establishing the connection.
637 callbacks().tls_session_established(
638 Session_Summary(m_handshake->state.server_hello(),
639 Connection_Side::Server,
640 peer_cert_chain(),
641 peer_raw_public_key(),
642 m_handshake->psk_identity,
643 m_handshake->resumed_session.has_value(),
644 Server_Information(m_handshake->state.client_hello().sni_hostname()),
645 callbacks().tls_current_timestamp()));
646
647 m_cipher_state->advance_with_client_finished(m_transcript_hash.current());
648
649 // no more handshake messages expected
650 m_handshake->transitions.set_expected_next({});
651
652 // Extract post-handshake state before signaling activation.
653 {
654 auto extract_certs = [&]() -> std::vector<X509_Certificate> {
655 if(m_handshake->state.has_client_certificate_msg() &&
656 m_handshake->state.client_certificate().has_certificate_chain()) {
657 return m_handshake->state.client_certificate().cert_chain();
658 }
659 if(m_handshake->resumed_session.has_value()) {
660 return m_handshake->resumed_session->peer_certs();
661 }
662 return {};
663 };
664
665 auto extract_raw_pk = [&]() -> std::shared_ptr<const Public_Key> {
666 if(m_handshake->state.has_client_certificate_msg() &&
667 m_handshake->state.client_certificate().is_raw_public_key()) {
668 return m_handshake->state.client_certificate().public_key();
669 }
670 if(m_handshake->resumed_session.has_value()) {
671 return m_handshake->resumed_session->peer_raw_public_key();
672 }
673 return nullptr;
674 };
675
676 const bool supports_psk_dhe =
677 m_handshake->state.client_hello().extensions().has<PSK_Key_Exchange_Modes>() &&
678 value_exists(m_handshake->state.client_hello().extensions().get<PSK_Key_Exchange_Modes>()->modes(),
679 PSK_Key_Exchange_Mode::PSK_DHE_KE);
680
681 m_active_state = Active_Connection_State_13(m_handshake->state,
682 extract_certs(),
683 extract_raw_pk(),
684 m_handshake->psk_identity,
685 m_handshake->state.client_hello().sni_hostname(),
686 supports_psk_dhe);
687 }
688
689 m_handshake.reset();
690 m_transcript_hash = Transcript_Hash_State();
691 callbacks().tls_session_activated();
692
693 if(new_session_ticket_supported()) {
694 send_new_session_tickets(policy().new_session_tickets_upon_handshake_success());
695 }
696}
697
698} // namespace Botan::TLS
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
const Policy & policy() const
AggregatedPostHandshakeMessages aggregate_post_handshake_messages()
Credentials_Manager & credentials_manager()
RandomNumberGenerator & rng()
std::optional< Active_Connection_State_13 > m_active_state
Channel_Impl_13(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server)
Session_Manager & session_manager()
std::unique_ptr< Cipher_State > m_cipher_state
std::vector< X509_Certificate > peer_cert_chain() const override
size_t send_new_session_tickets(size_t tickets) override
std::optional< std::string > external_psk_identity() const override
std::shared_ptr< const Public_Key > peer_raw_public_key() const override
bool is_handshake_complete() const override
std::string application_protocol() const override
bool new_session_ticket_supported() const override
Server_Impl_13(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< const Policy > &policy, const std::shared_ptr< RandomNumberGenerator > &rng)
std::variant< Client_Hello_13, Client_Hello_12_Shim, Server_Hello_13, Server_Hello_12_Shim, Hello_Retry_Request, Encrypted_Extensions, Certificate_13, Certificate_Request_13, Certificate_Verify_13, Finished_13 > Handshake_Message_13
constexpr std::optional< SpecificVariantT > specialize_to(GeneralVariantT &&v)
Converts a given variant into another variant whose type states are a subset of the given variant.
Definition stl_util.h:117
bool value_exists(const std::vector< T > &vec, const V &val)
Definition stl_util.h:44
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504