Many fixes around secio
This commit is contained in:
parent
c5fa775534
commit
6d9473069b
22 changed files with 317 additions and 137 deletions
|
@ -8,6 +8,8 @@
|
||||||
#include "libp2p/conn/transport_dialer.h"
|
#include "libp2p/conn/transport_dialer.h"
|
||||||
#include "libp2p/crypto/key.h"
|
#include "libp2p/crypto/key.h"
|
||||||
#include "libp2p/utils/linked_list.h"
|
#include "libp2p/utils/linked_list.h"
|
||||||
|
#include "libp2p/utils/multiaddress.h"
|
||||||
|
#include "libp2p/net/multistream.h"
|
||||||
|
|
||||||
struct TransportDialer* libp2p_conn_tcp_transport_dialer_new();
|
struct TransportDialer* libp2p_conn_tcp_transport_dialer_new();
|
||||||
|
|
||||||
|
@ -60,14 +62,38 @@ void libp2p_conn_dialer_free(struct Dialer* in) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a Connection struct from the dialer
|
* Retrieve a Connection struct from the dialer
|
||||||
|
* NOTE: This should no longer be used. _get_stream should
|
||||||
|
* be used instead (which calls this method internally).
|
||||||
* @param dialer the dialer to use
|
* @param dialer the dialer to use
|
||||||
* @param muiltiaddress who to connect to
|
* @param muiltiaddress who to connect to
|
||||||
* @returns a Connection, or NULL
|
* @returns a Connection, or NULL
|
||||||
*/
|
*/
|
||||||
struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct MultiAddress* multiaddress) {
|
struct Connection* libp2p_conn_dialer_get_connection(const struct Dialer* dialer, const struct MultiAddress* multiaddress) {
|
||||||
struct Connection* conn = libp2p_conn_transport_dialer_get(dialer->transport_dialers, multiaddress);
|
struct Connection* conn = libp2p_conn_transport_dialer_get(dialer->transport_dialers, multiaddress);
|
||||||
if (conn == NULL) {
|
if (conn == NULL) {
|
||||||
conn = dialer->fallback_dialer->dial(dialer->fallback_dialer, multiaddress);
|
conn = dialer->fallback_dialer->dial(dialer->fallback_dialer, multiaddress);
|
||||||
}
|
}
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a Stream that is already set up to use the passed in protocol
|
||||||
|
* @param dialer the dialer to use
|
||||||
|
* @param multiaddress the host to dial
|
||||||
|
* @param protocol the protocol to use (right now only 'multistream' is supported)
|
||||||
|
* @returns the ready-to-use stream
|
||||||
|
*/
|
||||||
|
struct Stream* libp2p_conn_dialer_get_stream(const struct Dialer* dialer, const struct MultiAddress* multiaddress, const char* protocol) {
|
||||||
|
// this is a shortcut for now. Other protocols will soon be implemented
|
||||||
|
if (strcmp(protocol, "multistream") != 0)
|
||||||
|
return NULL;
|
||||||
|
char* ip;
|
||||||
|
int port;
|
||||||
|
if (!libp2p_utils_multiaddress_parse_ip4_tcp(multiaddress, &ip, &port)) {
|
||||||
|
free(ip);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
struct Stream* stream = libp2p_net_multistream_connect(ip, port);
|
||||||
|
free(ip);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
|
@ -6,43 +6,13 @@
|
||||||
#include "libp2p/net/p2pnet.h"
|
#include "libp2p/net/p2pnet.h"
|
||||||
#include "libp2p/conn/connection.h"
|
#include "libp2p/conn/connection.h"
|
||||||
#include "libp2p/conn/transport_dialer.h"
|
#include "libp2p/conn/transport_dialer.h"
|
||||||
|
#include "libp2p/utils/multiaddress.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of a tcp transport dialer
|
* An implementation of a tcp transport dialer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int libp2p_conn_tcp_can_handle(const struct MultiAddress* addr) {
|
||||||
struct TcpIp {
|
|
||||||
char* ip;
|
|
||||||
int port;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TcpIp* libp2p_conn_parse_ip_multiaddress(struct MultiAddress* addr) {
|
|
||||||
struct TcpIp* out = (struct TcpIp*)malloc(sizeof(struct TcpIp));
|
|
||||||
char* address = malloc(strlen(addr->string) + 1);
|
|
||||||
strcpy(address, addr->string);
|
|
||||||
char* tok = strtok(address, "/");
|
|
||||||
int pos = 0;
|
|
||||||
while (tok != NULL) {
|
|
||||||
switch (pos) {
|
|
||||||
case 1: {
|
|
||||||
out->ip = malloc(strlen(tok) + 1);
|
|
||||||
strcpy(out->ip, tok);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
out->port = strtol(tok, NULL, 10);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tok = strtok(NULL, "/");
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
//TODO: do a better job of parsing the results
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int libp2p_conn_tcp_can_handle(struct MultiAddress* addr) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +29,15 @@ int libp2p_conn_tcp_write(const struct Connection* connection, const char* in, s
|
||||||
return bytes == num_bytes;
|
return bytes == num_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Connection* libp2p_conn_tcp_dial(struct TransportDialer* transport_dialer, struct MultiAddress* addr) {
|
struct Connection* libp2p_conn_tcp_dial(const struct TransportDialer* transport_dialer, const struct MultiAddress* addr) {
|
||||||
struct Connection* conn = (struct Connection*) malloc(sizeof(struct Connection*));
|
struct Connection* conn = (struct Connection*) malloc(sizeof(struct Connection*));
|
||||||
conn->socket_handle = socket_open4();
|
conn->socket_handle = socket_open4();
|
||||||
struct TcpIp* results = libp2p_conn_parse_ip_multiaddress(addr);
|
char* ip;
|
||||||
struct hostent* host = gethostbyname(results->ip);
|
int port;
|
||||||
|
libp2p_utils_multiaddress_parse_ip4_tcp(addr, &ip, &port);
|
||||||
|
struct hostent* host = gethostbyname(ip);
|
||||||
struct in_addr** addr_list = (struct in_addr**)host->h_addr_list;
|
struct in_addr** addr_list = (struct in_addr**)host->h_addr_list;
|
||||||
socket_connect4(conn->socket_handle, (*addr_list[0]).s_addr, results->port);
|
socket_connect4(conn->socket_handle, (*addr_list[0]).s_addr, port);
|
||||||
conn->read = libp2p_conn_tcp_read;
|
conn->read = libp2p_conn_tcp_read;
|
||||||
conn->write = libp2p_conn_tcp_write;
|
conn->write = libp2p_conn_tcp_write;
|
||||||
return conn;
|
return conn;
|
||||||
|
|
|
@ -33,8 +33,8 @@ void libp2p_conn_transport_dialer_free(struct TransportDialer* in) {
|
||||||
* @param multiaddr the address
|
* @param multiaddr the address
|
||||||
* @returns a connection, or NULL if no appropriate dialer was found
|
* @returns a connection, or NULL if no appropriate dialer was found
|
||||||
*/
|
*/
|
||||||
struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct MultiAddress* multiaddr) {
|
struct Connection* libp2p_conn_transport_dialer_get(const struct Libp2pLinkedList* transport_dialers, const struct MultiAddress* multiaddr) {
|
||||||
struct Libp2pLinkedList* current = transport_dialers;
|
const struct Libp2pLinkedList* current = transport_dialers;
|
||||||
struct TransportDialer* t_dialer = NULL;
|
struct TransportDialer* t_dialer = NULL;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
t_dialer = (struct TransportDialer*)current->item;
|
t_dialer = (struct TransportDialer*)current->item;
|
||||||
|
|
20
crypto/aes.c
Normal file
20
crypto/aes.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a block of text
|
||||||
|
* @param key the aes key
|
||||||
|
* @param iv the random part of encryption
|
||||||
|
* @param input the text to encrypt
|
||||||
|
* @param input_size the length of the array
|
||||||
|
* @param output where the output will be placed
|
||||||
|
* @param output_size the length of the memory allocated for output
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_aes_encrypt(char* key, char* iv, char* input, size_t input_size, unsigned char* output, size_t* output_size) {
|
||||||
|
mbedtls_aes_context ctx;
|
||||||
|
mbedtls_aes_init(&ctx);
|
||||||
|
mbedtls_aes_setkey_enc(&ctx, key, 256);
|
||||||
|
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 24, iv, input, output);
|
||||||
|
//TODO Implement this method
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
/***
|
/***
|
||||||
* A local dialer. Uses MultiAddr to figure out the best way to
|
* A local dialer. Uses MultiAddr to figure out the best way to
|
||||||
* connect to a client, then returns an open Connection that can be
|
* connect to a client, then returns an open Connection that can be
|
||||||
* closed, read from and written to.
|
* closed, read from and written to. The normal procedure is as follows:
|
||||||
|
* 1) Create a Dialer struct, with the required information about the local host
|
||||||
|
* 2) Call _get_connection to create the connection with a specific host
|
||||||
|
* NOTE: 1 Dialer could be used to create all connections, saving time and resources
|
||||||
|
* if it is not too difficult to pass it around. The struct has enough information to
|
||||||
|
* build connections that negotiate many protocols
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libp2p/crypto/key.h"
|
#include "libp2p/crypto/key.h"
|
||||||
|
@ -29,11 +34,16 @@ struct Dialer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Dialer with the specified local information
|
* Create a Dialer with the specified local information
|
||||||
|
* NOTE: This fills in the fallback_dialer too
|
||||||
|
* @param peer_id the local PeerID
|
||||||
|
* @param private_key the local private key
|
||||||
|
* @returns a new Dialer struct
|
||||||
*/
|
*/
|
||||||
struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_key);
|
struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* free resources from the Dialer
|
* free resources from the Dialer struct
|
||||||
|
* @param in the Dialer struct to relieve of their resources
|
||||||
*/
|
*/
|
||||||
void libp2p_conn_dialer_free(struct Dialer* in);
|
void libp2p_conn_dialer_free(struct Dialer* in);
|
||||||
|
|
||||||
|
@ -43,4 +53,14 @@ void libp2p_conn_dialer_free(struct Dialer* in);
|
||||||
* @param muiltiaddress who to connect to
|
* @param muiltiaddress who to connect to
|
||||||
* @returns a Connection, or NULL
|
* @returns a Connection, or NULL
|
||||||
*/
|
*/
|
||||||
struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct MultiAddress* multiaddress);
|
struct Connection* libp2p_conn_dialer_get_connection(const struct Dialer* dialer, const struct MultiAddress* multiaddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a Stream that is already set up to use the passed in protocol
|
||||||
|
* @param dialer the dialer to use
|
||||||
|
* @param multiaddress the host to dial
|
||||||
|
* @param protocol the protocol to use (right now only 'multistream' is supported)
|
||||||
|
* @returns the ready-to-use stream
|
||||||
|
*/
|
||||||
|
struct Stream* libp2p_conn_dialer_get_stream(const struct Dialer* dialer, const struct MultiAddress* multiaddress, const char* protocol);
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
struct TransportDialer {
|
struct TransportDialer {
|
||||||
char* peer_id;
|
char* peer_id;
|
||||||
struct PrivateKey* private_key;
|
struct PrivateKey* private_key;
|
||||||
int (*can_handle)(struct MultiAddress* multiaddr);
|
int (*can_handle)(const struct MultiAddress* multiaddr);
|
||||||
struct Connection* (*dial)(struct TransportDialer* transport_dialer, struct MultiAddress* multiaddr);
|
struct Connection* (*dial)(const struct TransportDialer* transport_dialer, const struct MultiAddress* multiaddr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransportDialer* libp2p_conn_transport_dialer_new(char* peer_id, struct PrivateKey* private_key);
|
struct TransportDialer* libp2p_conn_transport_dialer_new(char* peer_id, struct PrivateKey* private_key);
|
||||||
void libp2p_conn_transport_dialer_free(struct TransportDialer* in);
|
void libp2p_conn_transport_dialer_free(struct TransportDialer* in);
|
||||||
|
|
||||||
struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct MultiAddress* multiaddr);
|
struct Connection* libp2p_conn_transport_dialer_get(const struct Libp2pLinkedList* transport_dialers, const struct MultiAddress* multiaddr);
|
||||||
|
|
11
include/libp2p/crypto/aes.h
Normal file
11
include/libp2p/crypto/aes.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a block of text
|
||||||
|
* @param input the text to encrypt
|
||||||
|
* @param input_size the length of the array
|
||||||
|
* @param output where the output will be placed
|
||||||
|
* @param output_size the length of the memory allocated for output
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_aes_encrypt(char* input, size_t input_size, unsigned char* output, size_t& output_size);
|
|
@ -11,7 +11,7 @@ struct StretchedKey {
|
||||||
size_t iv_size;
|
size_t iv_size;
|
||||||
char* cipher_key;
|
char* cipher_key;
|
||||||
size_t cipher_size;
|
size_t cipher_size;
|
||||||
char* mac_key;
|
unsigned char* mac_key;
|
||||||
size_t mac_size;
|
size_t mac_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ enum ConnectionType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Libp2pPeer {
|
struct Libp2pPeer {
|
||||||
char* id; // protobuf field 1
|
char* id; // protobuf field 1; the ID (aka peer id) of the peer
|
||||||
size_t id_size;
|
size_t id_size; // the length of id
|
||||||
struct Libp2pLinkedList* addr_head; // protobuf field 2 of multiaddr bytes (repeatable) (stored here as a struct MultiAddr)
|
struct Libp2pLinkedList* addr_head; // protobuf field 2 of multiaddr bytes (repeatable) (stored here as a struct MultiAddr)
|
||||||
enum ConnectionType connection_type; // protobuf field 3 (a varint)
|
enum ConnectionType connection_type; // protobuf field 3 (a varint)
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct SecureSession {
|
||||||
int port;
|
int port;
|
||||||
enum IPTrafficType traffic_type;
|
enum IPTrafficType traffic_type;
|
||||||
// once the connection is established
|
// once the connection is established
|
||||||
int socket_descriptor;
|
struct Stream* stream;
|
||||||
struct PublicKey remote_key;
|
struct PublicKey remote_key;
|
||||||
char* remote_peer_id;
|
char* remote_peer_id;
|
||||||
// filled in during negotiations
|
// filled in during negotiations
|
||||||
|
@ -28,6 +28,8 @@ struct SecureSession {
|
||||||
size_t shared_key_size;
|
size_t shared_key_size;
|
||||||
char nonce[16];
|
char nonce[16];
|
||||||
struct StretchedKey* stretched_key;
|
struct StretchedKey* stretched_key;
|
||||||
|
unsigned char* mac;
|
||||||
|
size_t mac_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
13
include/libp2p/utils/multiaddress.h
Normal file
13
include/libp2p/utils/multiaddress.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "multiaddr/multiaddr.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a hack to get ip4/tcp working
|
||||||
|
* TODO: this should be moved further down in the networking stack and generified for different multiaddresses
|
||||||
|
* This makes too many assumptions
|
||||||
|
* @param address the multiaddress to parse
|
||||||
|
* @param ip the first IP address in the multiaddress
|
||||||
|
* @param port the first port in the multiaddress
|
||||||
|
* @returns true(1) on success, false(0) on failure
|
||||||
|
*/
|
||||||
|
int libp2p_utils_multiaddress_parse_ip4_tcp(const struct MultiAddress* address, char** ip, int* port);
|
|
@ -128,15 +128,15 @@ struct Stream* libp2p_net_multistream_connect(const char* hostname, int port) {
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
num_bytes = libp2p_net_multistream_write(stream, (unsigned char*)protocol_buffer, strlen(protocol_buffer));
|
|
||||||
if (num_bytes <= 0)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
// try to receive the protocol id
|
// try to receive the protocol id
|
||||||
return_result = libp2p_net_multistream_read(stream, &results, &results_size);
|
return_result = libp2p_net_multistream_read(stream, &results, &results_size);
|
||||||
if (return_result == 0 || results_size < 1)
|
if (return_result == 0 || results_size < 1)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
num_bytes = libp2p_net_multistream_write(stream, (unsigned char*)protocol_buffer, strlen(protocol_buffer));
|
||||||
|
if (num_bytes <= 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
if (strstr((char*)results, "multistream") == NULL)
|
if (strstr((char*)results, "multistream") == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
|
32
net/socket.c
32
net/socket.c
|
@ -184,19 +184,27 @@ ssize_t socket_write_size(int s, unsigned long size, int flags) {
|
||||||
*/
|
*/
|
||||||
uint32_t hostname_to_ip(const char* hostname)
|
uint32_t hostname_to_ip(const char* hostname)
|
||||||
{
|
{
|
||||||
struct hostent *he;
|
struct sockaddr_in sa;
|
||||||
struct in_addr **addr_list;
|
int result = inet_pton(AF_INET, hostname, &(sa.sin_addr));
|
||||||
|
if (result != 0) {
|
||||||
|
// an ip address was passed in instead of a hostname
|
||||||
|
return sa.sin_addr.s_addr;
|
||||||
|
} else {
|
||||||
|
// it is probably an actual host name and not just an ip address
|
||||||
|
struct hostent *he;
|
||||||
|
struct in_addr **addr_list;
|
||||||
|
|
||||||
if ( (he = gethostbyname( hostname ) ) == NULL)
|
if ( (he = gethostbyname( hostname ) ) == NULL)
|
||||||
{
|
{
|
||||||
// get the host info
|
// get the host info
|
||||||
herror("gethostbyname");
|
herror("gethostbyname");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_list = (struct in_addr **) he->h_addr_list;
|
addr_list = (struct in_addr **) he->h_addr_list;
|
||||||
if ((*addr_list) == NULL)
|
if ((*addr_list) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return addr_list[0]->s_addr;
|
return addr_list[0]->s_addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ int libp2p_secio_exchange_protobuf_decode(unsigned char* buffer, size_t buffer_l
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
if (libp2p_secio_exchange_new(out) == 0)
|
if ( (*out = libp2p_secio_exchange_new()) == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
while(pos < buffer_length) {
|
while(pos < buffer_length) {
|
||||||
|
|
|
@ -78,11 +78,11 @@ int libp2p_secio_propose_protobuf_encode(struct Propose* in, unsigned char* buff
|
||||||
return 0;
|
return 0;
|
||||||
*bytes_written += bytes_used;
|
*bytes_written += bytes_used;
|
||||||
// exchanges
|
// exchanges
|
||||||
if (!protobuf_encode_length_delimited(4, secio_propose_message_fields[3], in->exchanges, in->exchanges_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used))
|
if (!protobuf_encode_length_delimited(3, secio_propose_message_fields[2], in->exchanges, in->exchanges_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used))
|
||||||
return 0;
|
return 0;
|
||||||
*bytes_written += bytes_used;
|
*bytes_written += bytes_used;
|
||||||
// ciphers
|
// ciphers
|
||||||
if (!protobuf_encode_length_delimited(3, secio_propose_message_fields[2], in->ciphers, in->ciphers_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used))
|
if (!protobuf_encode_length_delimited(4, secio_propose_message_fields[3], in->ciphers, in->ciphers_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used))
|
||||||
return 0;
|
return 0;
|
||||||
*bytes_written += bytes_used;
|
*bytes_written += bytes_used;
|
||||||
// hashes
|
// hashes
|
||||||
|
@ -131,11 +131,11 @@ int libp2p_secio_propose_protobuf_decode(unsigned char* buffer, size_t buffer_le
|
||||||
got_something = 1;
|
got_something = 1;
|
||||||
break;
|
break;
|
||||||
case (3): // exchanges
|
case (3): // exchanges
|
||||||
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->exchanges), &((*out)->exchanges_size), &bytes_read) == 0)
|
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->exchanges), &((*out)->exchanges_size), &bytes_read) == 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
pos += bytes_read;
|
pos += bytes_read;
|
||||||
got_something = 1;
|
got_something = 1;
|
||||||
break;
|
break;
|
||||||
case (4): // ciphers
|
case (4): // ciphers
|
||||||
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->ciphers), &((*out)->ciphers_size), &bytes_read) == 0)
|
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->ciphers), &((*out)->ciphers_size), &bytes_read) == 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
112
secio/secio.c
112
secio/secio.c
|
@ -29,7 +29,7 @@ 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->socket_descriptor = -1;
|
ss->stream = NULL;
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,8 +291,10 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s
|
||||||
if (num_needed > hash_size)
|
if (num_needed > hash_size)
|
||||||
num_needed = hash_size;
|
num_needed = hash_size;
|
||||||
// combine current_hash with first_seed
|
// combine current_hash with first_seed
|
||||||
if (temp != NULL)
|
if (temp != NULL) {
|
||||||
free(temp);
|
free(temp);
|
||||||
|
temp = NULL;
|
||||||
|
}
|
||||||
seed_size = secret_size + strlen(first_seed) + hash_size;
|
seed_size = secret_size + strlen(first_seed) + hash_size;
|
||||||
temp = malloc(seed_size);
|
temp = malloc(seed_size);
|
||||||
memcpy(temp, secret, secret_size);
|
memcpy(temp, secret, secret_size);
|
||||||
|
@ -305,6 +307,7 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s
|
||||||
num_filled += num_needed;
|
num_filled += num_needed;
|
||||||
// redo the hashes by adding the secret to the current hash
|
// redo the hashes by adding the secret to the current hash
|
||||||
free(temp);
|
free(temp);
|
||||||
|
temp = NULL;
|
||||||
seed_size = secret_size + hash_size;
|
seed_size = secret_size + hash_size;
|
||||||
temp = malloc(seed_size);
|
temp = malloc(seed_size);
|
||||||
memcpy(temp, secret, secret_size);
|
memcpy(temp, secret, secret_size);
|
||||||
|
@ -336,6 +339,8 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s
|
||||||
memcpy(k2->mac_key, temp, k2->mac_size);
|
memcpy(k2->mac_key, temp, k2->mac_size);
|
||||||
temp += k2->mac_size;
|
temp += k2->mac_size;
|
||||||
|
|
||||||
|
temp = NULL;
|
||||||
|
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
|
@ -362,8 +367,35 @@ int libp2p_secio_stretch_keys(char* cipherType, char* hashType, unsigned char* s
|
||||||
}
|
}
|
||||||
|
|
||||||
int libp2p_secio_make_mac_and_cipher(struct SecureSession* session) {
|
int libp2p_secio_make_mac_and_cipher(struct SecureSession* session) {
|
||||||
// TODO: Implement this method
|
// mac
|
||||||
return 0;
|
int (*mac_func)(const char*, size_t, unsigned char*);
|
||||||
|
if (strcmp(session->chosen_hash, "SHA1") == 0) {
|
||||||
|
session->stretched_key->mac_size = 40;
|
||||||
|
mac_func = libp2p_crypto_hashing_sha1;
|
||||||
|
} else if (strcmp(session->chosen_hash, "SHA512") == 0) {
|
||||||
|
session->stretched_key->mac_size = 32;
|
||||||
|
mac_func = libp2p_crypto_hashing_sha512;
|
||||||
|
} else if (strcmp(session->chosen_hash, "SHA256") == 0) {
|
||||||
|
session->stretched_key->mac_size = 16;
|
||||||
|
mac_func = libp2p_crypto_hashing_sha256;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
session->stretched_key->mac_key = malloc(session->stretched_key->mac_size);
|
||||||
|
mac_func(session->stretched_key->cipher_key, session->stretched_key->cipher_size, session->stretched_key->mac_key);
|
||||||
|
|
||||||
|
// block cipher
|
||||||
|
if (strcmp(session->chosen_cipher, "AES-128") == 0) {
|
||||||
|
|
||||||
|
} else if (strcmp(session->chosen_cipher, "AES-256") == 0) {
|
||||||
|
|
||||||
|
} else if (strcmp(session->chosen_cipher, "Blowfish") == 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int libp2p_secio_write(struct SecureSession* session, unsigned char* bytes, size_t data_length) {
|
int libp2p_secio_write(struct SecureSession* session, unsigned char* bytes, size_t data_length) {
|
||||||
|
@ -377,7 +409,7 @@ int libp2p_secio_write(struct SecureSession* session, unsigned char* bytes, size
|
||||||
int written = 0;
|
int written = 0;
|
||||||
int written_this_time = 0;
|
int written_this_time = 0;
|
||||||
do {
|
do {
|
||||||
written_this_time = socket_write(session->socket_descriptor, &size_as_char[written], left, 0);
|
written_this_time = socket_write(*((int*)session->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)) {
|
||||||
|
@ -393,7 +425,7 @@ int libp2p_secio_write(struct SecureSession* session, unsigned char* bytes, size
|
||||||
left = data_length;
|
left = data_length;
|
||||||
written = 0;
|
written = 0;
|
||||||
do {
|
do {
|
||||||
written_this_time = socket_write(session->socket_descriptor, (char*)&bytes[written], left, 0);
|
written_this_time = socket_write(*((int*)session->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)) {
|
||||||
|
@ -420,7 +452,7 @@ int libp2p_secio_read(struct SecureSession* session, unsigned char** results, si
|
||||||
int read = 0;
|
int read = 0;
|
||||||
int read_this_time = 0;
|
int read_this_time = 0;
|
||||||
do {
|
do {
|
||||||
read_this_time = socket_read(session->socket_descriptor, &size[read], 1, 0);
|
read_this_time = socket_read(*((int*)session->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)) {
|
||||||
|
@ -449,7 +481,7 @@ int libp2p_secio_read(struct SecureSession* session, unsigned char** results, si
|
||||||
*results = malloc(left);
|
*results = malloc(left);
|
||||||
unsigned char* ptr = *results;
|
unsigned char* ptr = *results;
|
||||||
do {
|
do {
|
||||||
read_this_time = socket_read(session->socket_descriptor, (char*)&ptr[read], left, 0);
|
read_this_time = socket_read(*((int*)session->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)) {
|
||||||
|
@ -474,9 +506,6 @@ int libp2p_secio_read(struct SecureSession* session, unsigned char** results, si
|
||||||
* @returns true(1) on success, false(0) otherwise
|
* @returns true(1) on success, false(0) otherwise
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivateKey* private_key) {
|
int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivateKey* private_key) {
|
||||||
// this needs to be redone
|
|
||||||
return 0;
|
|
||||||
/*
|
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
size_t results_size = 0, bytes_written = 0;
|
size_t results_size = 0, bytes_written = 0;
|
||||||
unsigned char* propose_in_bytes = NULL; // the remote protobuf
|
unsigned char* propose_in_bytes = NULL; // the remote protobuf
|
||||||
|
@ -504,6 +533,27 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat
|
||||||
|
|
||||||
//TODO: make sure we're not talking to ourself
|
//TODO: make sure we're not talking to ourself
|
||||||
|
|
||||||
|
// prepare the multistream send of the protocol ID
|
||||||
|
const unsigned char* protocol = (unsigned char*)"/secio/1.0.0\n";
|
||||||
|
int protocol_len = strlen((char*)protocol);
|
||||||
|
unsigned char* total = malloc(protocol_len + propose_out_size);
|
||||||
|
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);
|
||||||
|
free(total);
|
||||||
|
if (bytes_written <= 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// we should get back the secio confirmation
|
||||||
|
bytes_written = libp2p_net_multistream_read(local_session->stream, &results, &results_size);
|
||||||
|
if (bytes_written < 5 || strstr((char*)results, "secio") == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
free(results);
|
||||||
|
results = NULL;
|
||||||
|
results_size = 0;
|
||||||
|
|
||||||
// generate 16 byte nonce
|
// generate 16 byte nonce
|
||||||
if (!libp2p_secio_generate_nonce(&local_session->nonce[0], 16)) {
|
if (!libp2p_secio_generate_nonce(&local_session->nonce[0], 16)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -549,30 +599,11 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat
|
||||||
if (libp2p_secio_propose_protobuf_encode(propose_out, propose_out_bytes, propose_out_size, &propose_out_size) == 0)
|
if (libp2p_secio_propose_protobuf_encode(propose_out, propose_out_bytes, propose_out_size, &propose_out_size) == 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// prepare the multistream send
|
|
||||||
const unsigned char* protocol = (unsigned char*)"/secio/1.0.0\n";
|
|
||||||
int protocol_len = strlen((char*)protocol);
|
|
||||||
unsigned char* total = malloc(protocol_len + propose_out_size);
|
|
||||||
memcpy(total, protocol, protocol_len);
|
|
||||||
memcpy(&total[protocol_len], propose_out_bytes, propose_out_size);
|
|
||||||
|
|
||||||
bytes_written = libp2p_net_multistream_write(local_session->socket_descriptor, total, protocol_len + propose_out_size);
|
bytes_written = libp2p_secio_write(local_session, propose_out_bytes, propose_out_size);
|
||||||
free(total);
|
if (bytes_written < propose_out_size)
|
||||||
if (bytes_written <= 0)
|
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
//bytes_written = libp2p_secio_write(local_session, propose_out_bytes, propose_out_size);
|
|
||||||
//if (bytes_written < propose_out_size)
|
|
||||||
// goto exit;
|
|
||||||
// we should get back the secio confirmation
|
|
||||||
bytes_written = libp2p_net_multistream_receive(local_session->socket_descriptor, (char**)&results, &results_size);
|
|
||||||
if (bytes_written < 5 || strstr((char*)results, "secio") == NULL)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
free(results);
|
|
||||||
results = NULL;
|
|
||||||
results_size = 0;
|
|
||||||
|
|
||||||
// now receive the proposal from the new connection
|
// now receive the proposal from the new connection
|
||||||
bytes_written = libp2p_secio_read(local_session, &propose_in_bytes, &propose_in_size);
|
bytes_written = libp2p_secio_read(local_session, &propose_in_bytes, &propose_in_size);
|
||||||
if (bytes_written <= 0)
|
if (bytes_written <= 0)
|
||||||
|
@ -587,6 +618,11 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat
|
||||||
// generate their peer id
|
// generate their peer id
|
||||||
libp2p_crypto_public_key_to_peer_id(public_key, &remote_peer_id);
|
libp2p_crypto_public_key_to_peer_id(public_key, &remote_peer_id);
|
||||||
|
|
||||||
|
// receive Exchange packet
|
||||||
|
bytes_written = libp2p_secio_read(local_session, &results, &results_size);
|
||||||
|
if (bytes_written == 0)
|
||||||
|
goto exit;
|
||||||
|
libp2p_secio_exchange_protobuf_decode(results, results_size, &exchange_in);
|
||||||
|
|
||||||
// negotiate encryption parameters NOTE: SelectBest must match, otherwise this won't work
|
// negotiate encryption parameters NOTE: SelectBest must match, otherwise this won't work
|
||||||
// first determine order
|
// first determine order
|
||||||
|
@ -653,12 +689,6 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat
|
||||||
free(exchange_out_protobuf);
|
free(exchange_out_protobuf);
|
||||||
exchange_out_protobuf = NULL;
|
exchange_out_protobuf = NULL;
|
||||||
|
|
||||||
// receive Exchange packet
|
|
||||||
bytes_written = libp2p_secio_read(local_session, &results, &results_size);
|
|
||||||
if (bytes_written == 0)
|
|
||||||
goto exit;
|
|
||||||
libp2p_secio_exchange_protobuf_decode(results, results_size, &exchange_in);
|
|
||||||
|
|
||||||
// parse and verify
|
// parse and verify
|
||||||
remote_session.ephemeral_public_key = exchange_in->epubkey;
|
remote_session.ephemeral_public_key = exchange_in->epubkey;
|
||||||
remote_session.ephemeral_public_key_size = exchange_in->epubkey_size;
|
remote_session.ephemeral_public_key_size = exchange_in->epubkey_size;
|
||||||
|
@ -669,8 +699,9 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat
|
||||||
libp2p_utils_vector_add(char_buffer, propose_in_bytes, propose_in_size);
|
libp2p_utils_vector_add(char_buffer, propose_in_bytes, propose_in_size);
|
||||||
libp2p_utils_vector_add(char_buffer, propose_out_bytes, propose_out_size);
|
libp2p_utils_vector_add(char_buffer, propose_out_bytes, propose_out_size);
|
||||||
libp2p_utils_vector_add(char_buffer, remote_session.ephemeral_public_key, remote_session.ephemeral_public_key_size);
|
libp2p_utils_vector_add(char_buffer, remote_session.ephemeral_public_key, remote_session.ephemeral_public_key_size);
|
||||||
if (!libp2p_secio_verify_signature(public_key, char_buffer->buffer, char_buffer->buffer_size, exchange_in->signature))
|
// TODO: signature verification
|
||||||
goto exit;
|
//if (!libp2p_secio_verify_signature(public_key, char_buffer->buffer, char_buffer->buffer_size, exchange_in->signature))
|
||||||
|
// goto exit;
|
||||||
libp2p_utils_vector_free(char_buffer);
|
libp2p_utils_vector_free(char_buffer);
|
||||||
char_buffer = NULL;
|
char_buffer = NULL;
|
||||||
|
|
||||||
|
@ -727,5 +758,4 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat
|
||||||
libp2p_secio_propose_free(propose_in);
|
libp2p_secio_propose_free(propose_in);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "libp2p/conn/dialer.h"
|
#include "libp2p/conn/dialer.h"
|
||||||
|
#include "libp2p/net/stream.h"
|
||||||
#include "test_helper.h"
|
#include "test_helper.h"
|
||||||
|
|
||||||
int test_dialer_new() {
|
int test_dialer_new() {
|
||||||
|
@ -42,15 +43,6 @@ int test_dialer_dial() {
|
||||||
if (conn == NULL)
|
if (conn == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (conn->write(conn, "ping", 4) == 0)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (conn->read(conn, &result, &result_size) == 0)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (result_size < 4 || strncmp(result, "pong", 4) != 0)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
// clean up resources
|
// clean up resources
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
exit:
|
exit:
|
||||||
|
@ -63,3 +55,47 @@ int test_dialer_dial() {
|
||||||
libp2p_conn_connection_free(conn);
|
libp2p_conn_connection_free(conn);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_dialer_dial_multistream() {
|
||||||
|
int retVal = 0;
|
||||||
|
char* config_dir = "/home/parallels/.ipfs/config";
|
||||||
|
char* destination_string = "/ip4/192.210.179.217/tcp/4001/";
|
||||||
|
char* peer_id = NULL;
|
||||||
|
struct PrivateKey* private_key = NULL;
|
||||||
|
struct Dialer* dialer = NULL;
|
||||||
|
struct MultiAddress* destination_address = NULL;
|
||||||
|
struct Stream* stream = NULL;
|
||||||
|
char* result = NULL;
|
||||||
|
size_t result_size = 0;
|
||||||
|
|
||||||
|
test_helper_get_id_from_config(config_dir, &private_key, &peer_id);
|
||||||
|
if (private_key == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
dialer = libp2p_conn_dialer_new(peer_id, private_key);
|
||||||
|
if (dialer == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
destination_address = multiaddress_new_from_string(destination_string);
|
||||||
|
if (destination_address == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// now try to dial
|
||||||
|
stream = libp2p_conn_dialer_get_stream(dialer, destination_address, "multistream");
|
||||||
|
if (stream == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// now ping
|
||||||
|
|
||||||
|
// clean up resources
|
||||||
|
retVal = 1;
|
||||||
|
exit:
|
||||||
|
if (result != NULL)
|
||||||
|
free(result);
|
||||||
|
free(peer_id);
|
||||||
|
multiaddress_free(destination_address);
|
||||||
|
libp2p_conn_dialer_free(dialer);
|
||||||
|
libp2p_crypto_private_key_free(private_key);
|
||||||
|
stream->close(stream);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
|
@ -23,12 +23,13 @@ int test_multistream_connect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_multistream_get_list() {
|
int test_multistream_get_list() {
|
||||||
int retVal = 0, socket_fd = -1;
|
int retVal = 0;
|
||||||
unsigned char* response;
|
unsigned char* response;
|
||||||
size_t response_size;
|
size_t response_size;
|
||||||
|
char* filtered = NULL;
|
||||||
|
|
||||||
struct Stream* stream = libp2p_net_multistream_connect("www.jmjatlanta.com", 4001);
|
struct Stream* stream = libp2p_net_multistream_connect("www.jmjatlanta.com", 4001);
|
||||||
if (socket_fd < 0)
|
if (*((int*)stream->socket_descriptor) < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// try to respond something, ls command
|
// try to respond something, ls command
|
||||||
|
@ -42,7 +43,12 @@ int test_multistream_get_list() {
|
||||||
if (retVal <= 0)
|
if (retVal <= 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
fprintf(stdout, "Response from multistream ls: %s", (char*)response);
|
filtered = malloc(response_size + 1);
|
||||||
|
strncpy(filtered, response, response_size);
|
||||||
|
filtered[response_size] = 0;
|
||||||
|
|
||||||
|
fprintf(stdout, "Response from multistream ls: %s", (char*)filtered);
|
||||||
|
free(filtered);
|
||||||
|
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,13 @@
|
||||||
#include "libp2p/net/p2pnet.h"
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
|
||||||
int test_secio_handshake() {
|
int test_secio_handshake() {
|
||||||
return 0;
|
|
||||||
/*
|
|
||||||
* this needs to be redone
|
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
size_t decode_base64_size = 0;
|
size_t decode_base64_size = 0;
|
||||||
unsigned char* decode_base64 = NULL;
|
unsigned char* decode_base64 = NULL;
|
||||||
// this is a base64 encoded private key. It makes it easier to test if it is in base64 form
|
// this is a base64 encoded private key. It makes it easier to test if it is in base64 form
|
||||||
// these were pulled from the GO version of ipfs
|
// these were pulled from the GO version of ipfs
|
||||||
char* orig_priv_key = "CAASpwkwggSjAgEAAoIBAQCwfp3DpbTP/nD1R+1PcP7nDOV9MEDiLUoNf9cBVhWGefJT0ES81do1COwLXiD/k7gAHJu197F7AfFYKt+NQu6jpCDC/uRtK0M0MpeDGI0LV1oz0rKLTN79zQwKDHFimWCmNyOZRLfR3PF5TgLc0qiFOZw9WwYNJkohu6k6yVMDJiy3l/+K5Vdw9VVyz7mRulXdDvEMxccraKaTvjLAUNFjiqm5Zs3hrcZszuuP2RhcpZU40kuWDtyN9TAEge0NfhS5Fj7GtgQsHWJ4RxTdebHkQmX49ltI/nIw9TxGIVcA50g7eF/3a3zZtkh48JadbHiT2Mfr6SPXl0328gyg7v7tAgMBAAECggEABGlFvCwaFtC/NgI0NjYWyOOToMth88U6AphdYVUreI73tYyRCz81EvpEHAygOoMQqEAOzD+CmhZ0V8XKjJdNq51gjD8eqnPYXCefjdFBRTVLtdvgRocHU8SaNm4VL2ex+LWMGDqVdZNWHbgLbkV9nMbR1t69ifqZA7rTAfsiLgPtneu4kGjrO1nr+uFC0srch2o0stmiqxmcGOrkD9x2kXkw33O8wTSyBp3+STlTOehePuUqEho9BXdT7b2nXC8MNdTCekG9f3oUeKsK9pxH7ZlG3yUOBoM0mEm/N7BrPfJnQbogomUapWOpssWKSz0LCpKuy4El3mFpua0jmd3nAQKBgQDWvVHj44gSecjsrWH/QpMIn8W/ISXfJRxJKrdVBRC5Ey0h3wdLnF6Olz4kuD7KurPOWNR+IKaLzOWxZdX79aQn+oY8lB+UCM+0w1TWJeSWBUYATPtUU4xpKdD6YZ8ksOdgZ4hbn9VD49uu/SJUPVNGV+eHibnvdR+/sFJuHTAb4QKBgQDSaBd1V7z5R6NK8373QNMDHZnSa2qH8uAGvoSuajYGgcpAzDY3aueQFpQS66scrZK6zLQyOQgtyrIg/hKbeP+vV5LGBirzOtAH7Kko5BYeY/SCXOkHBsHhuPGyghqWl6KR2Vj8cjJZFCAiUvoqf3Ws0vW58kp/KgDCnlKGmgQkjQKBgDPYi7/4vG6xhqhWCDYIDdXkNWs7BpjErfqgXJkjWvFERv5Jicpgm5fTvkZBUa/CugzU96DoIy3Xr5FQJATsPtEENIrFvIYSRou/KWl2xqTN6yPBcmDetyTg2rrI/RJvv71P4eU1RtlYVz79kN9D2yo9qQHZZ9H/tkWivZQmaeohAoGAIafa0L9HEAzAdvW6AmzRE/eBKmJaOQLFiO6ipI+CssnCA1lm9rhX7/lcmCYwSbcN+GlUDZCH2WNJ2PMrIMlbBL4aUSidaCipLAtUB6FsVFIiw1N/Rsty6ds+dhJPlHUO4QuGK2NM4GjStwrUz0VyGkHoYmT6O5sJYhgXFUa/kOUCgYEAv1VGeX6EPsFgp+FKM1Q/8MYi7PPpSUI2fqMhnwe36u7UdNYa3Ismmo/ipfCw7DdX5qRcUh44PodTp4Zwp67Bd2KRzEAZmMvIurzclQB7VWUT7pB7yfbO9bjBUVbPTagjiqb30zq9A4kt+B/0MSPxa/Kh8EkgI02Jqh2Q97Ij4sc=";
|
char* orig_priv_key = "CAASpwkwggSjAgEAAoIBAQCo+BYd213u8PNHNcnXZ6TcUc7oXEoCtWL12XJEFqAiC7emadkp+WtujmuR993L6uCRPU/+mNXIvetodMQ5GORq0MxsPlKFNuVuqHS4PCdWYYFKeel4QsG17T3XMo72Kxm7/pQ1Dbs6tzWD4Ie4Zsa7ziyffjeak1/EExkFf0AKtj4UdXErNRI5gZhkDnWp6Si117Z2VVTslE+kKXWpLK0RYZ4w8DhhZa+ykt2tleOOJt8ocJ3s3yVZQxOafL1lwA8f10VEEeJLPGKJ1Y7mmW7OJhLmrq9tvdTLhum1H5kdYu/pheCm5b6/NSGKS+XbQztu5zedsKSPHsOlYhxYu3GJAgMBAAECggEAZIz93Fam14Jbw4ymyKDM4q9sSapiAKqgcV0tOoecU6ZVa5qhuPDMlcX7DapLOwZTDRtHd2LMFeGvLUIPY0sE4uvOOrv7r3qznd5xVxG09xqfLgrOfNp9HB5KJr3XhXawocclu0yolpBgMFJ1ca73pNtUgrVBsaLx4mTbBwJqwfQpQb/Xdkrdgc663bwXkSl4vApwhZGzi5CFJ6SFC6l6fMKoteWM1ay5e2VCfxi/1g41EINkrqm+QPWhy11bo21ScozxiFiywcxQ8Huo+I5GDHI5EUfIHP97NSRG24/IDSebxsGTukMdpLmiiwizV7hHP2eDlikHAhxBBAF2GkbkAQKBgQDg69jPHrETvHGlKjlEDE8sYQUrwpmGLHfsfZYqBxcz65jPYFAypG4icIU6f8Uhz9c42jLEBssNPT8LyLl2uY467hZZA2SkeWKS66Vi5wBGTN5qOBWUejhzTx8UzasYroWl/0RqFZhU9Xhwg4YqT9X8jYw5mXyOMLatp/d/Y96p0QKBgQDAUQodQZc9yc7olsmNvbuHZtBA+VndKCokFOuJ6YLRK69AL7y6n6eUjne6JqcEIKDC7vr33ryuOdFI+zNzMsdYykE8xcg2c5itWRqG7EdMxgR1dYLUqGC5ustRM/mmhmRzW8DXy88sS+vM4U84yPKv/rfeKAoYgE722R0kkpQCOQKBgQCKfm63yiw6/NP1YXR1hCbUKsFmWqLxzTvisMngAxG0dKNZPfLj2/+80RAYH0ihMztQ1Hph3dT1x/qkJOqeQk9j1eqI0OANrniWAueJaLfwkbB6MyKGlGNiDRwUUTfDMOM2fWIA+F8eITASB8p7D0GyCu6HIQ1i+HfjogNxu2sFoQKBgE4ZGthiqH6JE6NUiKks4ZjM4clg+WNcSjC45iXtVBiJevO/7w6Cg1VKvcg0piKA9Yfz8Kr0Iv9Fr33JtU0U0+t0xyVc1D94lgnfY2xjS1kcGPdyLx0Y+56xApwJVVqQvP4zxo5bz9gXRLzAyqEuyY87C4QGEoN8p5SK+tC9TanRAoGAbC+uVaBtqRqv3LY16+H58BW8lVfN+8dqtBOWluM2uImB1qL2EbKk0X/OChz3Dgzef5VTox6nHcMyYPwXLirS9aIYPggjdpDTjfbWPxUcwYmIB1U++F/mRk1IeDgl9g7t/OlPMg4snxQGEzMPPDVrj/KeLEKv5x+T5yFZ/y+8xNo=";
|
||||||
char* orig_peer_id = "QmYm3WdMQqqQuEyCWmRVNEjtXjhGhyRRNshdvqV7YLGvpA";
|
char* orig_peer_id = "QmZigcoDKaAafGSwot2tchJarCafxKapoRmnYTrZ69ckjb";
|
||||||
size_t orig_peer_id_size = strlen(orig_peer_id);
|
size_t orig_peer_id_size = strlen(orig_peer_id);
|
||||||
struct RsaPrivateKey* rsa_private_key = NULL;
|
struct RsaPrivateKey* rsa_private_key = NULL;
|
||||||
unsigned char hashed[32] = {0};
|
unsigned char hashed[32] = {0};
|
||||||
|
@ -45,12 +42,12 @@ 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 = "192.210.179.217";
|
secure_session.host = "www.jmjatlanta.com";
|
||||||
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.socket_descriptor = libp2p_net_multistream_connect(secure_session.host, secure_session.port);
|
secure_session.stream = libp2p_net_multistream_connect(secure_session.host, secure_session.port);
|
||||||
if (secure_session.socket_descriptor == -1) {
|
if (*((int*)secure_session.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;
|
||||||
}
|
}
|
||||||
|
@ -77,5 +74,4 @@ int test_secio_handshake() {
|
||||||
if (rsa_private_key != NULL)
|
if (rsa_private_key != NULL)
|
||||||
libp2p_crypto_rsa_rsa_private_key_free(rsa_private_key);
|
libp2p_crypto_rsa_rsa_private_key_free(rsa_private_key);
|
||||||
return retVal;
|
return retVal;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ const char* names[] = {
|
||||||
"test_ephemeral_key_generate",
|
"test_ephemeral_key_generate",
|
||||||
"test_dialer_new",
|
"test_dialer_new",
|
||||||
"test_dialer_dial",
|
"test_dialer_dial",
|
||||||
|
"test_dialer_dial_multistream",
|
||||||
"test_record_protobuf",
|
"test_record_protobuf",
|
||||||
"test_record_make_put_record",
|
"test_record_make_put_record",
|
||||||
"test_record_peer_protobuf",
|
"test_record_peer_protobuf",
|
||||||
|
@ -76,6 +77,7 @@ int (*funcs[])(void) = {
|
||||||
test_ephemeral_key_generate,
|
test_ephemeral_key_generate,
|
||||||
test_dialer_new,
|
test_dialer_new,
|
||||||
test_dialer_dial,
|
test_dialer_dial,
|
||||||
|
test_dialer_dial_multistream,
|
||||||
test_record_protobuf,
|
test_record_protobuf,
|
||||||
test_record_make_put_record,
|
test_record_make_put_record,
|
||||||
test_record_peer_protobuf,
|
test_record_peer_protobuf,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -O0 -Wall -I../include
|
CFLAGS = -O0 -Wall -I../include -I../../c-multiaddr/include
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CFLAGS += -g3
|
CFLAGS += -g3
|
||||||
|
@ -7,7 +7,7 @@ endif
|
||||||
|
|
||||||
LFLAGS =
|
LFLAGS =
|
||||||
DEPS =
|
DEPS =
|
||||||
OBJS = string_list.o vector.o linked_list.o
|
OBJS = string_list.o vector.o linked_list.o multiaddress.o
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
38
utils/multiaddress.c
Normal file
38
utils/multiaddress.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
/**
|
||||||
|
* A central repository for parsing Multiaddress structs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libp2p/utils/multiaddress.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a hack to get ip4/tcp working
|
||||||
|
* TODO: this should be moved further down in the networking stack and generified for different multiaddresses
|
||||||
|
* This makes too many assumptions
|
||||||
|
* @param address the multiaddress to parse
|
||||||
|
* @param ip the first IP address in the multiaddress
|
||||||
|
* @param port the first port in the multiaddress
|
||||||
|
* @returns true(1) on success, false(0) on failure
|
||||||
|
*/
|
||||||
|
int libp2p_utils_multiaddress_parse_ip4_tcp(const struct MultiAddress* address, char** ip, int* port) {
|
||||||
|
// the incoming address is not what was expected
|
||||||
|
if (strncmp(address->string, "/ip4/", 5) != 0)
|
||||||
|
return 0;
|
||||||
|
if (strstr(address->string, "/tcp/") == NULL)
|
||||||
|
return 0;
|
||||||
|
// ip
|
||||||
|
char* str = malloc(strlen(address->string));
|
||||||
|
if (str == NULL)
|
||||||
|
return 0;
|
||||||
|
strcpy(str, &address->string[5]); // gets rid of /ip4/
|
||||||
|
char* pos = strchr(str, '/');
|
||||||
|
pos[0] = 0;
|
||||||
|
*ip = malloc(strlen(str) + 1);
|
||||||
|
strcpy(*ip, str);
|
||||||
|
free(str);
|
||||||
|
// port
|
||||||
|
str = strstr(address->string, "/tcp/");
|
||||||
|
str += 5;
|
||||||
|
*port = atoi(str);
|
||||||
|
return 1;
|
||||||
|
}
|
Loading…
Reference in a new issue