diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-11-07 12:53:59 +0100 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-11-07 12:53:59 +0100 |
| commit | 46f22621759d388f7cef4bf0d2ac03667a5d611e (patch) | |
| tree | b26cd49fe2552680eb16d9008695c8f56e757ded | |
| parent | 7e21069bea9e8e6276591eee98f22cb07d67392d (diff) | |
| download | cmix-46f22621759d388f7cef4bf0d2ac03667a5d611e.tar.gz cmix-46f22621759d388f7cef4bf0d2ac03667a5d611e.tar.bz2 cmix-46f22621759d388f7cef4bf0d2ac03667a5d611e.zip | |
prepares the api for sending and mixing messages in the realtime phase.
| -rw-r--r-- | client/cmixclient.cpp | 52 | ||||
| -rw-r--r-- | client/cmixclient.hpp | 9 | ||||
| -rw-r--r-- | libcmix-protobuf/cmix.proto | 12 | ||||
| -rw-r--r-- | libcmix/cmix.c | 41 | ||||
| -rw-r--r-- | libcmix/cmix.h | 13 | ||||
| -rw-r--r-- | node/main.cpp | 4 | ||||
| -rw-r--r-- | node/node.cpp | 6 | ||||
| -rw-r--r-- | node/node.hpp | 2 | ||||
| -rw-r--r-- | node/node_client.cpp | 2 | ||||
| -rw-r--r-- | node/node_node.cpp | 15 |
10 files changed, 108 insertions, 48 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp index ba1a187..ba2f1da 100644 --- a/client/cmixclient.cpp +++ b/client/cmixclient.cpp @@ -17,25 +17,12 @@ using namespace boost::asio; void CMixClient::key_exchange(size_t node_id) { BOOST_LOG_TRIVIAL(trace) << "Sending KeyExchange for node: " << node_id; - - unsigned char* buffer; - size_t len; - - api.element_to_array(&buffer, &len, keypair.pub); cmix_proto::KeyExchange ke; - ke.set_public_key(buffer, len); - api.free_buffer(buffer); - - data.at(node_id).secret_value = api.get_group_element(true); - - GroupElement shared_value = api.get_key_exchange_value(data.at(node_id).secret_value); + ke.mutable_public_key()->resize(get_group_element_array_size(&cmix_ctx)); + ke.mutable_value()->resize(get_group_element_array_size(&cmix_ctx)); - api.element_to_array(&buffer, &len, shared_value); - ke.set_value(buffer, len); - api.free_buffer(buffer); - - api.free_group_element(shared_value); + key_exchange_init(&cmix_ctx, &(*ke.mutable_public_key())[0], &(*ke.mutable_value())[0], &data.at(node_id).secret_value); network_connections.at(node_id).async_send(ke); network_connections.at(node_id).async_receive([node_id, this](cmix_proto::CMixMessage message) { @@ -59,14 +46,26 @@ void CMixClient::initialize_connections() { }); }; - network_connections.emplace_back(std::unique_ptr<ssl::stream<tcp::socket>>(new ssl::stream<tcp::socket>(io_service, *ctx))); + network_connections.emplace_back(std::unique_ptr<ssl::stream<tcp::socket>>(new ssl::stream<tcp::socket>(io_service, *ssl_ctx))); network_connections.back().async_connect(network_details.node_details[i].host, network_details.node_details[i].port, handler); } } void CMixClient::handle_key_exchange(size_t node_id, cmix_proto::KeyExchange const& ke) { - data.at(node_id).shared_value.shared = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), ke.public_key().size(), reinterpret_cast<uint8_t const*>(ke.value().c_str()), ke.value().size(), data.at(node_id).secret_value, false); + key_exchange_initiator( + &cmix_ctx, + &data.at(node_id).shared_value, + ke.public_key().data(), + ke.value().data(), + data.at(node_id).secret_value + ); + + size_t len = get_group_element_array_size(&cmix_ctx); + std::string s = "abcdefghijklmnopqrstuvwxyz"; + s.resize(len, '0'); + + cmix_proto::Bye bye; network_connections.at(node_id).async_send(bye); @@ -104,14 +103,16 @@ void CMixClient::handle_message(size_t node_id, cmix_proto::CMixMessage message) CMixClient::CMixClient(NetworkDetails details) : io_service() -, ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23)) +, ssl_ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23)) +, cmix_ctx(initialize_cmix_context(get_implementation())) , network_details(details) , network_connections() -, api(get_implementation()) -, keypair(api.create_keypair()) +, data() { + initialize_keypair(&cmix_ctx); + if(!details.certdir.empty()) { - ctx->add_verify_path(details.certdir); + ssl_ctx->add_verify_path(details.certdir); } initialize_connections(); @@ -119,12 +120,7 @@ CMixClient::CMixClient(NetworkDetails details) CMixClient::~CMixClient() { - api.free_keypair(&keypair); - for(auto&& d : data) { - api.free_shared_key(&d.shared_value); - api.free_group_element(d.secret_value); - } - api.deinitialize(); + deinitialize(&cmix_ctx); } void CMixClient::run() { diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp index ee99d38..59aeba6 100644 --- a/client/cmixclient.hpp +++ b/client/cmixclient.hpp @@ -1,6 +1,7 @@ #pragma once #include "senderreceiver.hpp" +#include "cmix.h" #include "api.h" #include "groupelement.h" #include "keypair.h" @@ -44,19 +45,17 @@ class CMixClient { struct NodeData { GroupElement secret_value; - SharedKey shared_value; + GroupElement shared_value; }; boost::asio::io_service io_service; - std::shared_ptr<boost::asio::ssl::context> ctx; + std::shared_ptr<boost::asio::ssl::context> ssl_ctx; + CMixContext cmix_ctx; NetworkDetails network_details; std::vector<SSLSenderReceiver> network_connections; std::vector<NodeData> data; - Api api; - KeyPair keypair; - void key_exchange(size_t node_id); void initialize_connections(); diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto index e048fef..9ff5bb2 100644 --- a/libcmix-protobuf/cmix.proto +++ b/libcmix-protobuf/cmix.proto @@ -29,6 +29,11 @@ message NodeReady { } +message UserMessage { + required bytes r_M = 1; + required bytes m_M = 2; +} + message PrePre { repeated bytes r_ER = 1; repeated bytes m_ER = 2; @@ -53,8 +58,9 @@ message CMixMessage { Bye bye = 5; KeyExchange keyexchange = 6; NodeReady nodeready = 7; - PrePre prepre = 8; - PreMix premix = 9; - PrePost prepost = 10; + UserMessage usermessage = 8; + PrePre prepre = 9; + PreMix premix = 10; + PrePost prepost = 11; } } diff --git a/libcmix/cmix.c b/libcmix/cmix.c index 28f56db..582fe70 100644 --- a/libcmix/cmix.c +++ b/libcmix/cmix.c @@ -45,7 +45,8 @@ struct CMixContext initialize_cmix_context(struct Api api) { .r = NULL, .s = NULL, .permutation = NULL, - .pirs = NULL + .pirs = NULL, + .messages = NULL }; } @@ -54,17 +55,20 @@ void release_mix(struct CMixContext* ctx) { ctx->api.free_group_element(ctx->r[i]); ctx->api.free_group_element(ctx->s[i]); ctx->api.free_group_element(ctx->pirs[i]); + ctx->api.free_group_element(ctx->messages[i]); } free(ctx->r); free(ctx->s); free(ctx->permutation); free(ctx->pirs); + free(ctx->messages); } void deinitialize(struct CMixContext* ctx) { ctx->api.free_keypair(&ctx->keypair); release_mix(ctx); + ctx->api.deinitialize(); } void element_to_buffer(struct CMixContext const* ctx, char* out_buffer, GroupElement element) { @@ -106,7 +110,8 @@ enum cmix_error alloc_mix(struct CMixContext* ctx) { ctx->s = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement)); ctx->permutation = (unsigned int*) calloc(ctx->nr_participants, sizeof(unsigned int)); ctx->pirs = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement)); - if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs) { + ctx->pirs = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement)); + if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs || !ctx->messages) { return out_of_memory; } return no_error; @@ -127,6 +132,11 @@ enum cmix_error initialize_mix_randomness(struct CMixContext* ctx) { return no_error; } +enum cmix_error generate_random_message(struct CMixContext* ctx, size_t index) { + ctx->messages[index] = ctx->api.get_group_element(true); + return no_error; +} + size_t get_group_element_array_size(struct CMixContext const* ctx) { return ctx->api.get_group_element_array_size(); } @@ -200,12 +210,20 @@ enum cmix_error multiply_s(struct CMixContext const* ctx, char* r_out_buffer, ch return no_error; } -enum cmix_error key_exchange(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exchange_value_buffer, char const* pubkey, char const* value) { +enum cmix_error key_exchange_init(struct CMixContext const* ctx, char* pubkey_buffer, char* value_buffer, GroupElement* priv_el) { + *priv_el = ctx->api.get_group_element(true); + GroupElement value = ctx->api.get_key_exchange_value(priv_el); + + get_public_key(ctx, pubkey_buffer); + element_to_buffer(ctx, value_buffer, value); + return no_error; +} + +enum cmix_error key_exchange_responder(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exchange_value_buffer, char const* pubkey, char const* value) { GroupElement priv_el = ctx->api.get_group_element(true); GroupElement ex_val = ctx->api.get_key_exchange_value(priv_el); size_t el_len = get_group_element_array_size(ctx); - *shared_key = ctx->api.derive_shared_key(ctx->keypair, (unsigned char*)pubkey, el_len, (unsigned char*)value, el_len, priv_el, true); element_to_buffer(ctx, public_key_buffer, ctx->keypair.pub); @@ -217,15 +235,24 @@ enum cmix_error key_exchange(struct CMixContext const* ctx, GroupElement* shared return no_error; } -enum cmix_error post_process(struct CMixContext* ctx, char const* r_epirs, char const* m_epirs, size_t index) { - GroupElement x = ctx->api.array_to_element(r_epirs, get_group_element_array_size(ctx), true); +enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupElement* shared_key, char const* pubkey, char const* value, GroupElement priv_el) { + size_t el_len = get_group_element_array_size(ctx); + *shared_key = ctx->api.derive_shared_key(ctx->keypair, (unsigned char*)pubkey, el_len, (unsigned char*)value, el_len, priv_el, false); + return no_error; +} + +enum cmix_error post_process(struct CMixContext* ctx, char* r_out, char* m_out, char const* r_epirs, char const* m_epirs, size_t index) { + GroupElement x = ctx->api.array_to_element(r_epirs, get_group_element_array_size(ctx), true); GroupElement D = ctx->api.get_decryption_share(x, ctx->keypair.sec); + element_to_buffer(ctx, r_out, D); GroupElement msg = ctx->api.array_to_element(m_epirs, get_group_element_array_size(ctx), true); GroupElement pirs = ctx->api.multiply(D, msg, true); + element_to_buffer(ctx, m_out, pirs); + + ctx->pirs = pirs; // this is not always usable as only the last node will be able to use this effectively, but we store it anyways. - ctx->pirs[index] = pirs; ctx->api.free_group_element(x); ctx->api.free_group_element(D); ctx->api.free_group_element(msg); diff --git a/libcmix/cmix.h b/libcmix/cmix.h index 433c3bc..7442369 100644 --- a/libcmix/cmix.h +++ b/libcmix/cmix.h @@ -78,6 +78,7 @@ struct CMixContext { GroupElement* s; unsigned int* permutation; GroupElement* pirs; + GroupElement* messages; }; struct CMixContext initialize_cmix_context(struct Api api); @@ -94,6 +95,8 @@ enum cmix_error start_mix(struct CMixContext* ctx, size_t nr_participants); enum cmix_error initialize_mix_randomness(struct CMixContext* ctx); +enum cmix_error generate_random_message(struct CMixContext* ctx, size_t index); + size_t get_group_element_array_size(struct CMixContext const* ctx); enum cmix_error set_network_key(struct CMixContext* ctx, char const* buffer, size_t len); @@ -104,9 +107,15 @@ enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char* rand enum cmix_error multiply_s(struct CMixContext const* ctx, char* r_out_buffer, char* m_out_buffer, char const* r_in_buffer, char const* m_in_buffer, size_t index); -enum cmix_error key_exchange(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exhange_value_buffer, char const* pubkey, char const* value); +enum cmix_error get_key_exchange_value(struct CMixContext const* ctx, char* buffer, GroupElement priv_element); + +enum cmix_error key_exchange_init(struct CMixContext const* ctx, char* pubkey_buffer, char* value_buffer, GroupElement* secret_value); + +enum cmix_error key_exchange_responder(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exhange_value_buffer, char const* pubkey, char const* value); + +enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupElement* shared_key, char const* pubkey, char const* value, GroupElement priv_el); -enum cmix_error post_process(struct CMixContext* ctx, char const* r_epirs, char const* m_epirs, size_t index); +enum cmix_error post_process(struct CMixContext* ctx, char* r_out, char* m_out, char const* r_epirs, char const* m_epirs, size_t index); #ifdef __cplusplus } // extern "C" diff --git a/node/main.cpp b/node/main.cpp index 0c81312..28ef60c 100644 --- a/node/main.cpp +++ b/node/main.cpp @@ -21,6 +21,7 @@ int main(int argc, char* argv[]) { ("interface6,6", po::value<std::string>()->default_value("::"), "Set the ipv6 address to listen on.") ("next_node,n", po::value<std::string>(), "The address of the next node in the network.") ("first,f", "This is the first node and will be the communication point for the clients.") + ("last,f", "this is the last node and will be able to send the original message out of the network.") ("cert,c", po::value<std::string>(), "The cert file to use (in pem format).") ("key,k", po::value<std::string>(), "The key file (in pem format).") ("dhparam,d", po::value<std::string>(), "The dhparam file.") @@ -92,6 +93,7 @@ int main(int argc, char* argv[]) { BOOST_LOG_TRIVIAL(info) << "Started node"; bool is_first = bool(vm.count("first")); + bool is_last = bool(vm.count("last")); std::string next_node; if(vm.count("next_node")) { next_node = vm["next_node"].as<std::string>(); @@ -112,7 +114,7 @@ int main(int argc, char* argv[]) { Uri uri = parse_uri(next_node); - NodeNetworkSettings nsettings{is_first, uri.host, uri.port, certdir}; + NodeNetworkSettings nsettings{is_first, is_last, uri.host, uri.port, certdir}; Node node(lsettings, nsettings); node.run(); diff --git a/node/node.cpp b/node/node.cpp index fa9a721..b5c8506 100644 --- a/node/node.cpp +++ b/node/node.cpp @@ -135,6 +135,12 @@ void Node::start_precomputation() { exit(-1); } + int i = 0; + for(auto&& pair : clients) { + index_map[pair.first] = i++; + generate_random_message(&cmix_ctx, i); + } + if(initialize_mix_randomness(&cmix_ctx) != no_error) { exit(-1); } diff --git a/node/node.hpp b/node/node.hpp index ea73121..a4c7992 100644 --- a/node/node.hpp +++ b/node/node.hpp @@ -24,6 +24,7 @@ */ struct NodeNetworkSettings { bool is_first; ///< Are we the first node in the network. + bool is_last; ///< Are we the last node in the network. std::string next_host; ///< Next nodes host. std::string next_port; ///< Next nodes port. std::string certdir; ///< Directory containing trusted certificate authorities. @@ -71,6 +72,7 @@ class Node CMixContext cmix_ctx; std::vector<MixData> precomputation_data; + std::map<std::string, int> index_map; bool shutting_down; diff --git a/node/node_client.cpp b/node/node_client.cpp index fef1937..f60c48d 100644 --- a/node/node_client.cpp +++ b/node/node_client.cpp @@ -10,7 +10,7 @@ void Node::handle_client_keyexchange(ClientConnections::key_type handle, cmix_pr nke.mutable_public_key()->resize(len); nke.mutable_value()->resize(len); - key_exchange(&cmix_ctx, &d.shared_value.shared, &(*nke.mutable_public_key())[0], &(*nke.mutable_value())[0], ke.public_key().data(), ke.value().data()); + key_exchange_responder(&cmix_ctx, &d.shared_value.shared, &(*nke.mutable_public_key())[0], &(*nke.mutable_value())[0], ke.public_key().data(), ke.value().data()); data[handle] = d; diff --git a/node/node_node.cpp b/node/node_node.cpp index fecc4ad..eea9eb0 100644 --- a/node/node_node.cpp +++ b/node/node_node.cpp @@ -60,7 +60,20 @@ cmix_proto::PrePost fill_precomputation_post_message(CMixContext& ctx, T const& cmix_proto::PrePost prepost; for(size_t i = 0; i < ctx.nr_participants; ++i) { - post_process(&ctx, rs.Get(i).data(), ms.Get(i).data(), i); + size_t el_len = get_group_element_array_size(&ctx); + + prepost.mutable_r_epirs(i)->resize(el_len); + prepost.mutable_m_epirs(i)->resize(el_len); + + post_process( + &ctx, + &(*prepost.mutable_r_epirs(i))[0], + &(*prepost.mutable_m_epirs(i))[0], + rs.Get(i).data(), + ms.Get(i).data(), + i + ); + *prepost.mutable_r_epirs(i) = rs.Get(i); *prepost.mutable_m_epirs(i) = ms.Get(i); } |
