// Called with cleartext data we want to encrypt and send back... extern "C" DLL_PUBLIC int32_t iocba_cleartext_push( buffers_t* buffers, char* in_clr, uint32_t clr_length, char* out_enc_to_send, uint32_t *enc_to_send_length ) { Botan::TLS::Channel* channel = buffers -> channel; // buffers -> enc_cursor = out_enc_to_send; buffers -> enc_end = out_enc_to_send + *enc_to_send_length; try { // TRACE("Before send channel=%p \n", channel); channel->send( (const unsigned char*) in_clr, clr_length); } catch (buffer_override_exception_t const& ) { TRACE("Buffer override trying to encrypt cleartext\n"); } catch (std::exception const& e) { using namespace std; cout << "BotanTLS engine raised exception on send: " << e.what() << endl; // Clear the buffers, they shall not be used again buffers -> clear_cursors(); return -1; } *enc_to_send_length = (uint32_t) ( buffers -> enc_cursor - out_enc_to_send ); buffers -> clear_cursors(); return 0; }
extern "C" void iocba_close( void* tls_channel ) { Botan::TLS::Channel* channel = (Botan::TLS::Channel*) tls_channel; try{ channel->close(); } catch (...) { printf("BotanTLS engine raised exception on close\n"); } }
// Checks a few hints that Botan may put here and there. // ALWAYS call this function after the Botan functions, to ensure // that some thread-local variables we are using are handled correctly. void check_readiness() { if (not ready_for_output && not (channel->is_closed()) && channel->is_active()) { ready_for_output = true; } if ( successfull_retrieval != 0) { session_was_resumed = successfull_retrieval; // Reset the value so that we can say something sensible // about the next session successfull_retrieval = 0; } }
extern "C" DLL_PUBLIC void iocba_close( buffers_t* buffers, char* out_enc_to_send, uint32_t *enc_to_send_length ) { // TRACE("Close called on buffer_t* %p\n", buffers); Botan::TLS::Channel* channel = buffers->channel; buffers -> enc_cursor = out_enc_to_send; buffers -> enc_end = out_enc_to_send + *enc_to_send_length; // No waiting cleartext data in this context buffers -> clr_cursor = 0; buffers -> clr_end = 0; try{ channel->close(); } catch (buffer_override_exception_t const& e) { TRACE("Buffer override at iocba_close!!\n"); return ; } catch (Botan::TLS::TLS_Exception const& e) { if (e.type() == Botan::TLS::Alert::INAPPROPRIATE_FALLBACK) { TRACE("BotanTLS engine (close) instance likely crashed before: %s \n", e.what()); return ; } else { TRACE("BotanTLS engine (close) instance crashed (normal if ALPN didn't go well): %s \n", e.what()); return ; } } catch (std::exception const& e) { // TODO: control messages //TRACE("BotanTLS engine crashed with generic exception: %s \n", e.what()); return ; }catch (...) { TRACE("BotanTLS engine raised exception on close\n"); } *enc_to_send_length = (uint32_t) ( buffers -> enc_cursor - out_enc_to_send ); buffers -> clear_cursors(); }
extern "C" void iocba_cleartext_push( void* tls_channel, char* data, int length ) { // TODO: Check for "can send"!!!!! // OTHERWISE THIS WON'T WORK try { Botan::TLS::Channel* channel = (Botan::TLS::Channel*) tls_channel; // printf("Before send channel=%p \n", channel); channel->send( (const unsigned char*) data, length); // printf("After send channel=%p \n", channel); } catch (...) { printf("BotanTLS engine raised exception on send\n"); } }
extern "C" int iocba_receive_data( void* tls_channel, char* data, int length ) { Botan::TLS::Channel* channel = (Botan::TLS::Channel*) tls_channel; try { //printf("Before taking data=%p \n", channel); size_t more_data_required = channel->received_data( (const unsigned char*) data, length); //printf("More data required %d \n", more_data_required); //printf("After taking data=%p \n", channel); } catch (std::exception const& e) { // TODO: control messages printf("BotanTLS engine instance crashed (normal if ALPN didn't go well): %s \n", e.what()); return -1; } return 0; }
// Called with encrypted data received from the peer. extern "C" DLL_PUBLIC int32_t iocba_receive_data( buffers_t* buffers, char* in_data, uint32_t in_length, char* out_enc_to_send, uint32_t *enc_to_send_length, char* out_cleartext_received, uint32_t *cleartext_received_length ) { //TRACE("Entering iocba_receive_data\n"); Botan::TLS::Channel* channel = buffers -> channel; // buffers -> enc_cursor = out_enc_to_send; buffers -> enc_end = out_enc_to_send + *enc_to_send_length; // buffers -> clr_cursor = out_cleartext_received; buffers -> clr_end = out_cleartext_received + *cleartext_received_length; //TRACE("Botan receives data\n"); try { size_t more_data_required = channel->received_data( (const unsigned char*) in_data, in_length); buffers->check_readiness(); } catch (buffer_override_exception_t const& e) { TRACE("Buffer override at iocba_receive_data!! (received %d bytes for cleartext and %d bytes for encoded)\n", *cleartext_received_length, *enc_to_send_length); return -1; } catch (Botan::TLS::TLS_Exception const& e) { if (e.type() == Botan::TLS::Alert::INAPPROPRIATE_FALLBACK) { TRACE("BotanTLS engine instance likely crashed before: %s \n", e.what()); return -1; } else { TRACE("BotanTLS engine instance crashed (normal if ALPN didn't go well): %s \n", e.what()); return -1; } } catch (std::exception const& e) { // TODO: control messages TRACE("BotanTLS engine crashed with generic exception: %s \n", e.what()); return -1; } *enc_to_send_length = (uint32_t) ( buffers -> enc_cursor - out_enc_to_send ); //TRACE("Returning %d bytes \n", *enc_to_send_length); *cleartext_received_length = (uint32_t) ( buffers -> clr_cursor - out_cleartext_received ); //TRACE("Returning %d bytes of cleartext \n", *cleartext_received_length); // So that we get a clean segfault if we do something wrong buffers-> clear_cursors(); if ( buffers -> alert_produced ) { if ( buffers -> alert_is_fatal || buffers -> peer_closed_transport) { // If I don't get this message we are in trouble... // TRACE("Alert assimilated as part of decryption call\n"); return -1; } } return 0; }