Made the stream methods more generic
This commit is contained in:
parent
40fc7d91f6
commit
d0512d9084
6 changed files with 47 additions and 26 deletions
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue