From 67d2d7f200d45d639d913034167e00a328de12f3 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 9 Jul 2020 21:44:24 +0200 Subject: [PATCH] implemented right version of stream filter for input --- .../epee/include/net/abstract_tcp_server2.inl | 4 +- src/common/encryption_filter.h | 96 +++++++++++++------ .../blockchain_storage_boost_serialization.h | 2 + .../currency_boost_serialization.h | 2 +- tests/unit_tests/chacha_stream_test.cpp | 45 ++++++++- 5 files changed, 111 insertions(+), 38 deletions(-) diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 799cfd01..6e57b54a 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -326,7 +326,7 @@ bool connection::do_send(const void* ptr, size_t cb) boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), m_send_que.front().size()), //strand_.wrap( - boost::bind(&connection::handle_write, self, _1, _2) + boost::bind(&connection::handle_write, self, boost::placeholders::_1, boost::placeholders::_2) //) ); @@ -404,7 +404,7 @@ void connection::handle_write(const boost::system::error_cod //have more data to send boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), m_send_que.front().size()), //strand_.wrap( - boost::bind(&connection::handle_write, connection::shared_from_this(), _1, _2)); + boost::bind(&connection::handle_write, connection::shared_from_this(), boost::placeholders::_1, boost::placeholders::_2)); //); } CRITICAL_REGION_END(); diff --git a/src/common/encryption_filter.h b/src/common/encryption_filter.h index b2e03f5d..edb2099c 100644 --- a/src/common/encryption_filter.h +++ b/src/common/encryption_filter.h @@ -24,6 +24,7 @@ public: typedef char char_type; //typedef boost::iostreams::multichar_output_filter_tag category; //typedef boost::iostreams::flushable_tag category; + static const uint32_t block_size = ECRYPT_BLOCKLENGTH; encrypt_chacha_processer_base(std::string const &pass, const crypto::chacha8_iv& iv) :m_iv(iv), m_ctx(AUTO_VAL_INIT(m_ctx)) { @@ -152,49 +153,83 @@ public: template std::streamsize read(Source& src, char* s, std::streamsize n) { - std::streamsize result = 0; - if ((result = boost::iostreams::read(src, s, n)) == -1) + if(m_buff.size() >= n) { - if (!m_was_eof) - { - m_was_eof = true; - std::streamsize written_butes = 0; - encrypt_chacha_processer_base::flush([&](char_type const * const buf_lambda, std::streamsize const n_lambda) { - return written_butes = withdraw_to_read_buff(s, n, buf_lambda, n_lambda); - }); - if (!written_butes) - return -1; - return written_butes; - } - else - { - if (!m_buff.size()) - { - return -1; - } - else - { - return withdraw_to_read_buff(s, n, "", 0); - } - } + return withdraw_to_read_buff(s, n); + } + if(m_was_eof && m_buff.empty()) + { + return -1; } - return encrypt_chacha_processer_base::process(s, result, [&](char_type const * const buf_lambda, std::streamsize const n_lambda) { - return withdraw_to_read_buff(s, n, buf_lambda, n_lambda); - }); + std::streamsize size_to_read_for_decrypt = (n - m_buff.size()); + size_to_read_for_decrypt += size_to_read_for_decrypt % encrypt_chacha_processer_base::block_size; + size_t offset_in_buff = m_buff.size(); + m_buff.resize(m_buff.size() + size_to_read_for_decrypt); + + std::streamsize result = boost::iostreams::read(src, (char*)&m_buff.data()[offset_in_buff], size_to_read_for_decrypt); + if(result == size_to_read_for_decrypt) + { + //regular read proocess, readed data enought to get decrypteds + encrypt_chacha_processer_base::process(&m_buff.data()[offset_in_buff], size_to_read_for_decrypt, [&](char_type const* const buf_lambda, std::streamsize const n_lambda) + { + CHECK_AND_ASSERT_THROW_MES(n_lambda == size_to_read_for_decrypt, "Error in decrypt: check n_lambda == size_to_read_for_decrypt failed"); + std::memcpy((char*)&m_buff.data()[offset_in_buff], buf_lambda, n_lambda); + }); + return withdraw_to_read_buff(s, n); + } + else + { + //been read some size_but it's basically might be eof + if(!m_was_eof) + { + size_t offset_before_flush = offset_in_buff; + if(result != -1) + { + //eof + encrypt_chacha_processer_base::process(&m_buff.data()[offset_in_buff], result, [&](char_type const* const buf_lambda, std::streamsize const n_lambda) { + std::memcpy((char*)&m_buff.data()[offset_in_buff], buf_lambda, n_lambda); + offset_before_flush = offset_in_buff + n_lambda; + }); + } + + encrypt_chacha_processer_base::flush([&](char_type const* const buf_lambda, std::streamsize const n_lambda) { + if(n_lambda + offset_before_flush > m_buff.size()) + { + m_buff.resize(n_lambda + offset_before_flush); + } + std::memcpy((char*)&m_buff.data()[offset_before_flush], buf_lambda, n_lambda); + }); + + //just to make sure that it's over + std::string buff_stub(10, ' '); + std::streamsize r = boost::iostreams::read(src, (char*)&buff_stub.data()[0], 10); + CHECK_AND_ASSERT_THROW_MES(r == -1, "expected EOF"); + m_was_eof = true; + return withdraw_to_read_buff(s, n); + } + } } template bool flush(Sink& snk) { - encrypt_chacha_processer_base::flush([&](char_type const * const buf_lambda, std::streamsize const n_lambda) { - boost::iostreams::write(snk, &buf_lambda[0], n_lambda); - }); + return true; } private: + + std::streamsize withdraw_to_read_buff(char* s, std::streamsize n) + { + size_t copy_size = m_buff.size() > n ? n : m_buff.size(); + std::memcpy(s, m_buff.data(), copy_size); + m_buff.erase(0, copy_size); + return copy_size; + } + + /* std::streamsize withdraw_to_read_buff(char* s, std::streamsize n, char_type const * const buf_lambda, std::streamsize const n_lambda) { if (m_buff.size()) @@ -218,6 +253,7 @@ private: return copy_size; } } + */ std::string m_buff; bool m_was_eof; diff --git a/src/currency_core/blockchain_storage_boost_serialization.h b/src/currency_core/blockchain_storage_boost_serialization.h index 709f0629..843af173 100644 --- a/src/currency_core/blockchain_storage_boost_serialization.h +++ b/src/currency_core/blockchain_storage_boost_serialization.h @@ -6,6 +6,8 @@ #pragma once +#include "currency_boost_serialization.h" + namespace boost { namespace serialization diff --git a/src/currency_core/currency_boost_serialization.h b/src/currency_core/currency_boost_serialization.h index 0b6622e3..49f4b9cf 100644 --- a/src/currency_core/currency_boost_serialization.h +++ b/src/currency_core/currency_boost_serialization.h @@ -208,7 +208,7 @@ namespace boost inline void serialize(Archive &a, currency::keypair &kp, const boost::serialization::version_type ver) { a & kp.pub; - a & kp.sec; + a & kp.sec; } template diff --git a/tests/unit_tests/chacha_stream_test.cpp b/tests/unit_tests/chacha_stream_test.cpp index 4f8b2298..b5188cf4 100644 --- a/tests/unit_tests/chacha_stream_test.cpp +++ b/tests/unit_tests/chacha_stream_test.cpp @@ -12,6 +12,9 @@ #include "common/encryption_filter.h" #include "crypto/crypto.h" +#include "currency_core/blockchain_storage_basic.h" +#include "currency_core/blockchain_storage_boost_serialization.h" +#include "common/boost_serialization_helper.h" TEST(chacha_stream_test, chacha_stream_test) @@ -84,7 +87,14 @@ TEST(chacha_stream_test, chacha_stream_test) // //public boost::iostreams::seekable_filter_tag // { }; + std::list test_list; + for(size_t i = 0; i != 1000; i++) { + test_list.push_back(currency::block_extended_info()); + test_list.back().height = i; + test_list.back().this_block_tx_fee_median = i; + } + std::list verification_list; crypto::chacha8_iv iv = crypto::rand(); boost::filesystem::ofstream store_data_file; @@ -94,11 +104,14 @@ TEST(chacha_stream_test, chacha_stream_test) boost::iostreams::filtering_ostream out; out.push(encrypt_filter); out.push(store_data_file); - out << buff; + + + //out << buff; + bool res = tools::portble_serialize_obj_to_stream(test_list, out); + out.flush(); store_data_file.close(); - boost::filesystem::ifstream data_file; data_file.open("./test.bin", std::ios_base::binary | std::ios_base::in); encrypt_chacha_in_filter decrypt_filter("pass", iv); @@ -109,12 +122,34 @@ TEST(chacha_stream_test, chacha_stream_test) in.push(data_file); //todo: read from stream - size_t size = buff_size;//in.tellg(); - std::string str(size, '\0'); // construct string to stream size + //size_t size = buff_size;//in.tellg(); + ///std::string str(size+10, '\0'); // construct string to stream size //in.seekg(0); try { + + bool res2 = tools::portable_unserialize_obj_from_stream(verification_list, in); + //if(verification_list != test_list) + { + std::cout << "erroor"; + } + //in.read(&str[0], size+10); + //std::streamsize sz = in.gcount(); + //if(!in) { + // std::cout << "error"; + //} + /* + in.read(&str[0], size + 10); + sz = in.gcount(); + if(!in) { + std::cout << "error"; + } - in.read(&str[0], size+1); + in.read(&str[0], size + 10); + sz = in.gcount(); + if(!in) { + std::cout << "error"; + } + */ std::cout << "ddd"; }