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