Botan  2.4.0
Crypto and TLS for C++11
tls_blocking.cpp
Go to the documentation of this file.
1 /*
2 * TLS Blocking API
3 * (C) 2013 Jack Lloyd
4 * 2016 Matthias Gierlings
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/tls_blocking.h>
10 
11 namespace Botan {
12 
13 namespace TLS {
14 
15 using namespace std::placeholders;
16 
18  write_fn writer,
19  Session_Manager& session_manager,
20  Credentials_Manager& creds,
21  const Policy& policy,
23  const Server_Information& server_info,
24  const Protocol_Version& offer_version,
25  const std::vector<std::string>& next) :
26  m_read(reader),
27  m_callbacks(new TLS::Compat_Callbacks(
28  /*
29  we are ok using deprecated features here because the whole Blocking_Client class
30  is also deprecated, so just silence the warning.
31  */
32  TLS::Compat_Callbacks::SILENCE_DEPRECATION_WARNING::PLEASE,
33  writer,
34  std::bind(&Blocking_Client::data_cb, this, _1, _2),
35  std::function<void (Alert)>(std::bind(&Blocking_Client::alert_cb, this, _1)),
36  std::bind(&Blocking_Client::handshake_cb, this, _1)
37  )),
38  m_channel(*m_callbacks.get(),
39  session_manager,
40  creds,
41  policy,
42  rng,
43  server_info,
44  offer_version,
45  next)
46  {
47  }
48 
49 bool Blocking_Client::handshake_cb(const Session& session)
50  {
51  return this->handshake_complete(session);
52  }
53 
54 void Blocking_Client::alert_cb(const Alert& alert)
55  {
56  this->alert_notification(alert);
57  }
58 
59 void Blocking_Client::data_cb(const uint8_t data[], size_t data_len)
60  {
61  m_plaintext.insert(m_plaintext.end(), data, data + data_len);
62  }
63 
65  {
66  std::vector<uint8_t> readbuf(4096);
67 
68  while(!m_channel.is_closed() && !m_channel.is_active())
69  {
70  const size_t from_socket = m_read(readbuf.data(), readbuf.size());
71  m_channel.received_data(readbuf.data(), from_socket);
72  }
73  }
74 
75 size_t Blocking_Client::read(uint8_t buf[], size_t buf_len)
76  {
77  std::vector<uint8_t> readbuf(4096);
78 
79  while(m_plaintext.empty() && !m_channel.is_closed())
80  {
81  const size_t from_socket = m_read(readbuf.data(), readbuf.size());
82  m_channel.received_data(readbuf.data(), from_socket);
83  }
84 
85  const size_t returned = std::min(buf_len, m_plaintext.size());
86 
87  for(size_t i = 0; i != returned; ++i)
88  buf[i] = m_plaintext[i];
89  m_plaintext.erase(m_plaintext.begin(), m_plaintext.begin() + returned);
90 
91  BOTAN_ASSERT_IMPLICATION(returned == 0, m_channel.is_closed(),
92  "Only return zero if channel is closed");
93 
94  return returned;
95  }
96 
97 }
98 
99 }
bool is_closed() const
Definition: bigint.h:635
std::function< size_t(uint8_t[], size_t)> read_fn
Definition: tls_blocking.h:29
virtual void alert_notification(const Alert &)
Definition: tls_blocking.h:83
std::function< void(const uint8_t[], size_t)> write_fn
Definition: tls_blocking.h:30
Definition: alg_id.cpp:13
virtual bool handshake_complete(const Session &)
Definition: tls_blocking.h:78
size_t received_data(const uint8_t buf[], size_t buf_size)
Blocking_Client(read_fn reader, write_fn writer, 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_protos={})
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition: assert.h:68
size_t read(uint8_t buf[], size_t buf_len)
bool is_active() const