267 lines
8 KiB
C
267 lines
8 KiB
C
#include <stdlib.h>
|
|
|
|
#include "libp2p/record/record.h"
|
|
#include "libp2p/record/message.h"
|
|
#include "libp2p/peer/peer.h"
|
|
#include "multiaddr/multiaddr.h"
|
|
|
|
int setval(char** result, size_t* result_size, char* in) {
|
|
*result = malloc(strlen(in) + 1);
|
|
if (*result == NULL)
|
|
return 0;
|
|
strcpy(*result, in);
|
|
if (result_size != NULL)
|
|
*result_size = strlen(in);
|
|
return 1;
|
|
}
|
|
|
|
struct Libp2pRecord* test_record_create() {
|
|
struct Libp2pRecord* record = libp2p_record_new();
|
|
if (record != NULL) {
|
|
setval(&record->key, &record->key_size, "Key");
|
|
setval((char**)&record->value, &record->value_size, "Value");
|
|
setval(&record->author, &record->author_size, "Author");
|
|
setval((char**)&record->signature, &record->signature_size, "Signature");
|
|
setval(&record->time_received, &record->time_received_size, "Time_Received");
|
|
}
|
|
return record;
|
|
}
|
|
|
|
int test_record_protobuf() {
|
|
struct Libp2pRecord* record = test_record_create();
|
|
struct Libp2pRecord* results = NULL;
|
|
struct MultiAddress *ma = NULL, *ma_results = NULL;
|
|
size_t protobuf_size = 0;
|
|
unsigned char* protobuf = NULL;
|
|
int retVal = 0;
|
|
|
|
// protobuf, unprotobuf
|
|
protobuf_size = libp2p_record_protobuf_encode_size(record);
|
|
protobuf = (unsigned char*)malloc(protobuf_size);
|
|
if (!libp2p_record_protobuf_encode(record, protobuf, protobuf_size, &protobuf_size))
|
|
goto exit;
|
|
|
|
if (!libp2p_record_protobuf_decode(protobuf, protobuf_size, &results))
|
|
goto exit;
|
|
|
|
if (record->key_size != results->key_size
|
|
|| record->value_size != results->value_size
|
|
|| record->author_size != results->author_size
|
|
|| record->signature_size != results->signature_size
|
|
|| record->time_received_size != results->time_received_size)
|
|
goto exit;
|
|
if (strcmp(record->key, results->key) != 0)
|
|
goto exit;
|
|
if (strncmp((char*)record->value, (char*)results->value, results->value_size) != 0)
|
|
goto exit;
|
|
if (strncmp(record->author, results->author, results->author_size) != 0)
|
|
goto exit;
|
|
if (strncmp((char*)record->signature, (char*)results->signature, results->signature_size) != 0)
|
|
goto exit;
|
|
if (strncmp(record->time_received, results->time_received, results->time_received_size) != 0)
|
|
goto exit;
|
|
|
|
retVal = 1;
|
|
exit:
|
|
if (protobuf != NULL)
|
|
free (protobuf);
|
|
libp2p_record_free(record);
|
|
if (results != NULL)
|
|
libp2p_record_free(results);
|
|
return retVal;
|
|
}
|
|
|
|
int test_record_make_put_record() {
|
|
int retVal = 0;
|
|
char* protobuf = NULL;
|
|
size_t protobuf_size = 0;
|
|
struct RsaPrivateKey* rsa_private_key = NULL;
|
|
struct RsaPublicKey rsa_public_key;
|
|
char* record_key = "Record Key";
|
|
unsigned char* record_value = (unsigned char*)"Record Value";
|
|
size_t record_value_length = strlen((char*)record_value);
|
|
struct Libp2pRecord* results = NULL;
|
|
char* signature_buffer = NULL;
|
|
size_t signature_buffer_length = 0;
|
|
|
|
// generate keys
|
|
|
|
rsa_public_key.der = NULL;
|
|
rsa_public_key.der_length = 0;
|
|
|
|
rsa_private_key = libp2p_crypto_rsa_rsa_private_key_new();
|
|
if (rsa_private_key == NULL)
|
|
goto exit;
|
|
|
|
if (!libp2p_crypto_rsa_generate_keypair(rsa_private_key, 2048))
|
|
goto exit;
|
|
|
|
rsa_public_key.der = rsa_private_key->public_key_der;
|
|
rsa_public_key.der_length = rsa_private_key->public_key_length;
|
|
|
|
// sign and protobuf
|
|
if (libp2p_record_make_put_record(&protobuf, &protobuf_size, rsa_private_key, record_key, (char*)record_value, record_value_length, 1) != 0)
|
|
goto exit;
|
|
|
|
// unprotobuf and test
|
|
if (!libp2p_record_protobuf_decode((unsigned char*)protobuf, protobuf_size, &results))
|
|
goto exit;
|
|
|
|
if (strcmp(record_key, results->key) != 0)
|
|
goto exit;
|
|
if (strncmp((char*)record_value, (char*)results->value, results->value_size) != 0)
|
|
goto exit;
|
|
if (results->key_size != strlen(record_key)
|
|
|| results->value_size != record_value_length)
|
|
goto exit;
|
|
|
|
// verify signature
|
|
signature_buffer_length = results->key_size + results->value_size + results->author_size;
|
|
signature_buffer = malloc(signature_buffer_length);
|
|
strncpy(&signature_buffer[0], results->key, results->key_size);
|
|
strncpy(&signature_buffer[results->key_size], (char*)results->value, results->value_size);
|
|
strncpy(&signature_buffer[results->key_size + results->value_size], results->author, results->author_size);
|
|
if (!libp2p_crypto_rsa_verify(&rsa_public_key, (unsigned char*)signature_buffer, signature_buffer_length, results->signature))
|
|
goto exit;
|
|
|
|
// cleanup
|
|
retVal = 1;
|
|
exit:
|
|
|
|
if (signature_buffer != NULL)
|
|
free(signature_buffer);
|
|
if (protobuf != NULL)
|
|
free(protobuf);
|
|
if (results != NULL)
|
|
libp2p_record_free(results);
|
|
if (rsa_private_key != NULL)
|
|
libp2p_crypto_rsa_rsa_private_key_free(rsa_private_key);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
int test_record_peer_protobuf() {
|
|
struct Libp2pPeer* peer = NULL;
|
|
struct MultiAddress* multi_addr1 = NULL;
|
|
struct MultiAddress* multi_addr2 = NULL;
|
|
int retVal = 0;
|
|
unsigned char* protobuf = NULL;
|
|
size_t protobuf_size = 0;
|
|
struct Libp2pPeer* result = NULL;
|
|
|
|
// make multiaddress
|
|
multi_addr1 = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001");
|
|
|
|
// make peer
|
|
peer = libp2p_peer_new();
|
|
peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
|
|
peer->id = malloc(7);
|
|
strcpy(peer->id, "ABC123");
|
|
peer->id_size = strlen(peer->id);
|
|
peer->addr_head = libp2p_utils_linked_list_new();
|
|
peer->addr_head->item = multi_addr1;
|
|
|
|
// protobuf
|
|
protobuf_size = libp2p_peer_protobuf_encode_size(peer);
|
|
protobuf = (unsigned char*)malloc(protobuf_size);
|
|
if (protobuf == NULL)
|
|
goto exit;
|
|
if (!libp2p_peer_protobuf_encode(peer, protobuf, protobuf_size, &protobuf_size))
|
|
goto exit;
|
|
|
|
// unprotobuf
|
|
if (!libp2p_peer_protobuf_decode(protobuf, protobuf_size, &result))
|
|
goto exit;
|
|
|
|
// check results
|
|
if (strncmp(peer->id, result->id, peer->id_size) != 0)
|
|
goto exit;
|
|
|
|
if (peer->id_size != result->id_size
|
|
|| peer->connection_type != result->connection_type)
|
|
goto exit;
|
|
|
|
// check multiaddress
|
|
multi_addr2 = (struct MultiAddress*)result->addr_head->item;
|
|
if (multi_addr1->bsize != multi_addr2->bsize)
|
|
goto exit;
|
|
if (strncmp((char*)multi_addr1->bytes, (char*)multi_addr2->bytes, multi_addr2->bsize) != 0)
|
|
goto exit;
|
|
|
|
// cleanup
|
|
retVal = 1;
|
|
exit:
|
|
if (peer != NULL) {
|
|
libp2p_peer_free(peer);
|
|
// above gets rid of below...
|
|
multi_addr1 = NULL;
|
|
}
|
|
if (multi_addr1 != NULL)
|
|
multiaddress_free(multi_addr1);
|
|
if (protobuf != NULL)
|
|
free(protobuf);
|
|
if (result != NULL)
|
|
libp2p_peer_free(result);
|
|
return retVal;
|
|
}
|
|
|
|
int test_record_message_protobuf() {
|
|
int retVal = 0;
|
|
struct Libp2pPeer* closer_peer = NULL;
|
|
struct KademliaMessage* message = NULL;
|
|
struct KademliaMessage* result = NULL;
|
|
struct MultiAddress *ma_result = NULL;
|
|
char* buffer = NULL;
|
|
size_t buffer_len = 0;
|
|
|
|
// construct message
|
|
closer_peer = libp2p_peer_new();
|
|
closer_peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
|
|
closer_peer->id = malloc(7);
|
|
strcpy(closer_peer->id, "ABC123");
|
|
closer_peer->id_size = strlen(closer_peer->id);
|
|
closer_peer->addr_head = libp2p_utils_linked_list_new();
|
|
closer_peer->addr_head->item = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001/ipfs/QmW8CYQuoJhgfxTeNVFWktGFnTRzdUAimerSsHaE4rUXk8/");
|
|
|
|
message = libp2p_message_new();
|
|
message->closer_peer_head = libp2p_utils_linked_list_new();
|
|
message->closer_peer_head->item = closer_peer;
|
|
message->cluster_level_raw = 1;
|
|
message->key = malloc(7);
|
|
strcpy(message->key, "ABC123");
|
|
message->key_size = 6;
|
|
message->message_type = MESSAGE_TYPE_ADD_PROVIDER;
|
|
message->record = test_record_create();
|
|
|
|
// protobuf
|
|
buffer_len = libp2p_message_protobuf_encode_size(message);
|
|
buffer = malloc(buffer_len);
|
|
if (!libp2p_message_protobuf_encode(message, (unsigned char*)buffer, buffer_len, &buffer_len))
|
|
goto exit;
|
|
|
|
// decode
|
|
if (!libp2p_message_protobuf_decode((unsigned char*)buffer, buffer_len, &result))
|
|
goto exit;
|
|
|
|
// check results
|
|
if (result->cluster_level_raw != 1)
|
|
goto exit;
|
|
|
|
ma_result = ((struct Libp2pPeer*)result->closer_peer_head->item)->addr_head->item;
|
|
|
|
if (strcmp(ma_result->string, ((struct MultiAddress*)closer_peer->addr_head->item)->string) != 0) {
|
|
fprintf(stderr, "MultiAddress strings do not match\n");
|
|
goto exit;
|
|
}
|
|
|
|
// cleanup
|
|
retVal = 1;
|
|
exit:
|
|
if (message != NULL)
|
|
libp2p_message_free(message);
|
|
if (buffer != NULL)
|
|
free(buffer);
|
|
if (result != NULL)
|
|
libp2p_message_free(result);
|
|
return retVal;
|
|
}
|