From d0512d90847dbc95283e1f5f38afbda1adedccd8 Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 9 Mar 2017 10:00:45 -0500 Subject: [PATCH] Made the stream methods more generic --- include/libp2p/net/multistream.h | 4 ++-- include/libp2p/net/stream.h | 6 +++--- include/libp2p/secio/secio.h | 4 +++- net/multistream.c | 13 +++++++++--- secio/secio.c | 36 +++++++++++++++++++++----------- test/test_secio.h | 10 ++++----- 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/include/libp2p/net/multistream.h b/include/libp2p/net/multistream.h index e4aa850..57125ed 100644 --- a/include/libp2p/net/multistream.h +++ b/include/libp2p/net/multistream.h @@ -20,7 +20,7 @@ * @param data_length the length of the data * @returns the number of bytes written */ -int libp2p_net_multistream_read(struct Stream* stream, unsigned char** data, size_t* data_length); +int libp2p_net_multistream_read(void* stream_context, unsigned char** data, size_t* data_length); /** * Write to an open multistream host * @param socket_fd the socket file descriptor @@ -28,7 +28,7 @@ int libp2p_net_multistream_read(struct Stream* stream, unsigned char** data, siz * @param results_size the size of the results in bytes * @returns true(1) on success, otherwise false(0) */ -int libp2p_net_multistream_write(struct Stream* stream, const unsigned char* data, size_t data_size); +int libp2p_net_multistream_write(void* stream_context, const unsigned char* data, size_t data_size); /** * Connect to a multistream host, and this includes the multistream handshaking. diff --git a/include/libp2p/net/stream.h b/include/libp2p/net/stream.h index 0445585..2f01195 100644 --- a/include/libp2p/net/stream.h +++ b/include/libp2p/net/stream.h @@ -16,7 +16,7 @@ struct Stream { * @param bytes_read how many bytes were read * @returns true(1) on success, false(0) otherwise */ - int (*read)(struct Stream* stream, unsigned char** buffer, size_t* bytes_read); + int (*read)(void* stream_context, unsigned char** buffer, size_t* bytes_read); /** * Writes to a stream @@ -25,12 +25,12 @@ struct Stream { * @param how much to write * @returns true(1) on success, false(0) otherwise */ - int (*write)(struct Stream* stream, const unsigned char* buffer, size_t buffer_size); + int (*write)(void* stream_context, const unsigned char* buffer, size_t buffer_size); /** * Closes a stream * @param stream the stream * @returns true(1) on success, otherwise false(0) */ - int (*close)(struct Stream* stream); + int (*close)(void* stream_context); }; diff --git a/include/libp2p/secio/secio.h b/include/libp2p/secio/secio.h index e57274d..e2ec457 100644 --- a/include/libp2p/secio/secio.h +++ b/include/libp2p/secio/secio.h @@ -15,7 +15,9 @@ struct SecureSession { int port; enum IPTrafficType traffic_type; // once the connection is established - struct Stream* stream; + struct Stream* insecure_stream; + struct Stream* secure_stream; + struct Stream* default_stream; // filled in during negotiations char* chosen_curve; char* chosen_cipher; diff --git a/net/multistream.c b/net/multistream.c index 5884cf6..300ead2 100644 --- a/net/multistream.c +++ b/net/multistream.c @@ -7,6 +7,7 @@ #include #include "libp2p/net/p2pnet.h" #include "libp2p/record/message.h" +#include "libp2p/secio/secio.h" #include "varint.h" #include "libp2p/net/multistream.h" @@ -14,7 +15,9 @@ * An implementation of the libp2p multistream */ -int libp2p_net_multistream_close(struct Stream* stream) { +int libp2p_net_multistream_close(void* stream_context) { + struct SecureSession* secure_context = (struct SecureSession*)stream_context; + struct Stream* stream = secure_context->insecure_stream; close((intptr_t)stream->socket_descriptor); return 1; } @@ -26,7 +29,9 @@ int libp2p_net_multistream_close(struct Stream* stream) { * @param data_length the length of the data * @returns the number of bytes written */ -int libp2p_net_multistream_write(struct Stream* stream, const unsigned char* data, size_t data_length) { +int libp2p_net_multistream_write(void* stream_context, const unsigned char* data, size_t data_length) { + struct SecureSession* secure_context = (struct SecureSession*)stream_context; + struct Stream* stream = secure_context->insecure_stream; int num_bytes = 0; if (data_length > 0) { // only do this is if there is something to send @@ -51,7 +56,9 @@ int libp2p_net_multistream_write(struct Stream* stream, const unsigned char* dat * @param results_size the size of the results in bytes * @returns number of bytes received */ -int libp2p_net_multistream_read(struct Stream* stream, unsigned char** results, size_t* results_size) { +int libp2p_net_multistream_read(void* stream_context, unsigned char** results, size_t* results_size) { + struct SecureSession* secure_context = (struct SecureSession*)stream_context; + struct Stream* stream = secure_context->insecure_stream; int bytes = 0; size_t buffer_size = 65535; char buffer[buffer_size]; diff --git a/secio/secio.c b/secio/secio.c index 87689f5..81c7d87 100644 --- a/secio/secio.c +++ b/secio/secio.c @@ -33,7 +33,8 @@ struct SecureSession* libp2p_secio_secure_session_new() { struct SecureSession* ss = (struct SecureSession*) malloc(sizeof(struct SecureSession)); if (ss == NULL) return NULL; - ss->stream = NULL; + ss->insecure_stream = NULL; + ss->secure_stream = NULL; return ss; } @@ -235,12 +236,11 @@ int libp2p_secio_sign(struct PrivateKey* private_key, const char* in, size_t in_ * @returns true(1) on success, otherwise 0 (false) */ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* secret, size_t secret_size, struct StretchedKey** k1_ptr, struct StretchedKey** k2_ptr) { - int retVal = 0, hash_size = 0, num_filled = 0, hmac_size = 20; + int retVal = 0, num_filled = 0, hmac_size = 20; struct StretchedKey* k1; struct StretchedKey* k2; unsigned char* result = NULL;; size_t result_size = 0; - int (*hash_func)(const unsigned char* input, size_t input_length, unsigned char* results); // pointer to hash function char* seed = "key expansion"; unsigned char* temp = NULL; unsigned char a_hash[32]; @@ -273,6 +273,8 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s goto exit; } // pick the right hash + // TODO: this + /* if (strcmp(hashType, "SHA1") == 0) { hash_func = libp2p_crypto_hashing_sha1; hash_size = 40; @@ -285,6 +287,7 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s } else { goto exit; } + */ //TODO: make this work for all hashes, not just SHA256 @@ -418,7 +421,7 @@ int libp2p_secio_unencrypted_write(struct SecureSession* session, unsigned char* int written = 0; int written_this_time = 0; do { - written_this_time = socket_write(*((int*)session->stream->socket_descriptor), &size_as_char[written], left, 0); + written_this_time = socket_write(*((int*)session->insecure_stream->socket_descriptor), &size_as_char[written], left, 0); if (written_this_time < 0) { written_this_time = 0; if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { @@ -433,7 +436,7 @@ int libp2p_secio_unencrypted_write(struct SecureSession* session, unsigned char* left = data_length; written = 0; do { - written_this_time = socket_write(*((int*)session->stream->socket_descriptor), (char*)&bytes[written], left, 0); + written_this_time = socket_write(*((int*)session->insecure_stream->socket_descriptor), (char*)&bytes[written], left, 0); if (written_this_time < 0) { written_this_time = 0; if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { @@ -467,7 +470,7 @@ int libp2p_secio_unencrypted_read(struct SecureSession* session, unsigned char** int read = 0; int read_this_time = 0; do { - read_this_time = socket_read(*((int*)session->stream->socket_descriptor), &size[read], 1, 0); + read_this_time = socket_read(*((int*)session->insecure_stream->socket_descriptor), &size[read], 1, 0); if (read_this_time < 0) { read_this_time = 0; if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { @@ -496,7 +499,7 @@ int libp2p_secio_unencrypted_read(struct SecureSession* session, unsigned char** *results = malloc(left); unsigned char* ptr = *results; do { - read_this_time = socket_read(*((int*)session->stream->socket_descriptor), (char*)&ptr[read], left, 0); + read_this_time = socket_read(*((int*)session->insecure_stream->socket_descriptor), (char*)&ptr[read], left, 0); if (read_this_time < 0) { read_this_time = 0; if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { @@ -560,7 +563,8 @@ int libp2p_secio_encrypt(const struct SecureSession* session, const unsigned cha * @param num_bytes the number of bytes to write * @returns the number of bytes written */ -int libp2p_secio_encrypted_write(struct SecureSession* session, unsigned char* bytes, size_t num_bytes) { +int libp2p_secio_encrypted_write(void* stream_context, const unsigned char* bytes, size_t num_bytes) { + struct SecureSession* session = (struct SecureSession*) stream_context; // writer uses the local cipher and mac unsigned char* buffer = NULL; size_t buffer_size = 0; @@ -621,7 +625,8 @@ int libp2p_secio_decrypt(const struct SecureSession* session, const unsigned cha * @param num_bytes the number of bytes read from the stream * @returns the number of bytes read */ -int libp2p_secio_encrypted_read(struct SecureSession* session, unsigned char** bytes, size_t* num_bytes) { +int libp2p_secio_encrypted_read(void* stream_context, unsigned char** bytes, size_t* num_bytes) { + struct SecureSession* session = (struct SecureSession*)stream_context; // reader uses the remote cipher and mac // read the data unsigned char* incoming = NULL; @@ -674,14 +679,14 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat memcpy(total, protocol, protocol_len); memcpy(&total[protocol_len], propose_out_bytes, propose_out_size); - bytes_written = libp2p_net_multistream_write(local_session->stream, total, protocol_len + propose_out_size); + bytes_written = libp2p_net_multistream_write(local_session->insecure_stream, total, protocol_len + propose_out_size); free(total); if (bytes_written <= 0) goto exit; if (!remote_requested) { // we should get back the secio confirmation - bytes_written = libp2p_net_multistream_read(local_session->stream, &results, &results_size); + bytes_written = libp2p_net_multistream_read(local_session->insecure_stream, &results, &results_size); if (bytes_written < 5 || strstr((char*)results, "secio") == NULL) goto exit; @@ -836,7 +841,7 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat local_session->remote_ephemeral_public_key[0] = exchange_in->epubkey_size; memcpy(&local_session->remote_ephemeral_public_key[1], exchange_in->epubkey, exchange_in->epubkey_size); - // TODO: signature verification + // signature verification char_buffer_length = propose_in_size + propose_out_size + local_session->remote_ephemeral_public_key_size - 1; char_buffer = malloc(char_buffer_length); if (char_buffer == NULL) @@ -896,6 +901,13 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat if (libp2p_secio_bytes_compare((char*)results, local_session->local_nonce, 16) != 0) goto exit; + // set up the secure stream in the struct + local_session->secure_stream = libp2p_net_multistream_stream_new(*((int*)local_session->insecure_stream->socket_descriptor)); + local_session->secure_stream->read = libp2p_secio_encrypted_read; + local_session->secure_stream->write = libp2p_secio_encrypted_write; + // set secure as default + local_session->default_stream = local_session->secure_stream; + retVal = 1; exit: diff --git a/test/test_secio.h b/test/test_secio.h index d454403..538b644 100644 --- a/test/test_secio.h +++ b/test/test_secio.h @@ -43,13 +43,13 @@ int test_secio_handshake() { if (!libp2p_crypto_rsa_private_key_fill_public_key(rsa_private_key)) goto exit; - secure_session.host = "10.0.1.11"; + secure_session.host = "www.jmjatlanta.com"; //secure_session.host = "127.0.0.1"; secure_session.port = 4001; secure_session.traffic_type = TCP; // connect to host - secure_session.stream = libp2p_net_multistream_connect(secure_session.host, secure_session.port); - if (*((int*)secure_session.stream->socket_descriptor) == -1) { + secure_session.insecure_stream = libp2p_net_multistream_connect(secure_session.host, secure_session.port); + if (*((int*)secure_session.insecure_stream->socket_descriptor) == -1) { fprintf(stderr, "test_secio_handshake: Unable to get socket descriptor\n"); goto exit; } @@ -62,8 +62,8 @@ int test_secio_handshake() { retVal = 1; exit: - if (secure_session.stream != NULL) - libp2p_net_multistream_stream_free(secure_session.stream); + if (secure_session.insecure_stream != NULL) + libp2p_net_multistream_stream_free(secure_session.insecure_stream); if (secure_session.local_stretched_key != NULL) libp2p_crypto_ephemeral_stretched_key_free(secure_session.local_stretched_key); if (secure_session.remote_stretched_key != NULL)