diff options
| -rw-r--r-- | client/cmixclient.cpp | 82 | ||||
| -rw-r--r-- | client/cmixclient.hpp | 13 | ||||
| -rw-r--r-- | client/main.cpp | 2 | ||||
| -rw-r--r-- | client/node.cpp | 4 | ||||
| -rw-r--r-- | client/node.hpp | 7 | ||||
| -rw-r--r-- | libcmix-crypto/api.h | 6 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/curve25519.c | 2 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/curve25519.h | 2 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/null/null_curve25519.c | 2 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/sodium/libsodium_curve25519.c | 2 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/elgamal.c | 2 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/elgamal.h | 2 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/null/null_elgamal.c | 2 | ||||
| -rw-r--r-- | libcmix-network/client.cpp | 2 | ||||
| -rw-r--r-- | libcmix-network/connect.cpp | 2 | ||||
| -rw-r--r-- | libcmix-protobuf/cmix.proto | 5 | ||||
| -rw-r--r-- | liblog/logging.cpp | 2 | ||||
| -rw-r--r-- | node/main.cpp | 9 | ||||
| -rw-r--r-- | node/node.cpp | 42 | ||||
| -rw-r--r-- | node/node.hpp | 1 |
20 files changed, 148 insertions, 43 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp index e3f5ac4..195c5e0 100644 --- a/client/cmixclient.cpp +++ b/client/cmixclient.cpp @@ -1,38 +1,86 @@ #include "cmixclient.hpp" -void CMixClient::initialized() { - BOOST_LOG_TRIVIAL(trace) << "Client connections were made"; - for(auto&& connection : network_connections) { - cmix_proto::Bye bye; - connection.send(bye); - } - io_service.stop(); +void CMixClient::key_exchange(int i) { + shared_keys.resize(network_connections.size()); + + cmix_proto::KeyExchange ke; + ke.set_public_key(keypair.pub, keypair.pub_len); + + network_connections[i].send(ke); + + cmix_proto::Bye bye; + network_connections[i].send(bye); } void CMixClient::initialize_connections() { network_connections.reserve(network_details.size()); - int i = network_details.size(); - auto handler = [this, i]() mutable { - cmix_proto::ImAClient imaclient; - network_connections.at(network_details.size() - i).send(imaclient); + for(int i = 0; i < network_details.size(); ++i) { + auto handler = [this, i]() mutable { + cmix_proto::ImAClient imaclient; + BOOST_LOG_TRIVIAL(trace) << "sending imaclient to node: " << i; + network_connections.at(i).send(imaclient); - if(--i == 0) { - initialized(); - } - }; + key_exchange(i); + }; - for(auto&& details : network_details) { network_connections.emplace_back(boost::asio::ip::tcp::socket(io_service)); - network_connections.back().async_connect(details.host, details.port, handler); + network_connections.back().async_connect(network_details[i].host, network_details[i].port, handler); + + } +} + +cmix_proto::CMixMessage CMixClient::parse_cmix_message(std::vector<uint8_t> const& buffer) +{ + cmix_proto::CMixMessage message; + if(!message.ParseFromArray(buffer.data(), buffer.size())) { + BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage"; + throw std::runtime_error("Network communication was disrupted in a unrecoverable way."); + } + return message; +} + +void CMixClient::handle_key_exchange(int node_id, cmix_proto::KeyExchange const& ke) +{ + shared_keys[node_id] = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), false); +} + +void CMixClient::handle_message(int node_id, std::vector<uint8_t> const& message_buffer) +{ + cmix_proto::CMixMessage message; + try { + message = parse_cmix_message(message_buffer); + } catch(std::runtime_error const& e) { + for(auto&& connection : network_connections) { + connection.close(); + } + io_service.stop(); + return; + } + + switch(message.contents_case()) { + case cmix_proto::CMixMessage::ContentsCase::kKeyexchange: { + handle_key_exchange(node_id, *message.mutable_keyexchange()); + return; + } + default: { + BOOST_LOG_TRIVIAL(error) << "Received unknown message"; + } } + + for(auto&& connection : network_connections) { + connection.close(); + } + io_service.stop(); } CMixClient::CMixClient(std::vector<NodeDetails> details) : io_service() , network_details(details) , network_connections() +, api(get_implementation()) +, keypair(api.create_key_pair()) { initialize_connections(); } diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp index 10438d1..5c6405a 100644 --- a/client/cmixclient.hpp +++ b/client/cmixclient.hpp @@ -2,6 +2,7 @@ #include "node.hpp" +#include "api.h" #include "logging.hpp" #include "client.hpp" #include "connect.hpp" @@ -22,10 +23,20 @@ class CMixClient { std::vector<NodeDetails> network_details; std::vector<Node> network_connections; - void initialized(); + Api api; + KeyPair keypair; + std::vector<SharedKey> shared_keys; + + void key_exchange(int i); void initialize_connections(); + cmix_proto::CMixMessage parse_cmix_message(std::vector<uint8_t> const& buffer); + + void handle_key_exchange(int node_id, cmix_proto::KeyExchange const& ke); + + void handle_message(int node_id, std::vector<uint8_t> const& message_buffer); + public: CMixClient(std::vector<NodeDetails> details); diff --git a/client/main.cpp b/client/main.cpp index fb05171..bcac249 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -14,7 +14,7 @@ int main(int argc, char* argv[]) { init_logging(boost::log::trivial::severity_level::trace, "client"); - BOOST_LOG_TRIVIAL(info) << "Started node"; + BOOST_LOG_TRIVIAL(info) << "Started client"; po::options_description desc("Allowed options"); desc.add_options() diff --git a/client/node.cpp b/client/node.cpp index 8fd1dd8..46375f4 100644 --- a/client/node.cpp +++ b/client/node.cpp @@ -13,6 +13,10 @@ void Node::async_connect(std::string next_host, std::string next_port, std::func client.async_connect(next_host, next_port, on_connect); } +void Node::receive(std::function<void (const std::vector<uint8_t>&)> receive_handler) { + client.receive(receive_handler); +} + void Node::close() { client.close(); diff --git a/client/node.hpp b/client/node.hpp index 3719223..afcf56a 100644 --- a/client/node.hpp +++ b/client/node.hpp @@ -22,6 +22,7 @@ inline void message_setter(cmix_proto::CMixMessage& m, cmix_proto::TYPE const& v MESSAGE_SETTER(ImAClient, imaclient) MESSAGE_SETTER(Bye, bye) +MESSAGE_SETTER(KeyExchange, keyexchange) #undef MESSAGE_SETTER @@ -50,6 +51,12 @@ public: } /*! + * \brief receive + * \param receive_handler + */ + void receive(std::function<void(std::vector<uint8_t> const&)> receive_handler); + + /*! * \brief async_connect * \param next_host The host of the next node. * \param next_port The port of the next node. diff --git a/libcmix-crypto/api.h b/libcmix-crypto/api.h index 09b474b..06afcd2 100644 --- a/libcmix-crypto/api.h +++ b/libcmix-crypto/api.h @@ -29,7 +29,7 @@ typedef void (*KeyPairDeleter)(struct KeyPair); * \brief Defines how a Derived Shared Key function should look like. * Used to store a pointer to function to a implementation. */ -typedef struct SharedKey (*SharedKeyDeriver)(struct KeyPair, unsigned char*, bool); +typedef struct SharedKey (*SharedKeyDeriver)(struct KeyPair, unsigned char const*, bool); /*! * \brief Defines how a Derived Shared Key deleter function should look like. @@ -47,6 +47,10 @@ struct Api { SharedKeyDeleter free_shared_key; ///< Pointer to shared key deleter function }; +typedef struct Api(*ImplementationGetter)(); + +extern ImplementationGetter get_implementation; + #ifdef __cplusplus } #endif diff --git a/libcmix-crypto/curve25519/curve25519.c b/libcmix-crypto/curve25519/curve25519.c index 824daf9..4d53ddf 100644 --- a/libcmix-crypto/curve25519/curve25519.c +++ b/libcmix-crypto/curve25519/curve25519.c @@ -10,3 +10,5 @@ struct Api get_curve25519_implementation() &curve25519_shared_key_deleter }; } + +ImplementationGetter get_implementation = &get_curve25519_implementation; diff --git a/libcmix-crypto/curve25519/curve25519.h b/libcmix-crypto/curve25519/curve25519.h index 8e2ad4e..fde317a 100644 --- a/libcmix-crypto/curve25519/curve25519.h +++ b/libcmix-crypto/curve25519/curve25519.h @@ -28,7 +28,7 @@ extern void curve25519_keypair_deleter(struct KeyPair p); * \param swap_pub_order Should we swap the order in which we feed the public keys to the hash function. * \return A Shared key */ -extern struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char* pub_key, bool swap_pub_order); +extern struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order); /*! * \brief curve25519_shared_key_deleter * \param s the Shared key to free. diff --git a/libcmix-crypto/curve25519/null/null_curve25519.c b/libcmix-crypto/curve25519/null/null_curve25519.c index 317455f..63280ec 100644 --- a/libcmix-crypto/curve25519/null/null_curve25519.c +++ b/libcmix-crypto/curve25519/null/null_curve25519.c @@ -17,7 +17,7 @@ struct KeyPair curve25519_create_keypair() { void curve25519_shared_key_deleter(struct SharedKey s) {} -struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char* pub_key, bool swap_pub_order) { +struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order) { return (struct SharedKey){ NULL, 0 diff --git a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c index 59e9258..e86ec09 100644 --- a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c +++ b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c @@ -43,7 +43,7 @@ void curve25519_shared_key_deleter(struct SharedKey s) { s.shared = NULL; } -struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char* pub_key, bool swap_pub_order) { +struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order) { init(); unsigned char* shared = (unsigned char*) sodium_malloc(crypto_generichash_BYTES); diff --git a/libcmix-crypto/elgamal/elgamal.c b/libcmix-crypto/elgamal/elgamal.c index 3136688..d50126c 100644 --- a/libcmix-crypto/elgamal/elgamal.c +++ b/libcmix-crypto/elgamal/elgamal.c @@ -9,3 +9,5 @@ struct Api get_elgamal_implementation() &elgamal_shared_key_deleter }; } + +ImplementationGetter get_implementation = &get_elgamal_implementation;
\ No newline at end of file diff --git a/libcmix-crypto/elgamal/elgamal.h b/libcmix-crypto/elgamal/elgamal.h index 77b5c9b..feac7f5 100644 --- a/libcmix-crypto/elgamal/elgamal.h +++ b/libcmix-crypto/elgamal/elgamal.h @@ -9,7 +9,7 @@ extern "C" { extern struct KeyPair elgamal_create_keypair(); extern void elgamal_keypair_deleter(struct KeyPair p); -extern struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, unsigned char* pub_key, bool swap_pub_order); +extern struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order); extern void elgamal_shared_key_deleter(struct SharedKey s); struct Api get_elgamal_implementation(); diff --git a/libcmix-crypto/elgamal/null/null_elgamal.c b/libcmix-crypto/elgamal/null/null_elgamal.c index ef98912..285e2fd 100644 --- a/libcmix-crypto/elgamal/null/null_elgamal.c +++ b/libcmix-crypto/elgamal/null/null_elgamal.c @@ -17,7 +17,7 @@ struct KeyPair elgamal_create_keypair() { void elgamal_shared_key_deleter(struct SharedKey s) {} -struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, unsigned char* pub_key, bool swap_pub_order) { +struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order) { return (struct SharedKey){ NULL, 0 diff --git a/libcmix-network/client.cpp b/libcmix-network/client.cpp index 9293bd1..f693afa 100644 --- a/libcmix-network/client.cpp +++ b/libcmix-network/client.cpp @@ -81,7 +81,7 @@ void Client::handle_receive_message(MessageHandler message_handler, const error_ } } -void Client::handle_receive_size(Client::MessageHandler message_handler, const error_code& ec, size_t read_bytes) +void Client::handle_receive_size(Client::MessageHandler message_handler, error_code const& ec, size_t read_bytes) { using namespace boost::asio::placeholders; diff --git a/libcmix-network/connect.cpp b/libcmix-network/connect.cpp index fb663ac..01e72de 100644 --- a/libcmix-network/connect.cpp +++ b/libcmix-network/connect.cpp @@ -96,6 +96,8 @@ void async_connect(tcp::socket& socket, std::string host, std::string next_port, boost::asio::ip::basic_resolver<tcp> resolver(socket.get_io_service()); boost::asio::ip::basic_resolver_query<tcp> query(host, next_port); + BOOST_LOG_TRIVIAL(trace) << "connecting to: \"" << host << ":" << next_port << "\""; + auto it = resolver.resolve(query); std::shared_ptr<IterationInfo> info = std::make_shared<IterationInfo>(0, it, socket.get_io_service()); diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto index 8be9b1f..8bbc303 100644 --- a/libcmix-protobuf/cmix.proto +++ b/libcmix-protobuf/cmix.proto @@ -16,11 +16,16 @@ message Bye { } +message KeyExchange { + required bytes public_key = 1; +} + message CMixMessage { oneof contents { Initialization initialization = 1; ImANode imanode = 2; ImAClient imaclient = 3; Bye bye = 4; + KeyExchange keyexchange= 5; } } diff --git a/liblog/logging.cpp b/liblog/logging.cpp index ecc9ae5..3b0c2c5 100644 --- a/liblog/logging.cpp +++ b/liblog/logging.cpp @@ -16,7 +16,7 @@ void init_logging(boost::log::trivial::severity_level log_level, std::string fil boost::log::add_file_log ( - boost::log::keywords::file_name = file_name + "%N.log", + boost::log::keywords::file_name = file_name + ".log", boost::log::keywords::rotation_size = 10 * 1024 * 1024, boost::log::keywords::format = "[%Severity%] (%TimeStamp%): %Message%", boost::log::keywords::auto_flush = true diff --git a/node/main.cpp b/node/main.cpp index 7425f00..527e3c5 100644 --- a/node/main.cpp +++ b/node/main.cpp @@ -10,10 +10,6 @@ int main(int argc, char* argv[]) { namespace po = boost::program_options; - init_logging(boost::log::trivial::severity_level::trace, "node"); - - BOOST_LOG_TRIVIAL(info) << "Started node"; - po::options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message.") @@ -41,6 +37,11 @@ int main(int argc, char* argv[]) { std::string if6 = vm["interface6"].as<std::string>(); uint16_t port = vm["port"].as<uint16_t>(); + init_logging(boost::log::trivial::severity_level::trace, "node_" + std::to_string(port)); + + BOOST_LOG_TRIVIAL(info) << "Started node"; + + ListenSettings lsettings{en4, if4, en6, if6, port}; bool is_first = bool(vm.count("first")); diff --git a/node/node.cpp b/node/node.cpp index 1fe0b44..db18253 100644 --- a/node/node.cpp +++ b/node/node.cpp @@ -15,7 +15,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se , network_settings(network_settings) , prev_node(Client(tcp::socket(io_service))) , next_node(tcp::socket(io_service)) -, api(get_curve25519_implementation()) +, api(get_implementation()) , keypair(api.create_key_pair()) , network_pub_key() { @@ -100,11 +100,6 @@ void Node::handle_initialization(const cmix_proto::Initialization& init) free_bignum(&shared); free_bignum(&mod); free_bignum(&new_shared); - - io_service.post([this]{ - clients.clear(); - io_service.stop(); - }); } } @@ -116,28 +111,54 @@ void Node::handle_node_message(const std::vector<uint8_t>& message_buffer) handle_initialization(message.initialization()); break; } + case cmix_proto::CMixMessage::ContentsCase::kBye: { + prev_node.close(); + return; + } default: { - BOOST_LOG_TRIVIAL(error) << "CMixMessage contains unknown contents."; + BOOST_LOG_TRIVIAL(error) << "handle_node_message: CMixMessage contains unknown contents."; } } + prev_node.receive([this](std::vector<uint8_t> const& buffer) { + handle_node_message(buffer); + }); } void Node::handle_client_message(std::list<Client>::iterator handle, const std::vector<uint8_t>& message_buffer) { cmix_proto::CMixMessage message = parse_cmix_message(message_buffer); + BOOST_LOG_TRIVIAL(trace) << "case: " << message.contents_case(); switch(message.contents_case()) { + case cmix_proto::CMixMessage::ContentsCase::kKeyexchange: { + BOOST_LOG_TRIVIAL(trace) << "Deriving shared key"; + api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(message.keyexchange().public_key().c_str()), true); + + handle->receive([this, handle](std::vector<uint8_t> const& buffer){ + handle_client_message(handle, buffer); + }); + return; + } case cmix_proto::CMixMessage::ContentsCase::kBye: { + BOOST_LOG_TRIVIAL(trace) << "Handling bye"; + handle->close(); clients.erase(handle); if(clients.size() == 0) { - io_service.stop(); + cmix_proto::Bye bye; + next_node.send(bye); + + io_service.post([this]{ + BOOST_LOG_TRIVIAL(trace) << "Shutting down"; + io_service.stop(); + }); + } return; } default: { - BOOST_LOG_TRIVIAL(error) << "CMixMessage contains unknown contents."; + BOOST_LOG_TRIVIAL(error) << "handle_client_message: CMixMessage contains unknown contents."; } } handle->close(); @@ -184,7 +205,7 @@ void Node::handle_message(std::list<Client>::iterator handle, const std::vector< return; } default: { - BOOST_LOG_TRIVIAL(error) << "CMixMessage contains unknown contents."; + BOOST_LOG_TRIVIAL(error) << "handle_message: CMixMessage contains unknown contents."; } } @@ -192,5 +213,4 @@ void Node::handle_message(std::list<Client>::iterator handle, const std::vector< } void Node::start_precomputation() { - } diff --git a/node/node.hpp b/node/node.hpp index fa0cb37..44e379f 100644 --- a/node/node.hpp +++ b/node/node.hpp @@ -6,7 +6,6 @@ #include "nextnode.hpp" #include "api.h" -#include "curve25519.h" #include "cmix.pb.h" |
