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
|
||||
* @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.
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#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];
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue