Botan 2.19.1
Crypto and TLS for C&
tls_client.cpp
Go to the documentation of this file.
1/*
2* TLS Client
3* (C) 2004-2011,2012,2015,2016 Jack Lloyd
4* 2016 Matthias Gierlings
5* 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/tls_client.h>
11#include <botan/tls_messages.h>
12#include <botan/internal/tls_handshake_state.h>
13#include <botan/internal/stl_util.h>
14#include <iterator>
15#include <sstream>
16
17namespace Botan {
18
19namespace TLS {
20
21namespace {
22
23class Client_Handshake_State final : public Handshake_State
24 {
25 public:
26 Client_Handshake_State(Handshake_IO* io, Callbacks& cb) :
27 Handshake_State(io, cb),
28 m_is_reneg(false)
29 {}
30
31 const Public_Key& get_server_public_key() const
32 {
33 BOTAN_ASSERT(server_public_key, "Server sent us a certificate");
34 return *server_public_key.get();
35 }
36
37 bool is_a_resumption() const { return (resumed_session != nullptr); }
38
39 bool is_a_renegotiation() const { return m_is_reneg; }
40
41 const secure_vector<uint8_t>& resume_master_secret() const
42 {
43 BOTAN_STATE_CHECK(is_a_resumption());
44 return resumed_session->master_secret();
45 }
46
47 const std::vector<X509_Certificate>& resume_peer_certs() const
48 {
49 BOTAN_STATE_CHECK(is_a_resumption());
50 return resumed_session->peer_certs();
51 }
52
53 std::unique_ptr<Public_Key> server_public_key;
54 // Used during session resumption
55 std::unique_ptr<Session> resumed_session;
56 bool m_is_reneg = false;
57 };
58
59}
60
61/*
62* TLS Client Constructor
63*/
65 Session_Manager& session_manager,
67 const Policy& policy,
69 const Server_Information& info,
70 const Protocol_Version& offer_version,
71 const std::vector<std::string>& next_protos,
72 size_t io_buf_sz) :
73 Channel(callbacks, session_manager, rng, policy,
74 false, offer_version.is_datagram_protocol(), io_buf_sz),
75 m_creds(creds),
76 m_info(info)
77 {
78 init(offer_version, next_protos);
79 }
80
82 data_cb proc_cb,
83 alert_cb recv_alert_cb,
84 handshake_cb hs_cb,
85 Session_Manager& session_manager,
87 const Policy& policy,
89 const Server_Information& info,
90 const Protocol_Version& offer_version,
91 const std::vector<std::string>& next_protos,
92 size_t io_buf_sz) :
93 Channel(data_output_fn, proc_cb, recv_alert_cb, hs_cb, Channel::handshake_msg_cb(),
94 session_manager, rng, policy, false, offer_version.is_datagram_protocol(), io_buf_sz),
95 m_creds(creds),
96 m_info(info)
97 {
98 init(offer_version, next_protos);
99 }
100
102 data_cb proc_cb,
103 alert_cb recv_alert_cb,
104 handshake_cb hs_cb,
105 handshake_msg_cb hs_msg_cb,
106 Session_Manager& session_manager,
107 Credentials_Manager& creds,
108 const Policy& policy,
110 const Server_Information& info,
111 const Protocol_Version& offer_version,
112 const std::vector<std::string>& next_protos) :
113 Channel(data_output_fn, proc_cb, recv_alert_cb, hs_cb, hs_msg_cb,
114 session_manager, rng, policy, false, offer_version.is_datagram_protocol()),
115 m_creds(creds),
116 m_info(info)
117 {
118 init(offer_version, next_protos);
119 }
120
121void Client::init(const Protocol_Version& protocol_version,
122 const std::vector<std::string>& next_protocols)
123 {
124 const std::string srp_identifier = m_creds.srp_identifier("tls-client", m_info.hostname());
125
126 Handshake_State& state = create_handshake_state(protocol_version);
127 send_client_hello(state, false, protocol_version,
128 srp_identifier, next_protocols);
129 }
130
131Handshake_State* Client::new_handshake_state(Handshake_IO* io)
132 {
133 return new Client_Handshake_State(io, callbacks());
134 }
135
136std::vector<X509_Certificate>
137Client::get_peer_cert_chain(const Handshake_State& state) const
138 {
139 const Client_Handshake_State& cstate = dynamic_cast<const Client_Handshake_State&>(state);
140
141 if(cstate.is_a_resumption())
142 return cstate.resume_peer_certs();
143
144 if(state.server_certs())
145 return state.server_certs()->cert_chain();
146 return std::vector<X509_Certificate>();
147 }
148
149/*
150* Send a new client hello to renegotiate
151*/
152void Client::initiate_handshake(Handshake_State& state,
153 bool force_full_renegotiation)
154 {
155 send_client_hello(state, force_full_renegotiation,
156 policy().latest_supported_version(state.version().is_datagram_protocol()));
157 }
158
159void Client::send_client_hello(Handshake_State& state_base,
160 bool force_full_renegotiation,
161 Protocol_Version version,
162 const std::string& srp_identifier,
163 const std::vector<std::string>& next_protocols)
164 {
165 Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
166
167 if(state.version().is_datagram_protocol())
168 state.set_expected_next(HELLO_VERIFY_REQUEST); // optional
169 state.set_expected_next(SERVER_HELLO);
170
171 if(!force_full_renegotiation && !m_info.empty())
172 {
173 std::unique_ptr<Session> session_info(new Session);;
174 if(session_manager().load_from_server_info(m_info, *session_info))
175 {
176 /*
177 Ensure that the session protocol cipher and version are acceptable
178 If not skip the resume and establish a new session
179 */
180 const bool exact_version = session_info->version() == version;
181 const bool ok_version =
182 (session_info->version().is_datagram_protocol() == version.is_datagram_protocol()) &&
183 policy().acceptable_protocol_version(session_info->version());
184
185 const bool session_version_ok = policy().only_resume_with_exact_version() ? exact_version : ok_version;
186
187 if(policy().acceptable_ciphersuite(session_info->ciphersuite()) && session_version_ok)
188 {
189 if(srp_identifier == "" || session_info->srp_identifier() == srp_identifier)
190 {
191 state.client_hello(
192 new Client_Hello(state.handshake_io(),
193 state.hash(),
194 policy(),
195 callbacks(),
196 rng(),
198 *session_info,
199 next_protocols));
200
201 state.resumed_session = std::move(session_info);
202 }
203 }
204 }
205 }
206
207 if(!state.client_hello()) // not resuming
208 {
209 Client_Hello::Settings client_settings(version, m_info.hostname(), srp_identifier);
210 state.client_hello(new Client_Hello(
211 state.handshake_io(),
212 state.hash(),
213 policy(),
214 callbacks(),
215 rng(),
217 client_settings,
218 next_protocols));
219 }
220
221 secure_renegotiation_check(state.client_hello());
222 }
223
224namespace {
225
226bool key_usage_matches_ciphersuite(Key_Constraints usage,
227 const Ciphersuite& suite)
228 {
229 if(usage == NO_CONSTRAINTS)
230 return true; // anything goes ...
231
232 if(suite.kex_method() == Kex_Algo::STATIC_RSA)
233 {
234 return (usage & KEY_ENCIPHERMENT) | (usage & DATA_ENCIPHERMENT);
235 }
236 else
237 {
238 return (usage & DIGITAL_SIGNATURE) | (usage & NON_REPUDIATION);
239 }
240 }
241
242}
243
244/*
245* Process a handshake message
246*/
247void Client::process_handshake_msg(const Handshake_State* active_state,
248 Handshake_State& state_base,
250 const std::vector<uint8_t>& contents,
251 bool epoch0_restart)
252 {
253 BOTAN_ASSERT_NOMSG(epoch0_restart == false); // only happens on server side
254
255 Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base);
256
257 if(type == HELLO_REQUEST && active_state)
258 {
259 Hello_Request hello_request(contents);
260
261 if(state.client_hello())
262 {
263 throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Cannot renegotiate during a handshake");
264 }
265
266 if(policy().allow_server_initiated_renegotiation())
267 {
268 if(secure_renegotiation_supported() || policy().allow_insecure_renegotiation())
269 {
270 state.m_is_reneg = true;
271 this->initiate_handshake(state, true);
272 }
273 else
274 {
275 throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client policy prohibits insecure renegotiation");
276 }
277 }
278 else
279 {
280 if(policy().abort_connection_on_undesired_renegotiation())
281 {
282 throw TLS_Exception(Alert::NO_RENEGOTIATION, "Client policy prohibits renegotiation");
283 }
284 else
285 {
286 // RFC 5746 section 4.2
288 }
289 }
290
291 return;
292 }
293
294 state.confirm_transition_to(type);
295
297 state.hash().update(state.handshake_io().format(contents, type));
298
300 {
301 state.set_expected_next(SERVER_HELLO);
302 state.set_expected_next(HELLO_VERIFY_REQUEST); // might get it again
303
304 Hello_Verify_Request hello_verify_request(contents);
305 state.hello_verify_request(hello_verify_request);
306 }
307 else if(type == SERVER_HELLO)
308 {
309 state.server_hello(new Server_Hello(contents));
310
311 if(!state.client_hello()->offered_suite(state.server_hello()->ciphersuite()))
312 {
313 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
314 "Server replied with ciphersuite we didn't send");
315 }
316
317 if(!Ciphersuite::by_id(state.server_hello()->ciphersuite()).usable_in_version(state.server_hello()->version()))
318 {
319 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
320 "Server replied using a ciphersuite not allowed in version it offered");
321 }
322
323 if(Ciphersuite::is_scsv(state.server_hello()->ciphersuite()))
324 {
325 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
326 "Server replied with a signaling ciphersuite");
327 }
328
329 if(state.server_hello()->compression_method() != 0)
330 {
331 throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
332 "Server replied with non-null compression method");
333 }
334
335 if(state.client_hello()->version() > state.server_hello()->version())
336 {
337 if(state.server_hello()->random_signals_downgrade())
338 throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Downgrade attack detected");
339 }
340
341 auto client_extn = state.client_hello()->extension_types();
342 auto server_extn = state.server_hello()->extension_types();
343
344 std::vector<Handshake_Extension_Type> diff;
345
346 std::set_difference(server_extn.begin(), server_extn.end(),
347 client_extn.begin(), client_extn.end(),
348 std::back_inserter(diff));
349
350 if(!diff.empty())
351 {
352 // Server sent us back an extension we did not send!
353
354 std::ostringstream msg;
355 msg << "Server replied with unsupported extensions:";
356 for(auto&& d : diff)
357 msg << " " << static_cast<int>(d);
358 throw TLS_Exception(Alert::UNSUPPORTED_EXTENSION, msg.str());
359 }
360
361 if(uint16_t srtp = state.server_hello()->srtp_profile())
362 {
363 if(!value_exists(state.client_hello()->srtp_profiles(), srtp))
364 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
365 "Server replied with DTLS-SRTP alg we did not send");
366 }
367
368 callbacks().tls_examine_extensions(state.server_hello()->extensions(), SERVER);
369
370 state.set_version(state.server_hello()->version());
371 m_application_protocol = state.server_hello()->next_protocol();
372
373 secure_renegotiation_check(state.server_hello());
374
375 const bool server_returned_same_session_id =
376 !state.server_hello()->session_id().empty() &&
377 (state.server_hello()->session_id() == state.client_hello()->session_id());
378
379 if(server_returned_same_session_id)
380 {
381 // successful resumption
382
383 /*
384 * In this case, we offered the version used in the original
385 * session, and the server must resume with the same version.
386 */
387 if(state.server_hello()->version() != state.client_hello()->version())
388 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
389 "Server resumed session but with wrong version");
390
391 if(state.server_hello()->supports_extended_master_secret() &&
392 !state.resumed_session->supports_extended_master_secret())
393 {
394 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
395 "Server resumed session but added extended master secret");
396 }
397
398 if(!state.server_hello()->supports_extended_master_secret() &&
399 state.resumed_session->supports_extended_master_secret())
400 {
401 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
402 "Server resumed session and removed extended master secret");
403 }
404
405 state.compute_session_keys(state.resume_master_secret());
406
407 if(state.server_hello()->supports_session_ticket())
408 {
409 state.set_expected_next(NEW_SESSION_TICKET);
410 }
411 else
412 {
413 state.set_expected_next(HANDSHAKE_CCS);
414 }
415 }
416 else
417 {
418 // new session
419
420 if(active_state)
421 {
422 // Here we are testing things that should not change during a renegotation,
423 // even if the server creates a new session. Howerver they might change
424 // in a resumption scenario.
425
426 if(active_state->version() != state.server_hello()->version())
427 throw TLS_Exception(Alert::PROTOCOL_VERSION,
428 "Server changed version after renegotiation");
429
430 if(state.server_hello()->supports_extended_master_secret() !=
431 active_state->server_hello()->supports_extended_master_secret())
432 {
433 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
434 "Server changed its mind about extended master secret");
435 }
436 }
437
438 state.resumed_session.reset(); // non-null if we were attempting a resumption
439
440 if(state.client_hello()->version().is_datagram_protocol() !=
441 state.server_hello()->version().is_datagram_protocol())
442 {
443 throw TLS_Exception(Alert::PROTOCOL_VERSION,
444 "Server replied with different protocol type than we offered");
445 }
446
447 if(state.version() > state.client_hello()->version())
448 {
449 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
450 "Server replied with later version than client offered");
451 }
452
453 if(state.version().major_version() == 3 && state.version().minor_version() == 0)
454 {
455 throw TLS_Exception(Alert::PROTOCOL_VERSION,
456 "Server attempting to negotiate SSLv3 which is not supported");
457 }
458
459 if(!policy().acceptable_protocol_version(state.version()))
460 {
461 throw TLS_Exception(Alert::PROTOCOL_VERSION,
462 "Server version " + state.version().to_string() +
463 " is unacceptable by policy");
464 }
465
466 if(state.ciphersuite().signature_used() || state.ciphersuite().kex_method() == Kex_Algo::STATIC_RSA)
467 {
468 state.set_expected_next(CERTIFICATE);
469 }
470 else if(state.ciphersuite().kex_method() == Kex_Algo::PSK)
471 {
472 /* PSK is anonymous so no certificate/cert req message is
473 ever sent. The server may or may not send a server kex,
474 depending on if it has an identity hint for us.
475
476 (EC)DHE_PSK always sends a server key exchange for the
477 DH exchange portion, and is covered by block below
478 */
479
480 state.set_expected_next(SERVER_KEX);
481 state.set_expected_next(SERVER_HELLO_DONE);
482 }
483 else if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
484 {
485 state.set_expected_next(SERVER_KEX);
486 }
487 else
488 {
489 state.set_expected_next(CERTIFICATE_REQUEST); // optional
490 state.set_expected_next(SERVER_HELLO_DONE);
491 }
492 }
493 }
494 else if(type == CERTIFICATE)
495 {
496 state.server_certs(new Certificate(contents, policy()));
497
498 const std::vector<X509_Certificate>& server_certs =
499 state.server_certs()->cert_chain();
500
501 if(server_certs.empty())
502 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
503 "Client: No certificates sent by server");
504
505 /*
506 If the server supports certificate status messages,
507 certificate verification happens after we receive the server hello done,
508 in case an OCSP response was also available
509 */
510
511 X509_Certificate server_cert = server_certs[0];
512
513 if(active_state && active_state->server_certs())
514 {
515 X509_Certificate current_cert = active_state->server_certs()->cert_chain().at(0);
516
517 if(current_cert != server_cert)
518 throw TLS_Exception(Alert::BAD_CERTIFICATE, "Server certificate changed during renegotiation");
519 }
520
521 std::unique_ptr<Public_Key> peer_key(server_cert.subject_public_key());
522
523 const std::string expected_key_type =
524 state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() : "RSA";
525
526 if(peer_key->algo_name() != expected_key_type)
527 throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
528 "Certificate key type did not match ciphersuite");
529
530 if(!key_usage_matches_ciphersuite(server_cert.constraints(), state.ciphersuite()))
531 throw TLS_Exception(Alert::BAD_CERTIFICATE,
532 "Certificate usage constraints do not allow this ciphersuite");
533
534 state.server_public_key.reset(peer_key.release());
535
536 if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
537 {
538 state.set_expected_next(SERVER_KEX);
539 }
540 else
541 {
542 state.set_expected_next(CERTIFICATE_REQUEST); // optional
543 state.set_expected_next(SERVER_HELLO_DONE);
544 }
545
546 if(state.server_hello()->supports_certificate_status_message())
547 {
548 state.set_expected_next(CERTIFICATE_STATUS); // optional
549 }
550 else
551 {
552 try
553 {
554 auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
555
556 callbacks().tls_verify_cert_chain(server_certs,
557 {},
558 trusted_CAs,
560 m_info.hostname(),
561 policy());
562 }
563 catch(TLS_Exception&)
564 {
565 throw;
566 }
567 catch(std::exception& e)
568 {
569 throw TLS_Exception(Alert::INTERNAL_ERROR, e.what());
570 }
571 }
572 }
573 else if(type == CERTIFICATE_STATUS)
574 {
575 state.server_cert_status(new Certificate_Status(contents));
576
577 if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA)
578 {
579 state.set_expected_next(SERVER_KEX);
580 }
581 else
582 {
583 state.set_expected_next(CERTIFICATE_REQUEST); // optional
584 state.set_expected_next(SERVER_HELLO_DONE);
585 }
586 }
587 else if(type == SERVER_KEX)
588 {
589 if(state.ciphersuite().psk_ciphersuite() == false)
590 state.set_expected_next(CERTIFICATE_REQUEST); // optional
591 state.set_expected_next(SERVER_HELLO_DONE);
592
593 state.server_kex(
594 new Server_Key_Exchange(contents,
595 state.ciphersuite().kex_method(),
596 state.ciphersuite().auth_method(),
597 state.version())
598 );
599
600 if(state.ciphersuite().signature_used())
601 {
602 const Public_Key& server_key = state.get_server_public_key();
603
604 if(!state.server_kex()->verify(server_key, state, policy()))
605 {
606 throw TLS_Exception(Alert::DECRYPT_ERROR,
607 "Bad signature on server key exchange");
608 }
609 }
610 }
611 else if(type == CERTIFICATE_REQUEST)
612 {
613 state.set_expected_next(SERVER_HELLO_DONE);
614 state.cert_req(new Certificate_Req(contents, state.version()));
615 }
616 else if(type == SERVER_HELLO_DONE)
617 {
618 state.server_hello_done(new Server_Hello_Done(contents));
619
620 if(state.server_certs() != nullptr &&
621 state.server_hello()->supports_certificate_status_message())
622 {
623 try
624 {
625 auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname());
626
627 std::vector<std::shared_ptr<const OCSP::Response>> ocsp;
628 if(state.server_cert_status() != nullptr)
629 {
630 try {
631 ocsp.push_back(std::make_shared<OCSP::Response>(state.server_cert_status()->response()));
632 }
633 catch(Decoding_Error&)
634 {
635 // ignore it here because it might be our fault
636 }
637 }
638
639 callbacks().tls_verify_cert_chain(state.server_certs()->cert_chain(),
640 ocsp,
641 trusted_CAs,
643 m_info.hostname(),
644 policy());
645 }
646 catch(TLS_Exception&)
647 {
648 throw;
649 }
650 catch(std::exception& e)
651 {
652 throw TLS_Exception(Alert::INTERNAL_ERROR, e.what());
653 }
654 }
655
656 if(state.received_handshake_msg(CERTIFICATE_REQUEST))
657 {
658 const auto& types = state.cert_req()->acceptable_cert_types();
659
660 std::vector<X509_Certificate> client_certs =
661 m_creds.find_cert_chain(types,
662 state.cert_req()->acceptable_CAs(),
663 "tls-client",
664 m_info.hostname());
665
666 state.client_certs(new Certificate(state.handshake_io(),
667 state.hash(),
668 client_certs));
669 }
670
671 state.client_kex(
672 new Client_Key_Exchange(state.handshake_io(),
673 state,
674 policy(),
675 m_creds,
676 state.server_public_key.get(),
677 m_info.hostname(),
678 rng())
679 );
680
681 state.compute_session_keys();
682
683 if(state.received_handshake_msg(CERTIFICATE_REQUEST) &&
684 !state.client_certs()->empty())
685 {
686 Private_Key* private_key =
687 m_creds.private_key_for(state.client_certs()->cert_chain()[0],
688 "tls-client",
689 m_info.hostname());
690
691 state.client_verify(
692 new Certificate_Verify(state.handshake_io(),
693 state,
694 policy(),
695 rng(),
696 private_key)
697 );
698 }
699
700 state.handshake_io().send(Change_Cipher_Spec());
701
703
704 state.client_finished(new Finished(state.handshake_io(), state, CLIENT));
705
706 if(state.server_hello()->supports_session_ticket())
707 state.set_expected_next(NEW_SESSION_TICKET);
708 else
709 state.set_expected_next(HANDSHAKE_CCS);
710 }
711 else if(type == NEW_SESSION_TICKET)
712 {
713 state.new_session_ticket(new New_Session_Ticket(contents));
714
715 state.set_expected_next(HANDSHAKE_CCS);
716 }
717 else if(type == HANDSHAKE_CCS)
718 {
719 state.set_expected_next(FINISHED);
720
722 }
723 else if(type == FINISHED)
724 {
725 state.server_finished(new Finished(contents));
726
727 if(!state.server_finished()->verify(state, SERVER))
728 throw TLS_Exception(Alert::DECRYPT_ERROR,
729 "Finished message didn't verify");
730
731 state.hash().update(state.handshake_io().format(contents, type));
732
733 if(!state.client_finished()) // session resume case
734 {
735 state.handshake_io().send(Change_Cipher_Spec());
737 state.client_finished(new Finished(state.handshake_io(), state, CLIENT));
738 }
739
740 std::vector<uint8_t> session_id = state.server_hello()->session_id();
741
742 const std::vector<uint8_t>& session_ticket = state.session_ticket();
743
744 if(session_id.empty() && !session_ticket.empty())
745 session_id = make_hello_random(rng(), policy());
746
747 Session session_info(
748 session_id,
749 state.session_keys().master_secret(),
750 state.server_hello()->version(),
751 state.server_hello()->ciphersuite(),
752 CLIENT,
753 state.server_hello()->supports_extended_master_secret(),
754 state.server_hello()->supports_encrypt_then_mac(),
755 get_peer_cert_chain(state),
756 session_ticket,
757 m_info,
758 "",
759 state.server_hello()->srtp_profile()
760 );
761
762 const bool should_save = save_session(session_info);
763
764 if(session_id.size() > 0 && state.is_a_resumption() == false)
765 {
766 if(should_save)
767 session_manager().save(session_info);
768 else
769 session_manager().remove_entry(session_info.session_id());
770 }
771
773 }
774 else
775 throw Unexpected_Message("Unknown handshake message received");
776 }
777
778}
779
780}
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:49
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
virtual Private_Key * private_key_for(const X509_Certificate &cert, const std::string &type, const std::string &context)
virtual std::vector< Certificate_Store * > trusted_certificate_authorities(const std::string &type, const std::string &context)
virtual std::vector< X509_Certificate > find_cert_chain(const std::vector< std::string > &cert_key_types, const std::vector< X509_DN > &acceptable_CAs, const std::string &type, const std::string &context)
virtual std::string srp_identifier(const std::string &type, const std::string &context)
virtual void tls_examine_extensions(const Extensions &extn, Connection_Side which_side)
virtual void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::shared_ptr< const OCSP::Response > > &ocsp_responses, const std::vector< Certificate_Store * > &trusted_roots, Usage_Type usage, const std::string &hostname, const TLS::Policy &policy)
bool secure_renegotiation_supported() const
Handshake_State & create_handshake_state(Protocol_Version version)
void send_warning_alert(Alert::Type type)
Definition: tls_channel.h:139
Callbacks & callbacks() const
Definition: tls_channel.h:242
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
bool save_session(const Session &session)
std::function< bool(const Session &)> handshake_cb
Definition: tls_channel.h:43
void change_cipher_spec_writer(Connection_Side side)
std::function< void(Alert, const uint8_t[], size_t)> alert_cb
Definition: tls_channel.h:42
Session_Manager & session_manager()
Definition: tls_channel.h:236
std::function< void(const Handshake_Message &)> handshake_msg_cb
Definition: tls_channel.h:44
const Policy & policy() const
Definition: tls_channel.h:238
RandomNumberGenerator & rng()
Definition: tls_channel.h:234
void change_cipher_spec_reader(Connection_Side side)
std::function< void(const uint8_t[], size_t)> output_fn
Definition: tls_channel.h:40
void secure_renegotiation_check(const Client_Hello *client_hello)
std::function< void(const uint8_t[], size_t)> data_cb
Definition: tls_channel.h:41
static Ciphersuite by_id(uint16_t suite)
bool usable_in_version(Protocol_Version version) const
static bool is_scsv(uint16_t suite)
Client(Callbacks &callbacks, Session_Manager &session_manager, Credentials_Manager &creds, const Policy &policy, RandomNumberGenerator &rng, const Server_Information &server_info=Server_Information(), const Protocol_Version &offer_version=Protocol_Version::latest_tls_version(), const std::vector< std::string > &next_protocols={}, size_t reserved_io_buffer_size=TLS::Client::IO_BUF_DEFAULT_SIZE)
Definition: tls_client.cpp:64
virtual bool only_resume_with_exact_version() const
Definition: tls_policy.cpp:346
virtual bool acceptable_protocol_version(Protocol_Version version) const
Definition: tls_policy.cpp:278
std::string hostname() const
virtual void remove_entry(const std::vector< uint8_t > &session_id)=0
virtual void save(const Session &session)=0
int(* final)(unsigned char *, CTX *)
@ HELLO_VERIFY_REQUEST
Definition: tls_magic.h:49
@ HANDSHAKE_CCS
Definition: tls_magic.h:62
@ SERVER_HELLO
Definition: tls_magic.h:48
@ NEW_SESSION_TICKET
Definition: tls_magic.h:50
@ SERVER_HELLO_DONE
Definition: tls_magic.h:54
@ HELLO_REQUEST
Definition: tls_magic.h:46
@ CERTIFICATE_REQUEST
Definition: tls_magic.h:53
@ CERTIFICATE
Definition: tls_magic.h:51
@ CERTIFICATE_STATUS
Definition: tls_magic.h:60
@ SERVER_KEX
Definition: tls_magic.h:52
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
Definition: alg_id.cpp:13
bool value_exists(const std::vector< T > &vec, const T &val)
Definition: stl_util.h:86
Key_Constraints
Definition: pkix_enums.h:106
@ DATA_ENCIPHERMENT
Definition: pkix_enums.h:111
@ NO_CONSTRAINTS
Definition: pkix_enums.h:107
@ DIGITAL_SIGNATURE
Definition: pkix_enums.h:108
@ KEY_ENCIPHERMENT
Definition: pkix_enums.h:110
@ NON_REPUDIATION
Definition: pkix_enums.h:109
MechanismType type
std::unique_ptr< Session > resumed_session
Definition: tls_client.cpp:55
std::unique_ptr< Public_Key > server_public_key
Definition: tls_client.cpp:53
bool m_is_reneg
Definition: tls_client.cpp:56