diff options
25 files changed, 561 insertions, 121 deletions
diff --git a/CMakeModules/FindGcrypt.cmake b/CMakeModules/FindGcrypt.cmake new file mode 100644 index 0000000..1b4e8c8 --- /dev/null +++ b/CMakeModules/FindGcrypt.cmake @@ -0,0 +1,33 @@ +# - Try to find the Gcrypt library +# Once run this will define +# +# Gcrypt_FOUND +# Gcrypt_CFLAGS +# Gcrypt_LIBRARIES + +FIND_PROGRAM(libgcrypt_config_executable NAMES libgcrypt-config) + +# if libgcrypt-config has been found +IF(libgcrypt_config_executable) + + EXEC_PROGRAM(${libgcrypt_config_executable} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE Gcrypt_LIBRARIES) + + EXEC_PROGRAM(${libgcrypt_config_executable} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE Gcrypt_CFLAGS) + + IF(Gcrypt_LIBRARIES AND Gcrypt_CFLAGS) + SET(Gcrypt_FOUND TRUE) + ENDIF(Gcrypt_LIBRARIES AND Gcrypt_CFLAGS) + +ENDIF(libgcrypt_config_executable) + +if(Gcrypt_FOUND) + if (NOT Gcrypt_FIND_QUIETLY) + message(STATUS "Found libgcrypt: ${Gcrypt_LIBRARIES}") + endif (NOT Gcrypt_FIND_QUIETLY) +else(Gcrypt_FOUND) + if (Gcrypt_FIND_REQUIRED) + message(FATAL_ERROR "Could not find libgcrypt libraries") + endif (Gcrypt_FIND_REQUIRED) +endif(Gcrypt_FOUND) + +MARK_AS_ADVANCED(Gcrypt_CFLAGS Gcrypt_LIBRARIES)
\ No newline at end of file diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 68a37da..b8fa287 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -15,7 +15,6 @@ else(WIN32) ) endif(WIN32) - target_link_libraries(client PRIVATE Boost::boost PRIVATE Boost::program_options diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp index 6866274..9ee1d81 100644 --- a/client/cmixclient.cpp +++ b/client/cmixclient.cpp @@ -1,14 +1,23 @@ #include "cmixclient.hpp" +#include <iostream> + using namespace boost::asio::ip; using namespace boost::asio; void CMixClient::key_exchange(int i) { BOOST_LOG_TRIVIAL(trace) << "Sending KeyExchange for node: " << i; + char* buffer; + size_t len; + + api.get_key_array(&buffer, &len, keypair.pub); + cmix_proto::KeyExchange ke; - ke.set_public_key(keypair.pub, keypair.pub_len); + ke.set_public_key(buffer, len); + + free(buffer); network_connections.at(i).async_send(ke); network_connections.at(i).async_receive([i, this](cmix_proto::CMixMessage message) { @@ -27,8 +36,9 @@ void CMixClient::initialize_connections() { imaclient.set_id("A"); BOOST_LOG_TRIVIAL(trace) << "sending imaclient to node: " << i; network_connections.at(i).async_send(imaclient); - - key_exchange(i); + network_connections.at(i).async_receive([i, this](cmix_proto::CMixMessage message) { + handle_message(i, message); + }); }; network_connections.emplace_back(std::unique_ptr<ssl::stream<tcp::socket>>(new ssl::stream<tcp::socket>(io_service, *ctx))); @@ -48,12 +58,12 @@ void CMixClient::handle_message(int node_id, cmix_proto::CMixMessage message) { switch(message.contents_case()) { case cmix_proto::CMixMessage::ContentsCase::kKeyexchange: { - BOOST_LOG_TRIVIAL(trace) << "handling keyexchange"; + BOOST_LOG_TRIVIAL(trace) << "handling keyexchange for node: " << node_id; handle_key_exchange(node_id, *message.mutable_keyexchange()); return; } case cmix_proto::CMixMessage::ContentsCase::kBye: { - BOOST_LOG_TRIVIAL(trace) << "handling bye"; + BOOST_LOG_TRIVIAL(trace) << "handling bye for node: " << node_id; network_connections.at(node_id).close(); if(std::all_of(network_connections.begin(), network_connections.end(), [](SSLSenderReceiver const& c) { return !c.is_open(); })) { break; @@ -61,6 +71,11 @@ void CMixClient::handle_message(int node_id, cmix_proto::CMixMessage message) return; } } + case cmix_proto::CMixMessage::ContentsCase::kNodeready: { + BOOST_LOG_TRIVIAL(trace) << "handling NodeReady: " << node_id; + key_exchange(node_id); + return; + } default: { BOOST_LOG_TRIVIAL(error) << "Received unknown message"; } @@ -86,7 +101,11 @@ CMixClient::CMixClient(NetworkDetails details) CMixClient::~CMixClient() { - api.free_key_pair(keypair); + api.free_key_pair(&keypair); + for(auto&& d : data) { + api.free_shared_key(&d.shared_value); + } + } void CMixClient::run() { diff --git a/libcmix-common/cmixprotofunctor.cpp b/libcmix-common/cmixprotofunctor.cpp index 46e56a0..525b3c9 100644 --- a/libcmix-common/cmixprotofunctor.cpp +++ b/libcmix-common/cmixprotofunctor.cpp @@ -13,5 +13,6 @@ MESSAGE_SETTER_DEF(ImAClient, imaclient) MESSAGE_SETTER_DEF(Bye, bye) MESSAGE_SETTER_DEF(KeyExchange, keyexchange) MESSAGE_SETTER_DEF(SecretKey, secretkey) +MESSAGE_SETTER_DEF(NodeReady, nodeready) #undef MESSAGE_SETTER_DEF
\ No newline at end of file diff --git a/libcmix-common/cmixprotofunctor.hpp b/libcmix-common/cmixprotofunctor.hpp index 86caa75..bd69504 100644 --- a/libcmix-common/cmixprotofunctor.hpp +++ b/libcmix-common/cmixprotofunctor.hpp @@ -54,6 +54,11 @@ struct CMixProtoFunctor { * #MESSAGE_SETTER_DECL(SecretKey) */ MESSAGE_SETTER_DECL(SecretKey); + + /*! + * + */ + MESSAGE_SETTER_DECL(NodeReady); #undef MESSAGE_SETTER }; diff --git a/libcmix-crypto/CMakeLists.txt b/libcmix-crypto/CMakeLists.txt index 0986024..65b00ab 100644 --- a/libcmix-crypto/CMakeLists.txt +++ b/libcmix-crypto/CMakeLists.txt @@ -34,7 +34,13 @@ target_sources(cmix-crypto option(UseEC "Use curve25519 instead of RSA" ON) -target_link_libraries(cmix-crypto - INTERFACE curve25519-implementation - INTERFACE elgamal-implementation -)
\ No newline at end of file +if(UseEC) + target_link_libraries(cmix-crypto + INTERFACE curve25519-implementation + ) +else(UseEC) + target_link_libraries(cmix-crypto + INTERFACE elgamal-implementation + ) +endif(UseEC) + diff --git a/libcmix-crypto/api.h b/libcmix-crypto/api.h index c6f904f..5267f33 100644 --- a/libcmix-crypto/api.h +++ b/libcmix-crypto/api.h @@ -13,44 +13,65 @@ extern "C" { #include "keypair.h" #include "sharedkey.h" +typedef void(*Initializer)(void); + /*! * \brief Defines how a KeyPair create function should look like. * Used to store a pointer to function to a implementation. */ -typedef struct KeyPair (*KeyPairCreator)(); +typedef struct KeyPair (*KeyPairCreator)(void); /*! * \brief Defines how a KeyPair deleter function should look like. * Used to store a pointer to function to a implementation. */ -typedef void (*KeyPairDeleter)(struct KeyPair); +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 const*, bool); +typedef struct SharedKey (*SharedKeyDeriver)(struct KeyPair, void const*, bool); /*! * \brief Defines how a Derived Shared Key deleter function should look like. * Used to store a pointer to function to a implementation. */ -typedef void (*SharedKeyDeleter)(struct SharedKey); +typedef void (*SharedKeyDeleter)(struct SharedKey*); + +/*! + * \brief Defines how the crypto library deinitialization should look. + */ +typedef void(*Deinitializer)(void); + +/*! + * \brief PubKeyArrayGetter typedef + */ +typedef void(*KeyArrayGetter)(char**, size_t* size, void*); + +/*! + * \brief PublicShareAdder typedef + */ +typedef void(*PublicShareAdder)(char**, size_t*, char const*, size_t, void*); /*! * \brief The Api struct stores pointers to functions of a specific implementation. Like a Curve25519 specific one. */ struct Api { + Initializer initialize; ///< Function that will initialize the crypto library. KeyPairCreator create_key_pair; ///< Pointer to keypair creation function KeyPairDeleter free_key_pair; ///< Pointer to keypair deletor function + KeyArrayGetter get_key_array; ///< Get the array representation of a public key; + PublicShareAdder add_public_share; ///< Adds the public key stored in void* to the existing share. SharedKeyDeriver derive_shared_key; ///< Pointer to shared key derivation function SharedKeyDeleter free_shared_key; ///< Pointer to shared key deleter function + Deinitializer deinitialize; ///< Function that will deinitialize the crypto library. }; /*! * A Pointer to function typedef to facilitate multiple implementations. */ -typedef struct Api(*ImplementationGetter)(); +typedef struct Api(*ImplementationGetter)(void); /*! * \brief get_implementation The pointer to member function variable to implement when diff --git a/libcmix-crypto/curve25519/curve25519.c b/libcmix-crypto/curve25519/curve25519.c index 4d53ddf..c4fae8d 100644 --- a/libcmix-crypto/curve25519/curve25519.c +++ b/libcmix-crypto/curve25519/curve25519.c @@ -3,11 +3,16 @@ struct Api get_curve25519_implementation() { + curve25519_initialize(); return (struct Api) { + &curve25519_initialize, &curve25519_create_keypair, &curve25519_keypair_deleter, + &curve25519_get_key_array, + &curve25519_add_public_share, &curve25519_derive_shared_key, - &curve25519_shared_key_deleter + &curve25519_shared_key_deleter, + &curve25519_deinitialize }; } diff --git a/libcmix-crypto/curve25519/curve25519.h b/libcmix-crypto/curve25519/curve25519.h index fde317a..5d004cf 100644 --- a/libcmix-crypto/curve25519/curve25519.h +++ b/libcmix-crypto/curve25519/curve25519.h @@ -11,15 +11,38 @@ extern "C" { */ /*! + * \brief curve25519_initialize initilalize curve25519 library + */ +extern void curve25519_initialize(void); + +/*! * \brief curve25519_create_keypair * \return A curve25519 keypair. */ -extern struct KeyPair curve25519_create_keypair(); +extern struct KeyPair curve25519_create_keypair(void); + /*! * \brief curve25519_keypair_deleter * \param p The keypair to free. */ -extern void curve25519_keypair_deleter(struct KeyPair p); +extern void curve25519_keypair_deleter(struct KeyPair* p); + +/*! + * \brief curve25519_get_pubkey_array + * \param pubkey + * \param buffer + * \param len + */ +extern void curve25519_get_key_array(char** buffer, size_t* len, void* pubkey); + +/*! + * \brief curve25519_add_public_share + * \param buffer + * \param out_len + * \param share + * \param pubkey + */ +extern void curve25519_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey); /*! * \brief curve25519_derive_shared_key @@ -28,12 +51,15 @@ 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 const* pub_key, bool swap_pub_order); +extern struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, void const* pub_key, bool swap_pub_order); + /*! * \brief curve25519_shared_key_deleter * \param s the Shared key to free. */ -extern void curve25519_shared_key_deleter(struct SharedKey s); +extern void curve25519_shared_key_deleter(struct SharedKey* s); + +extern void curve25519_deinitialize(void); /*! * \brief get_curve25519_implementation diff --git a/libcmix-crypto/curve25519/null/null_curve25519.c b/libcmix-crypto/curve25519/null/null_curve25519.c index 63280ec..33fb963 100644 --- a/libcmix-crypto/curve25519/null/null_curve25519.c +++ b/libcmix-crypto/curve25519/null/null_curve25519.c @@ -4,22 +4,28 @@ #include <stddef.h> #include <stdbool.h> -void curve25519_keypair_deleter(struct KeyPair p) {} +void curve25519_initialize(void){} -struct KeyPair curve25519_create_keypair() { +struct KeyPair curve25519_create_keypair(void) { return (struct KeyPair){ NULL, NULL, - 0, - 0 }; } -void curve25519_shared_key_deleter(struct SharedKey s) {} +void curve25519_keypair_deleter(struct KeyPair* p) {} + +void curve25519_get_key_array(char** buffer, size_t* len, void* key) {} + +void curve25519_add_public_share(char** buffer, size_t* len_out, char const* share, size_t in_len, void* pubkey) {} + +void curve25519_shared_key_deleter(struct SharedKey* s) {} + struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order) { return (struct SharedKey){ NULL, - 0 }; } + +void curve25519_deinitialize(void){}
\ No newline at end of file diff --git a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c index e86ec09..06453c5 100644 --- a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c +++ b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c @@ -6,23 +6,21 @@ #include <stddef.h> #include <stdlib.h> -void init() { +void curve25519_initialize(void) { if(sodium_init() == -1) { exit(-1); } } -void curve25519_keypair_deleter(struct KeyPair p) { - sodium_free(p.sec); - free(p.pub); +void curve25519_keypair_deleter(struct KeyPair* p) { + sodium_free(p->sec); + free(p->pub); - p.sec = NULL; - p.pub = NULL; + p->sec = NULL; + p->pub = NULL; } -struct KeyPair curve25519_create_keypair() { - init(); - +struct KeyPair curve25519_create_keypair(void) { unsigned char* sec = (unsigned char*) sodium_malloc(crypto_box_SECRETKEYBYTES); unsigned char* pub = (unsigned char*) malloc(crypto_box_PUBLICKEYBYTES); @@ -32,38 +30,42 @@ struct KeyPair curve25519_create_keypair() { return (struct KeyPair){ sec, pub, - crypto_box_SECRETKEYBYTES, - crypto_box_PUBLICKEYBYTES }; } -void curve25519_shared_key_deleter(struct SharedKey s) { - sodium_free(s.shared); +void curve25519_shared_key_deleter(struct SharedKey* s) { + sodium_free(s->shared); + + s->shared = NULL; +} + +void curve25519_get_key_array(char** buffer, size_t* len, void* key) { - s.shared = NULL; } -struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order) { - init(); +void curve25519_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey) { +} + +struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, void const* pub_key, bool swap_pub_order) { unsigned char* shared = (unsigned char*) sodium_malloc(crypto_generichash_BYTES); crypto_generichash_state h; unsigned char* scalarmult_q = (unsigned char*) sodium_malloc(crypto_scalarmult_BYTES); - if (crypto_scalarmult(scalarmult_q, pair.sec, pub_key) != 0) { + if (crypto_scalarmult(scalarmult_q, (unsigned char const*) pair.sec, (unsigned char const*) pub_key) != 0) { exit(-1); } crypto_generichash_init(&h, NULL, 0U, crypto_generichash_BYTES); crypto_generichash_update(&h, scalarmult_q, crypto_scalarmult_BYTES); if(swap_pub_order) { - crypto_generichash_update(&h, pub_key, crypto_box_PUBLICKEYBYTES); - crypto_generichash_update(&h, pair.pub, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&h, (unsigned char const*) pub_key, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&h, (unsigned char const*) pair.pub, crypto_box_PUBLICKEYBYTES); } else { - crypto_generichash_update(&h, pair.pub, crypto_box_PUBLICKEYBYTES); - crypto_generichash_update(&h, pub_key, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&h, (unsigned char const*) pair.pub, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&h, (unsigned char const*) pub_key, crypto_box_PUBLICKEYBYTES); } crypto_generichash_final(&h, shared, crypto_generichash_BYTES); @@ -71,7 +73,8 @@ struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char return (struct SharedKey){ shared, - crypto_generichash_BYTES }; } +void curve25519_deinitialize(void) {} + diff --git a/libcmix-crypto/elgamal/elgamal.c b/libcmix-crypto/elgamal/elgamal.c index d50126c..8d10789 100644 --- a/libcmix-crypto/elgamal/elgamal.c +++ b/libcmix-crypto/elgamal/elgamal.c @@ -2,11 +2,16 @@ struct Api get_elgamal_implementation() { + elgamal_initialize(); return (struct Api) { + &elgamal_initialize, &elgamal_create_keypair, &elgamal_keypair_deleter, + &elgamal_get_key_array, + &elgamal_add_public_share, &elgamal_derive_shared_key, - &elgamal_shared_key_deleter + &elgamal_shared_key_deleter, + &elgamal_deinitialize }; } diff --git a/libcmix-crypto/elgamal/elgamal.h b/libcmix-crypto/elgamal/elgamal.h index 826ea49..0662827 100644 --- a/libcmix-crypto/elgamal/elgamal.h +++ b/libcmix-crypto/elgamal/elgamal.h @@ -11,16 +11,39 @@ extern "C" { #include "api.h" /*! + * \brief elgamal_initialize initializes the elgamal library + */ +extern void elgamal_initialize(void); + +/*! * \brief elgamal_create_keypair * \return The new keypair */ -extern struct KeyPair elgamal_create_keypair(); +extern struct KeyPair elgamal_create_keypair(void); /*! * \brief elgamal_keypair_deleter * \param p the keypair to be freed */ -extern void elgamal_keypair_deleter(struct KeyPair p); +extern void elgamal_keypair_deleter(struct KeyPair* p); + +/*! + * \brief elgamal_get_pubkey_array + * \param buffer + * \param len + * \param pubkey + */ +extern void elgamal_get_key_array(char** buffer, size_t* len, void* pubkey); + +/*! + * \brief elgamal_add_public_share + * \param buffer + * \param in_len + * \param share + * \param in_len + * \param pubkey + */ +void elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey); /*! * \brief elgamal_derive_shared_key @@ -29,13 +52,18 @@ extern void elgamal_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 elgamal_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order); +extern struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, void const* pub_key, bool swap_pub_order); /*! * \brief elgamal_shared_key_deleter * \param s The shared key to be freed. */ -extern void elgamal_shared_key_deleter(struct SharedKey s); +extern void elgamal_shared_key_deleter(struct SharedKey* s); + +/*! + * \brief elgamal_deinitialize deinitializes the elgamal_library + */ +void elgamal_deinitialize(void); /*! * \brief get_elgamal_implementation diff --git a/libcmix-crypto/elgamal/gcrypt/CMakeLists.txt b/libcmix-crypto/elgamal/gcrypt/CMakeLists.txt new file mode 100644 index 0000000..826eee4 --- /dev/null +++ b/libcmix-crypto/elgamal/gcrypt/CMakeLists.txt @@ -0,0 +1,19 @@ +include(get_target_name) + +get_target_name(target_name) + +find_package(Gcrypt REQUIRED) + +add_library(${target_name} SHARED + gcrypt_elgamal.c +) + +target_compile_options(${target_name} + PRIVATE -std=c99 + PUBLIC ${Gcrypt_CFLAGS} +) + +target_link_libraries(${target_name} + PRIVATE elgamal-interface + PUBLIC ${Gcrypt_LIBRARIES} +) diff --git a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c new file mode 100644 index 0000000..113fb95 --- /dev/null +++ b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c @@ -0,0 +1,137 @@ + +#include "api.h" + +#include "gcrypt.h" + +#include <stddef.h> +#include <stdbool.h> + +static gcry_mpi_t p; +static gcry_mpi_t q; +static gcry_mpi_t g; + +void check(gcry_error_t error) { + if (error) { + fprintf (stderr, "Error: %s/%s\n", gcry_strsource (error), gcry_strerror (error)); + exit(1); + } +} + +void print_sexp(gcry_sexp_t exp) { + size_t required_size = gcry_sexp_sprint(exp, GCRYSEXP_FMT_ADVANCED, NULL, 0); //passing NULL as the buffer will return the size needed. + + char* str = (char *) malloc(sizeof(char)*required_size); + + gcry_sexp_sprint(exp, GCRYSEXP_FMT_ADVANCED, str, 2000); //So we ignore the size here. + + printf("size = %zu\n", required_size); + for(size_t i = 0; i < required_size; i++) + printf("%c", str[i]); + printf("\n"); + + free(str); +} + +void elgamal_initialize(void) { + if (!gcry_check_version (GCRYPT_VERSION)) { + fprintf(stderr, "libgcrypt version mismatch\n"); + exit(-1); + } + + gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + gcry_control (GCRYCTL_RESUME_SECMEM_WARN); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + //leading as specified by libgcrypt + char p_hex[] = "0087A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597"; + char q_hex[] = "008CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3"; + char g_hex[] = "003FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659"; + + size_t nr_bytes_scanned; + gcry_error_t error; + + error = gcry_mpi_scan(&p, GCRYMPI_FMT_HEX, p_hex, 0, &nr_bytes_scanned); + check(error); + + error = gcry_mpi_scan(&q, GCRYMPI_FMT_HEX, q_hex, 0, &nr_bytes_scanned); + check(error); + + error = gcry_mpi_scan(&g, GCRYMPI_FMT_HEX, g_hex, 0, &nr_bytes_scanned); + check(error); +} + +struct KeyPair elgamal_create_keypair() { + + size_t parse_error_offset; + gcry_error_t error; + + void* bytes = gcry_random_bytes_secure(2048/8, GCRY_VERY_STRONG_RANDOM); + gcry_mpi_t x = gcry_mpi_snew(2048); + error = gcry_mpi_scan(&x, GCRYMPI_FMT_USG, bytes, 2048/8, &parse_error_offset); + check(error); + + gcry_mpi_t y = gcry_mpi_new(0); + gcry_mpi_powm(y, g, x, p); + + gcry_sexp_t priv_key; + error = gcry_sexp_build(&priv_key, &parse_error_offset, "(private-key (elg (p %M) (g %M) (y %M) (x %M)))", p, g, y, x); + check(error); + + error = gcry_pk_testkey(priv_key); + check(error); + + return (struct KeyPair){ + x, + y, + }; +} + +void elgamal_keypair_deleter(struct KeyPair* p) { + gcry_mpi_release((gcry_mpi_t) p->sec); + gcry_mpi_release((gcry_mpi_t) p->pub); + p->sec = NULL; + p->pub = NULL; +} + +void elgamal_get_key_array(unsigned char** buffer, size_t* len, void* pubkey) { + gcry_mpi_t mpi = (gcry_mpi_t) pubkey; + + gcry_error_t error; + + error = gcry_mpi_aprint(GCRYMPI_FMT_USG, buffer, len, mpi); + check(error); +} + +void elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey) { + + gcry_error_t error; + + gcry_mpi_t y = (gcry_mpi_t) pubkey; + + gcry_mpi_t mpi_share; + size_t parse_error_pos; + error = gcry_mpi_scan(&mpi_share, GCRYMPI_FMT_USG, share, in_len, &parse_error_pos); + check(error); + + gcry_mpi_t result = gcry_mpi_new(0); + gcry_mpi_mulm(result, mpi_share, y, p); + + error = gcry_mpi_aprint(GCRYMPI_FMT_USG, (unsigned char**) buffer, out_len, result); + check(error); +} + +void elgamal_shared_key_deleter(struct SharedKey* s) { + gcry_mpi_release((gcry_mpi_t) s->shared); + s->shared = NULL; +} + +struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, void const* pub_key, bool swap_pub_order) { + + + return (struct SharedKey){ + NULL, + }; +} + +void elgamal_deinitialize(void) {} diff --git a/libcmix-crypto/elgamal/null/null_elgamal.c b/libcmix-crypto/elgamal/null/null_elgamal.c index 285e2fd..17478e1 100644 --- a/libcmix-crypto/elgamal/null/null_elgamal.c +++ b/libcmix-crypto/elgamal/null/null_elgamal.c @@ -4,22 +4,27 @@ #include <stddef.h> #include <stdbool.h> +void elgamal_initialize(void) {} + void elgamal_keypair_deleter(struct KeyPair p) {} struct KeyPair elgamal_create_keypair() { return (struct KeyPair){ NULL, NULL, - 0, - 0 }; } -void elgamal_shared_key_deleter(struct SharedKey s) {} +void elgamal_get_key_array(char** buffer, size_t* len, void* pubkey) {} + +void elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey) {} -struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, unsigned char const* pub_key, bool swap_pub_order) { +struct SharedKey elgamal_derive_shared_key(struct KeyPair pair, void const* pub_key, bool swap_pub_order) { return (struct SharedKey){ NULL, - 0 }; } + +void elgamal_shared_key_deleter(struct SharedKey* s) {} + +void elgamal_deinitialize(void) {} diff --git a/libcmix-crypto/keypair.h b/libcmix-crypto/keypair.h index 838291d..3b6e0d1 100644 --- a/libcmix-crypto/keypair.h +++ b/libcmix-crypto/keypair.h @@ -17,10 +17,8 @@ extern "C" { * responsible for memory meanagement. See the Api struct for examples of this. */ struct KeyPair { - unsigned char* sec; ///< Private key - unsigned char* pub; ///< Public key - unsigned int sec_len; ///< Private key length - unsigned int pub_len; ///< Public key length + void* sec; ///< Private key + void* pub; ///< Public key }; diff --git a/libcmix-crypto/sharedkey.h b/libcmix-crypto/sharedkey.h index c37ae41..b89cb5b 100644 --- a/libcmix-crypto/sharedkey.h +++ b/libcmix-crypto/sharedkey.h @@ -14,8 +14,7 @@ extern "C" { * Stored the derived shared secret after for instance Diffie-Hellman. */ struct SharedKey { - unsigned char* shared; ///< The Shared key. - unsigned int shared_len; ///< The shared key length. + void* shared; ///< The Shared key. }; #ifdef __cplusplus diff --git a/libcmix-network/CMakeLists.txt b/libcmix-network/CMakeLists.txt index 057061c..cfe02f1 100644 --- a/libcmix-network/CMakeLists.txt +++ b/libcmix-network/CMakeLists.txt @@ -29,6 +29,14 @@ target_link_libraries(cmix-network PUBLIC log ) +option(enable_asio_handler_debug "Enable Asio handler logging to stderr" off) + +if(enable_asio_handler_debug) + target_compile_definitions(cmix-network + PUBLIC BOOST_ASIO_ENABLE_HANDLER_TRACKING + ) +endif(enable_asio_handler_debug) + if(WIN32) target_include_directories(cmix-network PUBLIC ${OPENSSL_INCLUDE_DIRS} diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp index 2501908..df8c0c4 100644 --- a/libcmix-network/client.hpp +++ b/libcmix-network/client.hpp @@ -174,6 +174,7 @@ public: * \param message_handler The function to call when a message has been received. */ void async_receive(MessageHandler message_handler) { + BOOST_LOG_TRIVIAL(trace) << socket.get(); using namespace boost::asio::placeholders; boost::asio::async_read( @@ -268,7 +269,7 @@ struct SSLClient : private BaseClient<boost::asio::ssl::stream<boost::asio::ip:: * \brief close Closes the underlying socket. */ void close() { - socket->lowest_layer().close(); + socket->lowest_layer().cancel(); } using BaseClient::on_done; diff --git a/libcmix-network/connect.cpp b/libcmix-network/connect.cpp index 9df9b56..e80a6d4 100644 --- a/libcmix-network/connect.cpp +++ b/libcmix-network/connect.cpp @@ -6,6 +6,8 @@ #include <boost/asio/ip/address.hpp> #include <boost/asio/ssl.hpp> +#include <iostream> + using namespace boost::asio::ip; using namespace boost::asio; using boost::asio::io_service; @@ -69,8 +71,10 @@ void async_connect_iteration(basic_socket<tcp, stream_socket_service<tcp>>& sock info->retry_timer.expires_from_now(boost::posix_time::seconds(seconds_to_wait)); info->retry_timer.async_wait([&socket, info, on_connect](boost::system::error_code const& ec){ - if(ec) { - BOOST_LOG_TRIVIAL(error) << "Something went wrong with the retry timer: " << ec; + if(ec == boost::system::errc::operation_canceled) { + return; + } else if(ec) { + BOOST_LOG_TRIVIAL(error) << "Something went wrong with the retry timer: " << ec.message(); } else { async_connect_iteration(socket, info, on_connect); } @@ -83,9 +87,11 @@ void async_connect_iteration(basic_socket<tcp, stream_socket_service<tcp>>& sock } } else if(ec) { BOOST_LOG_TRIVIAL(info) << ec << std::endl; + info->retry_timer.cancel(); info->it++; async_connect_iteration(socket, info, on_connect); } else { + info->retry_timer.cancel(); on_connect(); } }; diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto index b57c86f..3be8b71 100644 --- a/libcmix-protobuf/cmix.proto +++ b/libcmix-protobuf/cmix.proto @@ -24,6 +24,10 @@ message KeyExchange { required bytes public_key = 1; } +message NodeReady { + +} + message CMixMessage { oneof contents { Initialization initialization = 1; @@ -32,5 +36,6 @@ message CMixMessage { ImAClient imaclient = 4; Bye bye = 5; KeyExchange keyexchange = 6; + NodeReady nodeready = 7; } } diff --git a/node/node.cpp b/node/node.cpp index 2dfbba8..857d5af 100644 --- a/node/node.cpp +++ b/node/node.cpp @@ -31,7 +31,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se } Node::~Node() { - api.free_key_pair(keypair); + api.free_key_pair(&keypair); } void Node::run() { @@ -68,46 +68,35 @@ void Node::connect_to_next_node() void Node::start_initialisation() { cmix_proto::Initialization init; - init.set_public_share(keypair.pub, keypair.pub_len); + char* pub_key; + size_t len; + api.get_key_array(&pub_key, &len, keypair.pub); + init.set_public_share(pub_key, len); + free(pub_key); + + BOOST_LOG_TRIVIAL(trace) << "Sending intialization as first node"; next_node.async_send(init); } void Node::handle_node_initialization(const cmix_proto::Initialization& init) { - if(init.public_share().size() != keypair.pub_len) { - prev_node.close(); - cmix_proto::Bye bye; - next_node.async_send(bye, [this]{io_service.stop();}); - BOOST_LOG_TRIVIAL(fatal) << "Previous node dit not send proper initialization message."; - return; - } - if(network_settings.is_first) { cmix_proto::SecretKey sec; sec.set_secret_key(network_key.data(), network_key.size()); next_node.async_send(sec); } else { - Bignum shared = allocate_bignum(init.public_share().size()); - std::copy_n(init.public_share().data(), init.public_share().size(), shared.data); - Bignum my_share = allocate_bignum(keypair.pub_len); - std::copy_n(my_share.data, my_share.len, keypair.pub); - Bignum mod = allocate_bignum(keypair.pub_len); - get_curve25519_mod(&mod); - Bignum new_shared = allocate_bignum(keypair.pub_len); - - calculate_shared_key_part(&new_shared, shared, my_share, mod); + char* buffer; + size_t len; + api.add_public_share(&buffer, &len, init.public_share().c_str(), init.public_share().size(), keypair.pub); cmix_proto::Initialization init; - init.set_public_share(new_shared.data, new_shared.len); + init.set_public_share(buffer, len); + free(buffer); + BOOST_LOG_TRIVIAL(trace) << "Sending intialization"; next_node.async_send(init); - - free_bignum(&shared); - free_bignum(&my_share); - free_bignum(&mod); - free_bignum(&new_shared); } } @@ -154,7 +143,14 @@ void Node::handle_client_keyexchange(ClientConnections::key_type handle, cmix_pr data[handle].shared_value = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), true); cmix_proto::KeyExchange exchange; - exchange.set_public_key(keypair.pub, keypair.pub_len); + + char* buffer; + size_t len; + api.get_key_array(&buffer, &len, keypair.pub); + + exchange.set_public_key(buffer, len); + free(buffer); + clients.at(handle).async_send(exchange); } @@ -188,7 +184,7 @@ void Node::handle_client_message(ClientConnections::key_type handle, cmix_proto: void Node::handle_imanode(Purgatory::iterator handle) { handle->on_done([]{}); - prev_node = SSLReceiver(std::move(*handle)); + prev_node = std::move(*handle); purgatory.erase(handle); if(network_settings.is_first) { @@ -204,11 +200,12 @@ void Node::handle_imanode(Purgatory::iterator handle) { void Node::handle_imaclient(Purgatory::iterator handle, cmix_proto::ImAClient c) { std::string client_id = c.id(); - clients.emplace(c.id(), SSLSenderReceiver(std::move(*handle))); + clients.emplace(c.id(), std::move(*handle)); clients.at(c.id()).on_done([this, client_id]{ clients.erase(client_id); }); purgatory.erase(handle); + clients.at(c.id()).async_send(cmix_proto::NodeReady()); clients.at(c.id()).async_receive([this, client_id](cmix_proto::CMixMessage message) { handle_client_message(client_id, message); }); diff --git a/scratchpad/CMakeLists.txt b/scratchpad/CMakeLists.txt index d1e4223..c1e2c75 100644 --- a/scratchpad/CMakeLists.txt +++ b/scratchpad/CMakeLists.txt @@ -1,4 +1,6 @@ +find_package(Gcrypt REQUIRED) + add_executable(scratchpad scratchpad.c ) @@ -7,7 +9,12 @@ target_compile_options(scratchpad PRIVATE -std=c99 ) +target_compile_options(scratchpad + PRIVATE ${Gcrypt_CFLAGS} +) + target_link_libraries(scratchpad PRIVATE cmix PRIVATE cmix-crypto + PRIVATE ${Gcrypt_LIBRARIES} ) diff --git a/scratchpad/scratchpad.c b/scratchpad/scratchpad.c index c0730fd..aadf3f0 100644 --- a/scratchpad/scratchpad.c +++ b/scratchpad/scratchpad.c @@ -2,14 +2,125 @@ #include "cmix.h" #include "message.h" -#include "curve25519.h" +#include "api.h" + +#include <gcrypt.h> #include <stdio.h> #include <string.h> +void cmix_buffer_scratch(); +void crypto_api_scratch(); +void gcrypt_scratch(); + int main(int argc, char* argv[]) { + gcrypt_scratch(); - struct Api api = get_curve25519_implementation(); + return 0; +} + +void check(gcry_error_t error) { + if (error) { + fprintf (stderr, "Error: %s/%s\n", gcry_strsource (error), gcry_strerror (error)); + exit(1); + } +} + +void print_sexp(gcry_sexp_t exp) { + size_t required_size = gcry_sexp_sprint(exp, GCRYSEXP_FMT_ADVANCED, NULL, 0); //passing NULL as the buffer will return the size needed. + + char* str = (char *) malloc(sizeof(char)*required_size); + + gcry_sexp_sprint(exp, GCRYSEXP_FMT_ADVANCED, str, 2000); //So we ignore the size here. + + printf("size = %zu\n", required_size); + for(size_t i = 0; i < required_size; i++) + printf("%c", str[i]); + printf("\n"); + + free(str); +} + +void gcrypt_scratch() { + + if (!gcry_check_version (GCRYPT_VERSION)) { + fprintf(stderr, "libgcrypt version mismatch\n"); + exit(-1); + } + + gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + gcry_control (GCRYCTL_RESUME_SECMEM_WARN); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + size_t parse_error_offset; + gcry_error_t error; + + gcry_sexp_t key_generator; + error = gcry_sexp_build(&key_generator, &parse_error_offset, "(genkey (%s (nbits %s)))", "elg", "2048"); + check(error); + + gcry_sexp_t key_pair; + error = gcry_pk_genkey(&key_pair, key_generator); + check(error); + + gcry_sexp_t pub_key = gcry_sexp_find_token(key_pair, "public-key", 0); + gcry_sexp_t sec_key = gcry_sexp_find_token(key_pair, "private-key", 0); + + char message_string[] = "hello world!"; + + gcry_sexp_t message; + error = gcry_sexp_build(&message, &parse_error_offset, "(data (flags %s) (value %b))", "raw", sizeof(message_string), message_string); + check(error); + + gcry_sexp_t cipher; + error = gcry_pk_encrypt(&cipher, message, pub_key); + check(error); + + gcry_sexp_t raw_cipher; + raw_cipher = gcry_sexp_find_token(cipher, "elg", 0); + + gcry_sexp_t decryption_sexpr; + error = gcry_sexp_build(&decryption_sexpr, &parse_error_offset, "(enc-val (flags %s) %S)", "raw", raw_cipher); + check(error); + + gcry_sexp_t plain_sexpr; + error = gcry_pk_decrypt(&plain_sexpr, decryption_sexpr, sec_key); + check(error); + + print_sexp(plain_sexpr); + + gcry_sexp_release(key_generator); + gcry_sexp_release(key_pair); + gcry_sexp_release(pub_key); + gcry_sexp_release(sec_key); + gcry_sexp_release(message); + gcry_sexp_release(cipher); + gcry_sexp_release(raw_cipher); + gcry_sexp_release(decryption_sexpr); + gcry_sexp_release(plain_sexpr); +} + +void cmix_buffer_scratch() { + struct CmixBufferImpl buffer_impl = get_cmix_Curve25519_buffer_implementation(); + char* buffer = buffer_impl.allocate_cmix_buffer(3); + + int message_size = buffer_impl.message_length(); + + for(int i=0; i < 3; i++) { + buffer[i*message_size] = 'h'; + } + + for(int i=0; i < 3; i++) { + putc(buffer[i*message_size], stdout); + putc('\n', stdout); + } + + buffer_impl.deallocate_cmix_buffer(buffer); +} + +void crypto_api_scratch() { + struct Api api = get_implementation(); struct KeyPair pair1 = api.create_key_pair(); struct KeyPair pair2 = api.create_key_pair(); @@ -17,34 +128,24 @@ int main(int argc, char* argv[]) { struct SharedKey sk1 = api.derive_shared_key(pair1, pair2.pub, false); struct SharedKey sk2 = api.derive_shared_key(pair2, pair1.pub, true); - if(memcmp(sk1.shared, sk2.shared, sk1.shared_len) != 0) { + char* buffer1; + size_t len1; + api.get_key_array(&buffer1, &len1, sk1.shared); + + char* buffer2; + size_t len2; + api.get_key_array(&buffer2, &len2, sk2.shared); + + if(len1 == len2 && memcmp(buffer1, buffer2, len1) != 0) { exit(-1); } else { printf("Yoepie!"); } - api.free_key_pair(pair1); - api.free_key_pair(pair2); - - api.free_shared_key(sk1); - api.free_shared_key(sk2); + api.free_key_pair(&pair1); + api.free_key_pair(&pair2); - -// struct CmixBufferImpl buffer_impl = get_cmix_Curve25519_buffer_implementation(); -// char* buffer = buffer_impl.allocate_cmix_buffer(3); - -// int message_size = buffer_impl.message_length(); - -// for(int i=0; i < 3; i++) { -// buffer[i*message_size] = 'h'; -// } + api.free_shared_key(&sk1); + api.free_shared_key(&sk2); -// for(int i=0; i < 3; i++) { -// putc(buffer[i*message_size], stdout); -// putc('\n', stdout); -// } - -// buffer_impl.deallocate_cmix_buffer(buffer); - - return 0; } |
