aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-10-11 12:39:05 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-10-11 12:39:05 +0200
commit0fb433690c0ca5f9561fe9e2e973e2cd61b873ba (patch)
tree9422a034b09d1e0b46144f35a1f9bcf7860156d6
parentd8e48c32f8435076382543edfafbf81c223f9e87 (diff)
downloadcmix-0fb433690c0ca5f9561fe9e2e973e2cd61b873ba.tar.gz
cmix-0fb433690c0ca5f9561fe9e2e973e2cd61b873ba.tar.bz2
cmix-0fb433690c0ca5f9561fe9e2e973e2cd61b873ba.zip
Commit introducing Client keyexchange, triggering bugs.
Clients now send their public key to each node and the node calculates the shared secret. The node does not yet respond with it's public key. To keep this commit smaller. Nodes now disconnect from each other in a better way. Getting the relevant crypto api is now done with a generic function. What crypto algorithm and implemenation is beign used can be selected in the cmake cache (use cmake-gui or ccmake) Clients now connect correctly to multiple nodes.
-rw-r--r--client/cmixclient.cpp82
-rw-r--r--client/cmixclient.hpp13
-rw-r--r--client/main.cpp2
-rw-r--r--client/node.cpp4
-rw-r--r--client/node.hpp7
-rw-r--r--libcmix-crypto/api.h6
-rw-r--r--libcmix-crypto/curve25519/curve25519.c2
-rw-r--r--libcmix-crypto/curve25519/curve25519.h2
-rw-r--r--libcmix-crypto/curve25519/null/null_curve25519.c2
-rw-r--r--libcmix-crypto/curve25519/sodium/libsodium_curve25519.c2
-rw-r--r--libcmix-crypto/elgamal/elgamal.c2
-rw-r--r--libcmix-crypto/elgamal/elgamal.h2
-rw-r--r--libcmix-crypto/elgamal/null/null_elgamal.c2
-rw-r--r--libcmix-network/client.cpp2
-rw-r--r--libcmix-network/connect.cpp2
-rw-r--r--libcmix-protobuf/cmix.proto5
-rw-r--r--liblog/logging.cpp2
-rw-r--r--node/main.cpp9
-rw-r--r--node/node.cpp42
-rw-r--r--node/node.hpp1
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"