Made the stream methods more generic

This commit is contained in:
John Jones 2017-03-09 10:00:45 -05:00
parent 40fc7d91f6
commit d0512d9084
6 changed files with 47 additions and 26 deletions

View file

@ -20,7 +20,7 @@
* @param data_length the length of the data * @param data_length the length of the data
* @returns the number of bytes written * @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 * Write to an open multistream host
* @param socket_fd the socket file descriptor * @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 * @param results_size the size of the results in bytes
* @returns true(1) on success, otherwise false(0) * @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. * Connect to a multistream host, and this includes the multistream handshaking.

View file

@ -16,7 +16,7 @@ struct Stream {
* @param bytes_read how many bytes were read * @param bytes_read how many bytes were read
* @returns true(1) on success, false(0) otherwise * @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 * Writes to a stream
@ -25,12 +25,12 @@ struct Stream {
* @param how much to write * @param how much to write
* @returns true(1) on success, false(0) otherwise * @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 * Closes a stream
* @param stream the stream * @param stream the stream
* @returns true(1) on success, otherwise false(0) * @returns true(1) on success, otherwise false(0)
*/ */
int (*close)(struct Stream* stream); int (*close)(void* stream_context);
}; };

View file

@ -15,7 +15,9 @@ struct SecureSession {
int port; int port;
enum IPTrafficType traffic_type; enum IPTrafficType traffic_type;
// once the connection is established // once the connection is established
struct Stream* stream; struct Stream* insecure_stream;
struct Stream* secure_stream;
struct Stream* default_stream;
// filled in during negotiations // filled in during negotiations
char* chosen_curve; char* chosen_curve;
char* chosen_cipher; char* chosen_cipher;

View file

@ -7,6 +7,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include "libp2p/net/p2pnet.h" #include "libp2p/net/p2pnet.h"
#include "libp2p/record/message.h" #include "libp2p/record/message.h"
#include "libp2p/secio/secio.h"
#include "varint.h" #include "varint.h"
#include "libp2p/net/multistream.h" #include "libp2p/net/multistream.h"
@ -14,7 +15,9 @@
* An implementation of the libp2p multistream * 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); close((intptr_t)stream->socket_descriptor);
return 1; return 1;
} }
@ -26,7 +29,9 @@ int libp2p_net_multistream_close(struct Stream* stream) {
* @param data_length the length of the data * @param data_length the length of the data
* @returns the number of bytes written * @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; int num_bytes = 0;
if (data_length > 0) { // only do this is if there is something to send 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 * @param results_size the size of the results in bytes
* @returns number of bytes received * @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; int bytes = 0;
size_t buffer_size = 65535; size_t buffer_size = 65535;
char buffer[buffer_size]; char buffer[buffer_size];

View file

@ -33,7 +33,8 @@ struct SecureSession* libp2p_secio_secure_session_new() {
struct SecureSession* ss = (struct SecureSession*) malloc(sizeof(struct SecureSession)); struct SecureSession* ss = (struct SecureSession*) malloc(sizeof(struct SecureSession));
if (ss == NULL) if (ss == NULL)
return NULL; return NULL;
ss->stream = NULL; ss->insecure_stream = NULL;
ss->secure_stream = NULL;
return ss; 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) * @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 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* k1;
struct StretchedKey* k2; struct StretchedKey* k2;
unsigned char* result = NULL;; unsigned char* result = NULL;;
size_t result_size = 0; 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"; char* seed = "key expansion";
unsigned char* temp = NULL; unsigned char* temp = NULL;
unsigned char a_hash[32]; unsigned char a_hash[32];
@ -273,6 +273,8 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s
goto exit; goto exit;
} }
// pick the right hash // pick the right hash
// TODO: this
/*
if (strcmp(hashType, "SHA1") == 0) { if (strcmp(hashType, "SHA1") == 0) {
hash_func = libp2p_crypto_hashing_sha1; hash_func = libp2p_crypto_hashing_sha1;
hash_size = 40; hash_size = 40;
@ -285,6 +287,7 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s
} else { } else {
goto exit; goto exit;
} }
*/
//TODO: make this work for all hashes, not just SHA256 //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 = 0;
int written_this_time = 0; int written_this_time = 0;
do { 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) { if (written_this_time < 0) {
written_this_time = 0; written_this_time = 0;
if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
@ -433,7 +436,7 @@ int libp2p_secio_unencrypted_write(struct SecureSession* session, unsigned char*
left = data_length; left = data_length;
written = 0; written = 0;
do { 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) { if (written_this_time < 0) {
written_this_time = 0; written_this_time = 0;
if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
@ -467,7 +470,7 @@ int libp2p_secio_unencrypted_read(struct SecureSession* session, unsigned char**
int read = 0; int read = 0;
int read_this_time = 0; int read_this_time = 0;
do { 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) { if (read_this_time < 0) {
read_this_time = 0; read_this_time = 0;
if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
@ -496,7 +499,7 @@ int libp2p_secio_unencrypted_read(struct SecureSession* session, unsigned char**
*results = malloc(left); *results = malloc(left);
unsigned char* ptr = *results; unsigned char* ptr = *results;
do { 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) { if (read_this_time < 0) {
read_this_time = 0; read_this_time = 0;
if ( (errno == EAGAIN) || (errno == EWOULDBLOCK)) { 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 * @param num_bytes the number of bytes to write
* @returns the number of bytes written * @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 // writer uses the local cipher and mac
unsigned char* buffer = NULL; unsigned char* buffer = NULL;
size_t buffer_size = 0; 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 * @param num_bytes the number of bytes read from the stream
* @returns the number of bytes read * @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 // reader uses the remote cipher and mac
// read the data // read the data
unsigned char* incoming = NULL; 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, protocol_len);
memcpy(&total[protocol_len], propose_out_bytes, propose_out_size); 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); free(total);
if (bytes_written <= 0) if (bytes_written <= 0)
goto exit; goto exit;
if (!remote_requested) { if (!remote_requested) {
// we should get back the secio confirmation // 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) if (bytes_written < 5 || strstr((char*)results, "secio") == NULL)
goto exit; 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; 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); 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_length = propose_in_size + propose_out_size + local_session->remote_ephemeral_public_key_size - 1;
char_buffer = malloc(char_buffer_length); char_buffer = malloc(char_buffer_length);
if (char_buffer == NULL) 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) if (libp2p_secio_bytes_compare((char*)results, local_session->local_nonce, 16) != 0)
goto exit; 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; retVal = 1;
exit: exit:

View file

@ -43,13 +43,13 @@ int test_secio_handshake() {
if (!libp2p_crypto_rsa_private_key_fill_public_key(rsa_private_key)) if (!libp2p_crypto_rsa_private_key_fill_public_key(rsa_private_key))
goto exit; goto exit;
secure_session.host = "10.0.1.11"; secure_session.host = "www.jmjatlanta.com";
//secure_session.host = "127.0.0.1"; //secure_session.host = "127.0.0.1";
secure_session.port = 4001; secure_session.port = 4001;
secure_session.traffic_type = TCP; secure_session.traffic_type = TCP;
// connect to host // connect to host
secure_session.stream = libp2p_net_multistream_connect(secure_session.host, secure_session.port); secure_session.insecure_stream = libp2p_net_multistream_connect(secure_session.host, secure_session.port);
if (*((int*)secure_session.stream->socket_descriptor) == -1) { if (*((int*)secure_session.insecure_stream->socket_descriptor) == -1) {
fprintf(stderr, "test_secio_handshake: Unable to get socket descriptor\n"); fprintf(stderr, "test_secio_handshake: Unable to get socket descriptor\n");
goto exit; goto exit;
} }
@ -62,8 +62,8 @@ int test_secio_handshake() {
retVal = 1; retVal = 1;
exit: exit:
if (secure_session.stream != NULL) if (secure_session.insecure_stream != NULL)
libp2p_net_multistream_stream_free(secure_session.stream); libp2p_net_multistream_stream_free(secure_session.insecure_stream);
if (secure_session.local_stretched_key != NULL) if (secure_session.local_stretched_key != NULL)
libp2p_crypto_ephemeral_stretched_key_free(secure_session.local_stretched_key); libp2p_crypto_ephemeral_stretched_key_free(secure_session.local_stretched_key);
if (secure_session.remote_stretched_key != NULL) if (secure_session.remote_stretched_key != NULL)