Botan
1.11.15
|
00001 /* 00002 * TLS Blocking API 00003 * (C) 2013 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/tls_blocking.h> 00009 00010 namespace Botan { 00011 00012 namespace TLS { 00013 00014 using namespace std::placeholders; 00015 00016 Blocking_Client::Blocking_Client(read_fn reader, 00017 write_fn writer, 00018 Session_Manager& session_manager, 00019 Credentials_Manager& creds, 00020 const Policy& policy, 00021 RandomNumberGenerator& rng, 00022 const Server_Information& server_info, 00023 const Protocol_Version offer_version, 00024 next_protocol_fn npn) : 00025 m_read(reader), 00026 m_channel(writer, 00027 std::bind(&Blocking_Client::data_cb, this, _1, _2), 00028 std::bind(&Blocking_Client::alert_cb, this, _1, _2, _3), 00029 std::bind(&Blocking_Client::handshake_cb, this, _1), 00030 session_manager, 00031 creds, 00032 policy, 00033 rng, 00034 server_info, 00035 offer_version, 00036 npn) 00037 { 00038 } 00039 00040 bool Blocking_Client::handshake_cb(const Session& session) 00041 { 00042 return this->handshake_complete(session); 00043 } 00044 00045 void Blocking_Client::alert_cb(const Alert alert, const byte[], size_t) 00046 { 00047 this->alert_notification(alert); 00048 } 00049 00050 void Blocking_Client::data_cb(const byte data[], size_t data_len) 00051 { 00052 m_plaintext.insert(m_plaintext.end(), data, data + data_len); 00053 } 00054 00055 void Blocking_Client::do_handshake() 00056 { 00057 std::vector<byte> readbuf(4096); 00058 00059 while(!m_channel.is_closed() && !m_channel.is_active()) 00060 { 00061 const size_t from_socket = m_read(&readbuf[0], readbuf.size()); 00062 m_channel.received_data(&readbuf[0], from_socket); 00063 } 00064 } 00065 00066 size_t Blocking_Client::read(byte buf[], size_t buf_len) 00067 { 00068 std::vector<byte> readbuf(4096); 00069 00070 while(m_plaintext.empty() && !m_channel.is_closed()) 00071 { 00072 const size_t from_socket = m_read(&readbuf[0], readbuf.size()); 00073 m_channel.received_data(&readbuf[0], from_socket); 00074 } 00075 00076 const size_t returned = std::min(buf_len, m_plaintext.size()); 00077 00078 for(size_t i = 0; i != returned; ++i) 00079 buf[i] = m_plaintext[i]; 00080 m_plaintext.erase(m_plaintext.begin(), m_plaintext.begin() + returned); 00081 00082 BOTAN_ASSERT_IMPLICATION(returned == 0, m_channel.is_closed(), 00083 "Only return zero if channel is closed"); 00084 00085 return returned; 00086 } 00087 00088 } 00089 00090 }