Added multistream protocol to communicate with GO version
This commit is contained in:
parent
29e1a0c31b
commit
d091a29b19
27 changed files with 714 additions and 131 deletions
|
@ -26,6 +26,7 @@
|
||||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.623347632" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.623347632" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
||||||
<option id="gnu.c.compiler.option.include.paths.1688271638" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
<option id="gnu.c.compiler.option.include.paths.1688271638" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/c-multihash/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/c-multihash/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/c-libp2p/include}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1284958161" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1284958161" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||||
</tool>
|
</tool>
|
||||||
|
|
15
Makefile
15
Makefile
|
@ -2,19 +2,27 @@
|
||||||
DEBUG = true
|
DEBUG = true
|
||||||
export DEBUG
|
export DEBUG
|
||||||
|
|
||||||
OBJS = crypto/*.o crypto/encoding/*.o thirdparty/mbedtls/*.o hashmap/hashmap.o record/*.o routing/*.o
|
OBJS = crypto/*.o crypto/encoding/*.o \
|
||||||
|
thirdparty/mbedtls/*.o \
|
||||||
|
hashmap/hashmap.o \
|
||||||
|
net/*.o \
|
||||||
|
record/*.o \
|
||||||
|
routing/*.o \
|
||||||
|
secio/*.o
|
||||||
|
|
||||||
|
link: $(OBJS)
|
||||||
|
ar rcs libp2p.a $(OBJS)
|
||||||
|
|
||||||
compile:
|
compile:
|
||||||
cd crypto; make all;
|
cd crypto; make all;
|
||||||
cd thirdparty; make all;
|
cd thirdparty; make all;
|
||||||
cd hashmap; make all;
|
cd hashmap; make all;
|
||||||
|
cd net; make all;
|
||||||
cd record; make all;
|
cd record; make all;
|
||||||
cd routing; make all;
|
cd routing; make all;
|
||||||
cd secio; make all;
|
cd secio; make all;
|
||||||
ar rcs libp2p.a $(OBJS)
|
|
||||||
|
|
||||||
test: compile
|
test: compile link
|
||||||
cd test; make all;
|
cd test; make all;
|
||||||
|
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
|
@ -24,6 +32,7 @@ all: test
|
||||||
clean:
|
clean:
|
||||||
cd crypto; make clean;
|
cd crypto; make clean;
|
||||||
cd hashmap; make clean;
|
cd hashmap; make clean;
|
||||||
|
cd net; make clean;
|
||||||
cd thirdparty; make clean
|
cd thirdparty; make clean
|
||||||
cd test; make clean;
|
cd test; make clean;
|
||||||
cd record; make clean;
|
cd record; make clean;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -O0 -I../include -g3
|
CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -g3
|
||||||
LFLAGS =
|
LFLAGS =
|
||||||
DEPS =
|
DEPS =
|
||||||
OBJS = rsa.o sha256.o sha512.o sha1.o
|
OBJS = rsa.o sha256.o sha512.o sha1.o key.o peerutils.o
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
127
crypto/key.c
127
crypto/key.c
|
@ -1,31 +1,29 @@
|
||||||
#include <stdio.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libp2p/crypto/key.h"
|
||||||
|
#include "libp2p/crypto/sha256.h"
|
||||||
|
#include "libp2p/crypto/peerutils.h"
|
||||||
|
#include "protobuf.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for public keys
|
* Utilities for public and private keys
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum KeyType { KEYTYPE_RSA, KEYTYPE_ED25519, KEYTYPE_INVALID };
|
|
||||||
|
|
||||||
struct PublicKey {
|
|
||||||
enum KeyType key_type;
|
|
||||||
char* raw_key;
|
|
||||||
size_t raw_key_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PublicKey* libp2p_crypto_public_key_new() {
|
struct PublicKey* libp2p_crypto_public_key_new() {
|
||||||
struct PublicKey* retVal = malloc(sizeof(struct PublicKey));
|
struct PublicKey* retVal = malloc(sizeof(struct PublicKey));
|
||||||
if (retVal == NULL)
|
if (retVal == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
retVal->key_type = KEYTYPE_INVALID;
|
retVal->type = KEYTYPE_INVALID;
|
||||||
retVal->raw_key = NULL;
|
retVal->data = NULL;
|
||||||
retVal->raw_key_size = 0;
|
retVal->data_size = 0;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void libp2p_crypto_public_key_free(struct PublicKey* in) {
|
void libp2p_crypto_public_key_free(struct PublicKey* in) {
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
if (in->raw_key != NULL)
|
if (in->data != NULL)
|
||||||
free(in->raw_key);
|
free(in->data);
|
||||||
free(in);
|
free(in);
|
||||||
in = NULL;
|
in = NULL;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +31,10 @@ void libp2p_crypto_public_key_free(struct PublicKey* in) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmarshal a public key from a protobuf
|
* Unmarshal a public key from a protobuf
|
||||||
|
* @param buffer the protobuf
|
||||||
|
* @param buffer_length the length of the protobuf
|
||||||
|
* @param out the pointer to the struct PublicKey that will be allocated
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
*/
|
*/
|
||||||
int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out) {
|
int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out) {
|
||||||
|
|
||||||
|
@ -55,12 +57,12 @@ int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffe
|
||||||
pos += bytes_read;
|
pos += bytes_read;
|
||||||
switch(field_no) {
|
switch(field_no) {
|
||||||
case (1): // type
|
case (1): // type
|
||||||
if (protobuf_decode_varint(&buffer[pos], buffer_length - pos, &((*out)->key_type), &bytes_read) == 0)
|
if (protobuf_decode_varint(&buffer[pos], buffer_length - pos, (long long unsigned int*)&((*out)->type), &bytes_read) == 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
pos += bytes_read;
|
pos += bytes_read;
|
||||||
break;
|
break;
|
||||||
case (2): // key
|
case (2): // key
|
||||||
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->raw_key), &((*out)->raw_key_size), &bytes_read) == 0)
|
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->data), &((*out)->data_size), &bytes_read) == 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
pos += bytes_read;
|
pos += bytes_read;
|
||||||
break;
|
break;
|
||||||
|
@ -75,3 +77,94 @@ exit:
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PrivateKey* libp2p_crypto_private_key_new() {
|
||||||
|
struct PrivateKey* retVal = malloc(sizeof(struct PrivateKey));
|
||||||
|
if (retVal == NULL)
|
||||||
|
return NULL;
|
||||||
|
retVal->type = KEYTYPE_INVALID;
|
||||||
|
retVal->data = NULL;
|
||||||
|
retVal->data_size = 0;
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void libp2p_crypto_private_key_free(struct PrivateKey* in) {
|
||||||
|
if (in != NULL) {
|
||||||
|
if (in->data != NULL)
|
||||||
|
free(in->data);
|
||||||
|
free(in);
|
||||||
|
in = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmarshal a private key from a protobuf
|
||||||
|
* @param buffer the protobuf
|
||||||
|
* @param buffer_length the length of the protobuf
|
||||||
|
* @param out the pointer to the struct PrivateKey that will be allocated
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_private_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PrivateKey** out) {
|
||||||
|
|
||||||
|
// first field is type (RSA vs ED25519)
|
||||||
|
// second field is the public key
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
if ( (*out = libp2p_crypto_private_key_new()) == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
while(pos < buffer_length) {
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
int field_no;
|
||||||
|
enum WireType field_type;
|
||||||
|
if (protobuf_decode_field_and_type(&buffer[pos], buffer_length, &field_no, &field_type, &bytes_read) == 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
pos += bytes_read;
|
||||||
|
switch(field_no) {
|
||||||
|
case (1): // type
|
||||||
|
if (protobuf_decode_varint(&buffer[pos], buffer_length - pos, (long long unsigned int*)&((*out)->type), &bytes_read) == 0)
|
||||||
|
goto exit;
|
||||||
|
pos += bytes_read;
|
||||||
|
break;
|
||||||
|
case (2): // key
|
||||||
|
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*out)->data), &((*out)->data_size), &bytes_read) == 0)
|
||||||
|
goto exit;
|
||||||
|
pos += bytes_read;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = 1;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (retVal == 0) {
|
||||||
|
libp2p_crypto_private_key_free(*out);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a public key into a peer id
|
||||||
|
* @param public_key the public key struct
|
||||||
|
* @param peer_id the results, in a null-terminated string
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_public_key_to_peer_id(struct PublicKey* public_key, char** peer_id) {
|
||||||
|
unsigned char hashed[32];
|
||||||
|
libp2p_crypto_hashing_sha256(public_key->data, public_key->data_size, hashed);
|
||||||
|
size_t final_id_size = 100;
|
||||||
|
unsigned char final_id[final_id_size];
|
||||||
|
memset(final_id, 0, final_id_size);
|
||||||
|
if (!PrettyID(final_id, &final_id_size, hashed, 32))
|
||||||
|
return 0;
|
||||||
|
*peer_id = (char*)malloc(final_id_size + 1);
|
||||||
|
if (*peer_id == NULL)
|
||||||
|
return 0;
|
||||||
|
memset(*peer_id, 0, final_id_size + 1);
|
||||||
|
memcpy(*peer_id, final_id, final_id_size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
66
crypto/peerutils.c
Normal file
66
crypto/peerutils.c
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mh/multihash.h"
|
||||||
|
#include "mh/hashes.h"
|
||||||
|
#include "libp2p/crypto/encoding/base58.h"
|
||||||
|
#include "libp2p/crypto/sha256.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base58 encode a string NOTE: this also puts the prefix 'Qm' in front as the ID is a multihash
|
||||||
|
* @param pointyaddr where the results will go
|
||||||
|
* @param rezbuflen the length of the results buffer. It will also put how much was used here
|
||||||
|
* @param ID_BUF the input text (usually a SHA256 hash)
|
||||||
|
* @param ID_BUF_SIZE the input size (normally a SHA256, therefore 32 bytes)
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int PrettyID(unsigned char * pointyaddr, size_t* rezbuflen,unsigned char * ID_BUF, size_t ID_BUF_SIZE)//b58 encoded ID buf
|
||||||
|
{
|
||||||
|
int returnstatus = 0;
|
||||||
|
|
||||||
|
unsigned char temp_buffer[*rezbuflen];
|
||||||
|
|
||||||
|
memset(temp_buffer, 0, *rezbuflen);
|
||||||
|
|
||||||
|
// wrap the base58 into a multihash
|
||||||
|
int retVal = mh_new(temp_buffer, MH_H_SHA2_256, ID_BUF, ID_BUF_SIZE);
|
||||||
|
if (retVal < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// base58 the multihash
|
||||||
|
returnstatus = libp2p_crypto_encoding_base58_encode(temp_buffer, strlen((char*)temp_buffer), &pointyaddr, rezbuflen);
|
||||||
|
if(returnstatus == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
* Make a SHA256 hash of what is usually the DER formatted private key.
|
||||||
|
* @param result where to store the result. Should be 32 chars long
|
||||||
|
* @param texttohash the text to hash
|
||||||
|
* @param text_size the size of the text
|
||||||
|
*/
|
||||||
|
void ID_FromPK_non_null_terminated(char * result,unsigned char * texttohash, size_t text_size)
|
||||||
|
{
|
||||||
|
/* old way
|
||||||
|
unsigned char hash[32];
|
||||||
|
bzero(hash,32);
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
sha256_init(&ctx);
|
||||||
|
sha256_update(&ctx,texttohash,text_size);
|
||||||
|
sha256_final(&ctx,hash);
|
||||||
|
a_store_hash(result,hash);
|
||||||
|
*/
|
||||||
|
libp2p_crypto_hashing_sha256(texttohash, text_size, (unsigned char*)result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
* Make a SHA256 hash of what is usually the DER formatted private key.
|
||||||
|
* @param result where to store the result. Should be 32 chars long
|
||||||
|
* @param texttohash a null terminated string of the text to hash
|
||||||
|
*/
|
||||||
|
void ID_FromPK(char * result,unsigned char * texttohash)
|
||||||
|
{
|
||||||
|
ID_FromPK_non_null_terminated(result,texttohash,strlen((char*)texttohash));
|
||||||
|
}
|
|
@ -92,7 +92,7 @@ A million repetitions of "a"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <libp2p/routing/sha1.h>
|
#include "libp2p/crypto/sha1.h"
|
||||||
|
|
||||||
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,21 @@ struct PrivateKey {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PublicKey* libp2p_crypto_public_key_new();
|
struct PublicKey* libp2p_crypto_public_key_new();
|
||||||
|
|
||||||
void libp2p_crypto_public_key_free(struct PublicKey* in);
|
void libp2p_crypto_public_key_free(struct PublicKey* in);
|
||||||
|
|
||||||
|
struct PrivateKey* libp2p_crypto_private_key_new();
|
||||||
|
void libp2p_crypto_private_key_free(struct PrivateKey* in);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmarshal a public key from a protobuf
|
* Unmarshal a public key from a protobuf
|
||||||
*/
|
*/
|
||||||
int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out);
|
int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out);
|
||||||
int libp2p_crypto_private_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out);
|
int libp2p_crypto_private_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PrivateKey** out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a public key into a peer id
|
||||||
|
* @param public_key the public key struct
|
||||||
|
* @param peer_id the results, in a null-terminated string
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_public_key_to_peer_id(struct PublicKey* public_key, char** peer_id);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "mh/multihash.h"
|
#include "mh/multihash.h"
|
||||||
#include "mh/hashes.h"
|
#include "mh/hashes.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
#define uchar unsigned char // 8-bit byte
|
#define uchar unsigned char // 8-bit byte
|
||||||
#define juint unsigned int // 32-bit word
|
#define juint unsigned int // 32-bit word
|
||||||
// DBL_INT_ADD treats two unsigned ints a and b as one 64-bit integer and adds c to it
|
// DBL_INT_ADD treats two unsigned ints a and b as one 64-bit integer and adds c to it
|
||||||
|
@ -170,6 +172,8 @@ void a_store_hash(unsigned char * result,unsigned char hash[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* base58 encode a string NOTE: this also puts the prefix 'Qm' in front as the ID is a multihash
|
* base58 encode a string NOTE: this also puts the prefix 'Qm' in front as the ID is a multihash
|
||||||
* @param pointyaddr where the results will go
|
* @param pointyaddr where the results will go
|
||||||
|
@ -178,26 +182,7 @@ void a_store_hash(unsigned char * result,unsigned char hash[])
|
||||||
* @param ID_BUF_SIZE the input size (normally a SHA256, therefore 32 bytes)
|
* @param ID_BUF_SIZE the input size (normally a SHA256, therefore 32 bytes)
|
||||||
* @returns true(1) on success
|
* @returns true(1) on success
|
||||||
*/
|
*/
|
||||||
int PrettyID(unsigned char * pointyaddr, size_t* rezbuflen,unsigned char * ID_BUF, size_t ID_BUF_SIZE)//b58 encoded ID buf
|
int PrettyID(unsigned char * pointyaddr, size_t* rezbuflen,unsigned char * ID_BUF, size_t ID_BUF_SIZE);//b58 encoded ID buf
|
||||||
{
|
|
||||||
int returnstatus = 0;
|
|
||||||
|
|
||||||
unsigned char temp_buffer[*rezbuflen];
|
|
||||||
|
|
||||||
memset(temp_buffer, 0, *rezbuflen);
|
|
||||||
|
|
||||||
// wrap the base58 into a multihash
|
|
||||||
int retVal = mh_new(temp_buffer, MH_H_SHA2_256, ID_BUF, ID_BUF_SIZE);
|
|
||||||
if (retVal < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// base58 the multihash
|
|
||||||
returnstatus = libp2p_crypto_encoding_base58_encode(temp_buffer, strlen((char*)temp_buffer), &pointyaddr, rezbuflen);
|
|
||||||
if(returnstatus == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****
|
/****
|
||||||
* Make a SHA256 hash of what is usually the DER formatted private key.
|
* Make a SHA256 hash of what is usually the DER formatted private key.
|
||||||
|
@ -205,28 +190,13 @@ int PrettyID(unsigned char * pointyaddr, size_t* rezbuflen,unsigned char * ID_BU
|
||||||
* @param texttohash the text to hash
|
* @param texttohash the text to hash
|
||||||
* @param text_size the size of the text
|
* @param text_size the size of the text
|
||||||
*/
|
*/
|
||||||
void ID_FromPK_non_null_terminated(char * result,unsigned char * texttohash, size_t text_size)
|
void ID_FromPK_non_null_terminated(char * result,unsigned char * texttohash, size_t text_size);
|
||||||
{
|
|
||||||
/* old way
|
|
||||||
unsigned char hash[32];
|
|
||||||
bzero(hash,32);
|
|
||||||
SHA256_CTX ctx;
|
|
||||||
sha256_init(&ctx);
|
|
||||||
sha256_update(&ctx,texttohash,text_size);
|
|
||||||
sha256_final(&ctx,hash);
|
|
||||||
a_store_hash(result,hash);
|
|
||||||
*/
|
|
||||||
libp2p_crypto_hashing_sha256(texttohash, text_size, (unsigned char*)result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****
|
/****
|
||||||
* Make a SHA256 hash of what is usually the DER formatted private key.
|
* Make a SHA256 hash of what is usually the DER formatted private key.
|
||||||
* @param result where to store the result. Should be 32 chars long
|
* @param result where to store the result. Should be 32 chars long
|
||||||
* @param texttohash a null terminated string of the text to hash
|
* @param texttohash a null terminated string of the text to hash
|
||||||
*/
|
*/
|
||||||
void ID_FromPK(char * result,unsigned char * texttohash)
|
void ID_FromPK(char * result,unsigned char * texttohash);
|
||||||
{
|
|
||||||
ID_FromPK_non_null_terminated(result,texttohash,strlen((char*)texttohash));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
30
include/libp2p/net/multistream.h
Normal file
30
include/libp2p/net/multistream.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/***
|
||||||
|
* An implementation of the libp2p multistream
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to an open multistream host
|
||||||
|
* @param socket_fd the socket file descriptor
|
||||||
|
* @param data the data to send
|
||||||
|
* @param data_length the length of the data
|
||||||
|
* @returns the number of bytes written
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_send(int socket_fd, const unsigned char* data, size_t data_length);
|
||||||
|
/**
|
||||||
|
* Read from a multistream socket
|
||||||
|
* @param socket_fd the socket file descriptor
|
||||||
|
* @param results where to put the results. NOTE: this memory is allocated
|
||||||
|
* @param results_size the size of the results in bytes
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_receive(int socket_fd, char** results, size_t* results_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to a multistream host, and this includes the multistream handshaking.
|
||||||
|
* @param hostname the host
|
||||||
|
* @param port the port
|
||||||
|
* @returns the socket file descriptor of the connection, or -1 on error
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_connect(const char* hostname, int port);
|
37
include/libp2p/net/p2pnet.h
Normal file
37
include/libp2p/net/p2pnet.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef P2PNET_H
|
||||||
|
#define P2PNET_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int socket_open4();
|
||||||
|
int socket_bind4(int s, uint32_t ip, uint16_t port);
|
||||||
|
int socket_bind4_reuse(int s, uint32_t ip, uint16_t port);
|
||||||
|
int socket_accept4(int s, uint32_t *ip, uint16_t *port);
|
||||||
|
int socket_local4(int s, uint32_t *ip, uint16_t *port);
|
||||||
|
int socket_connect4(int s, uint32_t ip, uint16_t port);
|
||||||
|
int socket_listen(int s, uint32_t *localip, uint16_t *localport);
|
||||||
|
ssize_t socket_read(int s, char *buf, size_t len, int flags);
|
||||||
|
ssize_t socket_write(int s, char *buf, size_t len, int flags);
|
||||||
|
/**
|
||||||
|
* Used to send the size of the next transmission for "framed" transmissions. NOTE: This will send in big endian format
|
||||||
|
* @param s the socket descriptor
|
||||||
|
* @param size the size to send
|
||||||
|
* @param flags socket flags
|
||||||
|
* @returns number of bytes sent
|
||||||
|
*/
|
||||||
|
ssize_t socket_write_size(int s, unsigned long size, int flags);
|
||||||
|
|
||||||
|
int socket_tcp4(void);
|
||||||
|
|
||||||
|
int socket_stream_sctp4(void);
|
||||||
|
|
||||||
|
int socket_udp4(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a hostname into an ip address
|
||||||
|
* @param hostname the name of the host. i.e. www.jmjatlanta.com
|
||||||
|
* @returns the ip address as an uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t hostname_to_ip(const char* hostname);
|
||||||
|
|
||||||
|
#endif // P2PNET_H
|
|
@ -23,7 +23,7 @@ void libp2p_secio_propose_free(struct Propose* in);
|
||||||
* @param from_size the size of from
|
* @param from_size the size of from
|
||||||
* @returns true(1) on success, otherwise false(0)
|
* @returns true(1) on success, otherwise false(0)
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_propose_set_property(void** to, size_t* to_size, void* from, size_t from_size);
|
int libp2p_secio_propose_set_property(void** to, size_t* to_size, const void* from, size_t from_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieves the approximate size of an encoded version of the passed in struct
|
* retrieves the approximate size of an encoded version of the passed in struct
|
||||||
|
|
|
@ -1,13 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libp2p/crypto/key.h"
|
#include "libp2p/crypto/key.h"
|
||||||
|
#include "libp2p/crypto/rsa.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A secure connection
|
* A secure connection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum IPTrafficType { TCP, UDP };
|
||||||
|
|
||||||
struct SecureSession {
|
struct SecureSession {
|
||||||
|
// to get the connection started
|
||||||
|
char* host;
|
||||||
|
int port;
|
||||||
|
enum IPTrafficType traffic_type;
|
||||||
|
// once the connection is established
|
||||||
int socket_descriptor;
|
int socket_descriptor;
|
||||||
struct PublicKey remote_key;
|
struct PublicKey remote_key;
|
||||||
int remote_peer_id;
|
char* remote_peer_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***
|
||||||
|
* performs initial communication over an insecure channel to share
|
||||||
|
* keys, IDs, and initiate connection. This is a framed messaging system
|
||||||
|
* @param session the secure session to be filled
|
||||||
|
* @returns true(1) on success, false(0) otherwise
|
||||||
|
*/
|
||||||
|
int libp2p_secio_handshake(struct SecureSession* session, struct RsaPrivateKey* private_key);
|
||||||
|
|
18
net/Makefile
Normal file
18
net/Makefile
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -O0 -Wall -I../include -I../../c-protobuf
|
||||||
|
|
||||||
|
ifdef DEBUG
|
||||||
|
CFLAGS += -g3
|
||||||
|
endif
|
||||||
|
|
||||||
|
LFLAGS =
|
||||||
|
DEPS =
|
||||||
|
OBJS = sctp.o socket.o tcp.o udp.o multistream.o
|
||||||
|
|
||||||
|
%.o: %.c $(DEPS)
|
||||||
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
|
all: $(OBJS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
117
net/multistream.c
Normal file
117
net/multistream.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
#include "varint.h"
|
||||||
|
|
||||||
|
/***
|
||||||
|
* An implementation of the libp2p multistream
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to an open multistream host
|
||||||
|
* @param socket_fd the socket file descriptor
|
||||||
|
* @param data the data to send
|
||||||
|
* @param data_length the length of the data
|
||||||
|
* @returns the number of bytes written
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_send(int socket_fd, const unsigned char* data, size_t data_length) {
|
||||||
|
int num_bytes = 0;
|
||||||
|
|
||||||
|
if (data_length > 0) { // only do this is if there is something to send
|
||||||
|
// first send the size
|
||||||
|
unsigned char varint[12];
|
||||||
|
size_t varint_size = 0;
|
||||||
|
varint_encode(data_length, &varint[0], 12, &varint_size);
|
||||||
|
num_bytes = socket_write(socket_fd, (char*)varint, varint_size, 0);
|
||||||
|
if (num_bytes == 0)
|
||||||
|
return 0;
|
||||||
|
// then send the actual data
|
||||||
|
num_bytes += socket_write(socket_fd, (char*)data, data_length, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Parse the incoming data, removing the size indicator at the front of the array
|
||||||
|
* @param incoming the incoming data
|
||||||
|
* @param incoming_size the size of the incoming data
|
||||||
|
* @param outgoing the buffer to hold the outgoing data, allocated within this function
|
||||||
|
* @param outgoing_size the outgoing size
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_parse_results(char* incoming, size_t incoming_size, char** outgoing, size_t* outgoing_size) {
|
||||||
|
int retVal = 0;
|
||||||
|
if (incoming_size > 0) {
|
||||||
|
// TODO: handle this differently
|
||||||
|
// read the varint
|
||||||
|
// allocate memory
|
||||||
|
*outgoing = (char*)malloc(incoming_size - 1);
|
||||||
|
if (*outgoing == NULL)
|
||||||
|
return 0;
|
||||||
|
// copy in the data
|
||||||
|
memcpy(*outgoing, &incoming[1], incoming_size - 1);
|
||||||
|
*outgoing_size = incoming_size - 1;
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from a multistream socket
|
||||||
|
* @param socket_fd the socket file descriptor
|
||||||
|
* @param results where to put the results. NOTE: this memory is allocated
|
||||||
|
* @param results_size the size of the results in bytes
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_receive(int socket_fd, char** results, size_t* results_size) {
|
||||||
|
int bytes = 0;
|
||||||
|
size_t buffer_size = 65535;
|
||||||
|
char buffer[buffer_size];
|
||||||
|
|
||||||
|
bytes = socket_read(socket_fd, buffer, buffer_size, 0);
|
||||||
|
if (bytes == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// parse the results, removing the leading size indicator
|
||||||
|
return libp2p_net_multistream_parse_results(buffer, bytes, results, results_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to a multistream host, and this includes the multistream handshaking.
|
||||||
|
* @param hostname the host
|
||||||
|
* @param port the port
|
||||||
|
* @returns the socket file descriptor of the connection, or -1 on error
|
||||||
|
*/
|
||||||
|
int libp2p_net_multistream_connect(const char* hostname, int port) {
|
||||||
|
int retVal = -1, socket = -1;
|
||||||
|
char* results = NULL;
|
||||||
|
size_t results_size;
|
||||||
|
size_t num_bytes = 0;
|
||||||
|
|
||||||
|
uint32_t ip = hostname_to_ip(hostname);
|
||||||
|
socket = socket_open4();
|
||||||
|
|
||||||
|
// connect
|
||||||
|
if (socket_connect4(socket, ip, port) != 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// try to receive the protocol id
|
||||||
|
retVal = libp2p_net_multistream_receive(socket, &results, &results_size);
|
||||||
|
|
||||||
|
// send the multistream handshake
|
||||||
|
const char* protocol_buffer = "/multistream/1.0.0\n";
|
||||||
|
|
||||||
|
num_bytes = libp2p_net_multistream_send(socket, (const unsigned char*)protocol_buffer, strlen(protocol_buffer));
|
||||||
|
if (num_bytes <= 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
retVal = socket;
|
||||||
|
exit:
|
||||||
|
if (results != NULL)
|
||||||
|
free(results);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
18
net/p2pnet.h
18
net/p2pnet.h
|
@ -1,18 +0,0 @@
|
||||||
#ifndef P2PNET_H
|
|
||||||
#define P2PNET_H
|
|
||||||
|
|
||||||
int socket_bind4(int s, uint32_t ip, uint16_t port);
|
|
||||||
int socket_bind4_reuse(int s, uint32_t ip, uint16_t port);
|
|
||||||
int socket_accept4(int s, uint32_t *ip, uint16_t *port);
|
|
||||||
int socket_local4(int s, uint32_t *ip, uint16_t *port);
|
|
||||||
int socket_connect4(int s, uint32_t ip, uint16_t port);
|
|
||||||
int socket_listen(int s, uint32_t *localip, uint16_t *localport);
|
|
||||||
ssize_t socket_read(int s, char *buf, size_t len, int flags);
|
|
||||||
ssize_t socket_write(int s, char *buf, size_t len, int flags);
|
|
||||||
|
|
||||||
int socket_tcp4(void);
|
|
||||||
|
|
||||||
int socket_stream_sctp4(void);
|
|
||||||
|
|
||||||
int socket_udp4(void);
|
|
||||||
#endif // P2PNET_H
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "p2pnet.h"
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
|
||||||
/* Create a SCTP socket.
|
/* Create a SCTP socket.
|
||||||
*/
|
*/
|
||||||
|
|
92
net/socket.c
92
net/socket.c
|
@ -3,8 +3,11 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "p2pnet.h"
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
|
||||||
/* associate an IP address with an port to a socket.
|
/* associate an IP address with an port to a socket.
|
||||||
* first param is the socket file description
|
* first param is the socket file description
|
||||||
|
@ -64,7 +67,12 @@ int socket_local4(int s, uint32_t *ip, uint16_t *port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start a client connection.
|
/***
|
||||||
|
* start a client connection.
|
||||||
|
* @param s the socket number
|
||||||
|
* @param ip the ip address
|
||||||
|
* @param port the port number
|
||||||
|
* @return 0 on success, otherwise -1
|
||||||
*/
|
*/
|
||||||
int socket_connect4(int s, uint32_t ip, uint16_t port)
|
int socket_connect4(int s, uint32_t ip, uint16_t port)
|
||||||
{
|
{
|
||||||
|
@ -112,3 +120,83 @@ ssize_t socket_write(int s, char *buf, size_t len, int flags)
|
||||||
{
|
{
|
||||||
return send(s, buf, len, flags);
|
return send(s, buf, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int socket_open4() {
|
||||||
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
return sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to send the size of the next transmission for "framed" transmissions. NOTE: This will send in big endian format
|
||||||
|
* @param s the socket descriptor
|
||||||
|
* @param size the size to send
|
||||||
|
* @param flags socket flags
|
||||||
|
* @returns number of bytes sent
|
||||||
|
*/
|
||||||
|
ssize_t socket_write_size(int s, unsigned long size, int flags) {
|
||||||
|
// determine if we're big or little endian
|
||||||
|
int big_endian = 1;
|
||||||
|
if (*(char*)&big_endian == 1) {
|
||||||
|
big_endian = 0;
|
||||||
|
}
|
||||||
|
// convert to int32_t
|
||||||
|
int32_t conv = htonl(size);
|
||||||
|
// swap bytes if this machine is little endian
|
||||||
|
if (!big_endian) {
|
||||||
|
uint32_t b0, b1, b2, b3;
|
||||||
|
b0 = (conv & 0x000000ff) << 24u;
|
||||||
|
b1 = (conv & 0x0000ff00) << 8u;
|
||||||
|
b2 = (conv & 0x00ff0000) >> 8u;
|
||||||
|
b3 = (conv & 0xff000000) >> 24u;
|
||||||
|
conv = b0 | b1 | b2 | b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send to socket
|
||||||
|
char* data = (char*)&conv;
|
||||||
|
int left = sizeof(conv);
|
||||||
|
ssize_t rc;
|
||||||
|
int retries_left = 100;
|
||||||
|
do {
|
||||||
|
rc = send(s, data, left, flags);
|
||||||
|
if (rc < 0) {
|
||||||
|
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||||
|
retries_left--;
|
||||||
|
if (retries_left <= 0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data += rc;
|
||||||
|
left -= rc;
|
||||||
|
}
|
||||||
|
} while (left > 0);
|
||||||
|
return sizeof(conv) - left;
|
||||||
|
//return send(s, size, 4, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a hostname into an ip address
|
||||||
|
* @param hostname the name of the host. i.e. www.jmjatlanta.com
|
||||||
|
* @returns the ip address as an uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t hostname_to_ip(const char* hostname)
|
||||||
|
{
|
||||||
|
struct hostent *he;
|
||||||
|
struct in_addr **addr_list;
|
||||||
|
|
||||||
|
if ( (he = gethostbyname( hostname ) ) == NULL)
|
||||||
|
{
|
||||||
|
// get the host info
|
||||||
|
herror("gethostbyname");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_list = (struct in_addr **) he->h_addr_list;
|
||||||
|
if ((*addr_list) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return addr_list[0]->s_addr;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "p2pnet.h"
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
|
||||||
/* Create a TCP socket.
|
/* Create a TCP socket.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "p2pnet.h"
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
|
||||||
/* Create a UDP socket.
|
/* Create a UDP socket.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -32,7 +32,7 @@ void libp2p_secio_propose_free( struct Propose* in) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int libp2p_secio_propose_set_property(void** to, size_t* to_size, void* from, size_t from_size) {
|
int libp2p_secio_propose_set_property(void** to, size_t* to_size, const void* from, size_t from_size) {
|
||||||
if (*to != NULL)
|
if (*to != NULL)
|
||||||
free(*to);
|
free(*to);
|
||||||
*to = (void*)malloc(from_size);
|
*to = (void*)malloc(from_size);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "libp2p/secio/secio.h"
|
#include "libp2p/secio/secio.h"
|
||||||
#include "libp2p/secio/propose.h"
|
#include "libp2p/secio/propose.h"
|
||||||
|
#include "libp2p/net/p2pnet.h"
|
||||||
|
|
||||||
const char* SupportedExchanges = "P-256,P-384,P-521";
|
const char* SupportedExchanges = "P-256,P-384,P-521";
|
||||||
const char* SupportedCiphers = "AES-256,AES-128,Blowfish";
|
const char* SupportedCiphers = "AES-256,AES-128,Blowfish";
|
||||||
|
@ -29,56 +31,104 @@ void libp2p_secio_secure_session_free(struct SecureSession* in) {
|
||||||
free(in);
|
free(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random nonce
|
||||||
|
* @param results where to put the results
|
||||||
|
* @param length the length of the nonce
|
||||||
|
* @returns true(1) on success, otherwise false(0)
|
||||||
|
*/
|
||||||
|
int libp2p_secio_generate_nonce(char* results, int length) {
|
||||||
|
results = "abcdefghijklmno";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* performs initial communication over an insecure channel to share
|
* performs initial communication over an insecure channel to share
|
||||||
* keys, IDs, and initiate connection. This is a framed messaging system
|
* keys, IDs, and initiate connection. This is a framed messaging system
|
||||||
* @param session the secure session to be filled
|
* @param session the secure session to be filled
|
||||||
* @returns true(1) on success, false(0) otherwise
|
* @returns true(1) on success, false(0) otherwise
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_secure_session_handshake(struct SecureSession* session, struct RsaPrivateKey* private_key) {
|
int libp2p_secio_handshake(struct SecureSession* session, struct RsaPrivateKey* private_key) {
|
||||||
int retVal = 0, protobuf_size = 0, results_size = 0;
|
int retVal = 0, results_size = 65535, bytes_written = 0;
|
||||||
unsigned char* protobuf = 0;;
|
size_t protobuf_size = 0;
|
||||||
unsigned char* results;
|
unsigned char* protobuf = 0;
|
||||||
struct Propose* propose = NULL;
|
unsigned char results[results_size];
|
||||||
struct SocketMuxer* socketMuxer;
|
struct Propose* propose_out = NULL;
|
||||||
|
struct Propose* propose_in = NULL;
|
||||||
|
struct PublicKey* public_key = NULL;
|
||||||
|
uint32_t ip;
|
||||||
|
int socket;
|
||||||
|
|
||||||
// generate 16 byte nonce
|
// generate 16 byte nonce
|
||||||
char nonceOut[16];
|
char nonceOut[16];
|
||||||
if (!generateNonce(&nonceOut, 16)) {
|
if (!libp2p_secio_generate_nonce(&nonceOut[0], 16)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
propose = libp2p_secio_propose_new();
|
propose_out = libp2p_secio_propose_new();
|
||||||
libp2p_secio_propose_set_property(&propose->rand, &propose->rand_size, nonceOut, 16);
|
libp2p_secio_propose_set_property((void**)&propose_out->rand, &propose_out->rand_size, nonceOut, 16);
|
||||||
|
|
||||||
// will need:
|
// will need:
|
||||||
// TODO: public key
|
// TODO: public key
|
||||||
// supported exchanges
|
// supported exchanges
|
||||||
libp2p_secio_propose_set_property(&propose->exchanges, &propose->exchanges_size, SupportedExchanges, strlen(SupportedExchanges));
|
libp2p_secio_propose_set_property((void**)&propose_out->exchanges, &propose_out->exchanges_size, SupportedExchanges, strlen(SupportedExchanges));
|
||||||
// supported ciphers
|
// supported ciphers
|
||||||
libp2p_secio_propose_set_property(&propose->ciphers, &propose->ciphers_size, SupportedCiphers, strlen(SupportedCiphers));
|
libp2p_secio_propose_set_property((void**)&propose_out->ciphers, &propose_out->ciphers_size, SupportedCiphers, strlen(SupportedCiphers));
|
||||||
// supported hashes
|
// supported hashes
|
||||||
libp2p_secio_propose_set_property(&propose->hashes, &propose->exchanges_size, SupportedHashes, strlen(SupportedHashes));
|
libp2p_secio_propose_set_property((void**)&propose_out->hashes, &propose_out->exchanges_size, SupportedHashes, strlen(SupportedHashes));
|
||||||
|
|
||||||
// send request (protobuf, then send)
|
// send request (protobuf, then send)
|
||||||
protobuf_size = libp2p_secio_propose_protobuf_encode_size(propose);
|
protobuf_size = libp2p_secio_propose_protobuf_encode_size(propose_out);
|
||||||
protobuf = (unsigned char*) malloc(protobuf_size);
|
protobuf = (unsigned char*) malloc(protobuf_size);
|
||||||
if (protobuf == NULL)
|
if (protobuf == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
if (!libp2p_secio_propose_protobuf_encode(propose, protobuf, protobuf_size, &protobuf_size))
|
if (!libp2p_secio_propose_protobuf_encode(propose_out, protobuf, protobuf_size, &protobuf_size))
|
||||||
goto exit;
|
goto exit;
|
||||||
libp2p_secio_propose_free(propose);
|
ip = hostname_to_ip(session->host);
|
||||||
if (!libp2p_net_socket_muxer_send(socketMuxer, protobuf, protobuf_size))
|
socket = socket_open4();
|
||||||
|
// connect
|
||||||
|
if (socket_connect4(socket, ip, session->port) != 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// try 1
|
||||||
|
// first try to send mulitstream line
|
||||||
|
char buf[21];
|
||||||
|
buf[0] = 23;
|
||||||
|
strcpy(&buf[1], "/multistream/1.0.0\n");
|
||||||
|
bytes_written = socket_write_size(socket, 20, sizeof(uint32_t));
|
||||||
|
if (bytes_written != 4)
|
||||||
|
goto exit;
|
||||||
|
bytes_written = socket_write(socket, buf, 20, 0);
|
||||||
|
if (bytes_written != 20)
|
||||||
|
goto exit;
|
||||||
|
// check to see what was written back...
|
||||||
|
bytes_written = socket_read(socket, (char*)&results[0], results_size, 0);
|
||||||
|
if (bytes_written == 65535)
|
||||||
|
goto exit;
|
||||||
|
// end of try 1
|
||||||
|
|
||||||
|
// send struct Propose in protobuf format
|
||||||
|
bytes_written = socket_write_size(socket, protobuf_size, sizeof(uint32_t));
|
||||||
|
if (bytes_written != 4)
|
||||||
|
goto exit;
|
||||||
|
bytes_written = socket_write(socket, (char*)protobuf, protobuf_size, 0);
|
||||||
|
if (bytes_written != protobuf_size)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// receive response (turn back into a Propose struct)
|
// receive response (turn back into a Propose struct)
|
||||||
if (!libp2p_net_socket_muxer_receive(socketMuxer, &results, &results_size))
|
bytes_written = socket_read(socket, (char*)&results[0], results_size, 0);
|
||||||
|
if (bytes_written == 65535)
|
||||||
goto exit;
|
goto exit;
|
||||||
if (!libp2p_secio_propose_protobuf_decode(results, results_size, &propose))
|
|
||||||
|
if (!libp2p_secio_propose_protobuf_decode(results, results_size, &propose_in))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// get public key
|
// get public key
|
||||||
|
if (!libp2p_crypto_public_key_protobuf_decode(propose_in->public_key, propose_in->public_key_size, &public_key))
|
||||||
|
goto exit;
|
||||||
// generate their peer id
|
// generate their peer id
|
||||||
|
char* remote_peer_id;
|
||||||
|
libp2p_crypto_public_key_to_peer_id(public_key, &remote_peer_id);
|
||||||
|
|
||||||
// negotiate encryption parameters NOTE: SelectBest must match, otherwise this won't work
|
// negotiate encryption parameters NOTE: SelectBest must match, otherwise this won't work
|
||||||
// curve
|
// curve
|
||||||
|
@ -101,7 +151,8 @@ int libp2p_secio_secure_session_handshake(struct SecureSession* session, struct
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|
||||||
ipfs_secio_propose_free(propose);
|
libp2p_secio_propose_free(propose_out);
|
||||||
|
libp2p_secio_propose_free(propose_in);
|
||||||
if (protobuf != NULL)
|
if (protobuf != NULL)
|
||||||
free(protobuf);
|
free(protobuf);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ endif
|
||||||
|
|
||||||
LFLAGS = -L../ -L../../c-multihash
|
LFLAGS = -L../ -L../../c-multihash
|
||||||
DEPS = crypto/test_base58.h crypto/test_rsa.h test_mbedtls.h
|
DEPS = crypto/test_base58.h crypto/test_rsa.h test_mbedtls.h
|
||||||
OBJS = testit.o
|
OBJS = testit.o ../../c-protobuf/protobuf.o ../../c-protobuf/varint.o ../libp2p.a
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
|
@ -8,31 +8,30 @@ int test_protobuf_private_key() {
|
||||||
size_t decode_base64_size = 0;
|
size_t decode_base64_size = 0;
|
||||||
unsigned char* decode_base64;
|
unsigned char* decode_base64;
|
||||||
// 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
|
||||||
char* orig_priv_key = "CAASpwkwggSjAgEAAoIBAQDTDJBWjDzS/HxDNOHazvzH2bu9CPMVHUrrvKRdBUM5ansL6/CC3MVZ6HVm4O6QHRapN6EF2CbrTgI4KBOXIL125Xo8MlROnyfXYk3O5q2tgwL/MbW8kXjtkyCfBak7MUoLOdLU7Svg0gkl3l+uDAiDcCLnwJVcFfq9ch6z4wMOhYJqE5dtx0uXxn6IuKWl1B69FTvBXCc0thw8Rw54b941FDcsBH5ttV9mRNCJym3poZ5qalNgXlxoIIB+PUx5QD+aq7KMJdpAX8HkapBntCOahP/QUceRmma0grlZLeYkH6/oi/hIrM6se3KUZ+F6tBuDFys8UAZy/X2BCUbKjbxtAgMBAAECggEANWfQfpYuLhXGPBt9q6kFPm1SnJtPJ+CpvM2XqhJS2IyhZnrl+bd0GTRBwS7aL42s1lVFYf04nAK5fQxnKK8YQqX/MIxr2RldM5ukpN6qxGWKtJkXrAgD2dqJPrRoBpqKahzPxSHfIJ0Fw5dqDtjsrpYJvyt0oEDPmnDuZAbmFx4sJqnesPNhKxtRMBx1+yxGVuRVJjHcqAgqPqwNiuoMEaYMY+G9yzT6vza8ovCpbX7BBIgM5fAT9PD8TBG//Vu9THvj/ZomiVG2qv6RL0qQyVb+DUzPZz1amBsSvahtXCl72jA3JwAZ943RxSR66P934S0ashkVwLUi46z/EAbJ4QKBgQDojGIO07BEVL2+7VxlGL9XGZQp4Y3qlhh2zDDQGwkCq/KQ+BdNYWitPwqRl9GqFLgpmeQIhyHTOa/IThx+AXGKVQ24ROH+skUs4IbO6R3qY7BKtb5lkZE/Yln09x70BBngUYAzh/rtnsXO3cl1x2XDDqUbCwlGcDAs8Jh/6UnvQwKBgQDoVSQs7Uq9MJCGIUM2bixX89tHzSxq5mn9wMD3/XRVfT5Ua8YkYBuzcmlcT39N7L5BwuyFqX3Vi7lv/Ya/qaQP6XkrZ8W1OAaTlYewfE5ZgknJqSpXcNWhABKeNmqndvqyQ/8HNCv/j8AdraGB2DGO57Xso5J0CQ43W/U9+QIyjwKBgHLL2hw3o+wXaRO3WMUPUmVM2zdRgR0suybp5a7Vqb0H5NZrohUw4NulIzJ8H6Q2VjMzJL6Q9sGu2HepF6ecTtBa7ErqtiVlG4Dr1aCOs5XhYEWBMlwxX+JKSt4Cn+UVoTB7Cy5lEhn7JurX0Xuy0ylXMWoIKKv89cs5eg6quzTBAoGAaq9eEztLjKCWXOE9SetBdYnG8aunb9cqaJlwgu/h0bfXPVDYBbAUSEyLURY4MQI7Q1tM3Pu9iqfEmUZj7/LoIV5mg6X9RX/alT6etk3+dF+9nlqN1OU9U9cCtZ/rTcb2y5EptJcidRH/eCFY/pTV/PcttOJPx/S4kHcroC+N8MUCgYEA6DA5QHxHfNN6Nxv+pEzy2DIxFe9RrBxS+KPBsra1C8jgdeMf4EmfU0Nox92V0q0bRrD5ztqQwSONI0hSRb1iiMWR6MuFnAFajUJfASjjIlZ6nIQjQslI7vjlvYyyHS/p/Codxap+yJlTLWwVEOXp2D9pWwiMq1xEyf0TH1BosvM=";
|
// these were pulled from the GO version of ipfs
|
||||||
|
char* orig_priv_key = "CAASqgkwggSmAgEAAoIBAQD0a4RI+bF/ov7IVOGSJ8dQfnK1DwM0gwVuJAd+3LXxIZEPZzsKIKia0TojDbTdLvOJ23wsaojTF/4bSzBK5otdAz8YSgez4vTRUV5pUqvCkK0dSJJ1DHTdrFUwvzlXuKbwNbvWyzjmKfeaE9a9YLzhrUIUTRvKyqhZXr++vMy3hw4fdtGUTJWeiqmoIuJWIZ1748Ff6LjcP7TdG7OvY4q+U9ilEJYdF4aM+TJY193zKp0GNWohunuVrtOUnL9VQaSSDbvGdFS1Mg9iCN6kRBQTHVQvFzvuEw/Y2LvoPH3yFG1zj6bDLWfOBhegy/6Zi6fi4E1UfgJNFN1sjWF+gZoHAgMBAAECggEBALTqBD9zuoMsJYQo99IT6X7WKZeE5i1vMYzF1Fp9iZpS6ylIkrW7WLFHXs3lblMtVoxazn2d2WrOXoLbU4KNROhy57fVy//FZMqufMBetc3NAqYjOmyy7KnLzj7Hu+0HO2GflEq3n4UV2TTNrGv+d7BfawLV1FV1TcjgzfKjkq/gMDCTPMgfT7lcF4TGSqv6Pgudp8RRn/R7EKOx+I8/XkJsZWP3XJ0zj4ciqDmKrX2j7wZMT8CH/8wfyg4NGk1+TN4xBB2CXgulIWJg5yhzu+JgbGnHEL/Ga+i40XJe+RnlKDpjQ+ZFyrOkmHpIldasjWNGFeKwLjzrDQfyDRwex5ECgYEA+fFGJ+zbi2YJwHDO/44PmvcoCWpho0ah7y+O5/LEVROTYEoNRqodLet+z+LMKDq/o2qTNaYJLiDGMBZzhqyJIFR5ZJ5MhgLloY1gL8s0a7KMWDbh7giiWSu5zqhB3Du8Tom+8bYZUxOL4zhzCGrFitRqiEIIjy1/c5qyRQZaZx8CgYEA+lf6tdO6kKiAOxm7sdZ3rEl4UGFY+tEqgivKwurLRIor0XDfhCKr1hCfsZggpR8SMLfjCuNEgKbceofcKMa8OtyDbMPRz0mYNkCELTUYA+r8Ib/LvleQApMcLn+TDNwEnGlglSrrF33RVAUK+i/WfSXUvZRVpLQpRmdAqHjJeBkCgYEA0+Zz/iFXOGW32slJFWxRWqYz8VeZk52saGY/l/I/9Yj1J2tgugo7VtUS3BiB0ZGNK3SNfaxYmBz9KYO/Sew5DYnQqTdz1SHboQ2FAMAcnznutlNBVFdJnKPvkX8g5yBV05gApFgoPECUFn2jOP2coMjZ0M97Bjgil9YNUWvDdS0CgYEA4beFs3+tzVRAGgl/tD7dNBgiRMchBTSmkSuO6+PrVmcGTxboUSk5qg7fDa9Ob9LuAcMrENwNHbpVPJ1WoeVePewpC14bxDxk4zWUd3ZRquaqYnud5obor4mYdUxNd+DAv447qQNDaLDmlkzdsuqDB9+eSzh9Z72RIYtjPwN5E7ECgYEAsbqkMZXfK1tTRfduX+7KOlPMfcSr29X6nuDglcna4dHec6FAOzp3xL2722nnFt6gygc7pErrm0m0Wd/6BMTb4T3+GYwkDiMjM2CsTZYjpzrUri/VfRR509rScxHVR0/1PTFWN0K0+VZbEAyXDbbs4opq40tW0dWtcKxaNlimMw8=";
|
||||||
struct PrivateKey* private_key = libp2p_crypto_private_key_new();
|
struct PrivateKey* private_key = libp2p_crypto_private_key_new();
|
||||||
struct RsaPrivateKey rsa_private_key = {0};
|
struct RsaPrivateKey rsa_private_key = {0};
|
||||||
|
char* orig_peer_id = "QmbTyKkUuv6yaSpTuCFq1Ft6Q3g4wTtFJk1BLGMPRdAEP8";
|
||||||
|
size_t orig_peer_id_size = strlen(orig_peer_id);
|
||||||
|
unsigned char hashed[32];
|
||||||
|
size_t final_id_size = 1600;
|
||||||
|
unsigned char final_id[final_id_size];
|
||||||
|
|
||||||
// convert from base64
|
|
||||||
|
|
||||||
// 1) take the private key and turn it back into bytes (decode base 64)
|
// 1) take the private key and turn it back into bytes (decode base 64)
|
||||||
decode_base64_size = libp2p_crypto_encoding_base64_decode_size(strlen(orig_priv_key));
|
decode_base64_size = libp2p_crypto_encoding_base64_decode_size(strlen(orig_priv_key));
|
||||||
decode_base64 = (unsigned char*)malloc(decode_base64_size);
|
decode_base64 = (unsigned char*)malloc(decode_base64_size);
|
||||||
memset(decode_base64, 0, decode_base64_size);
|
memset(decode_base64, 0, decode_base64_size);
|
||||||
|
|
||||||
int retVal = libp2p_crypto_encoding_base64_decode((unsigned char*)orig_priv_key, strlen(orig_priv_key), &decode_base64[0], decode_base64_size, &decode_base64_size);
|
if (!libp2p_crypto_encoding_base64_decode((unsigned char*)orig_priv_key, strlen(orig_priv_key), &decode_base64[0], decode_base64_size, &decode_base64_size))
|
||||||
if (retVal == 0)
|
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// the first 5 bytes [0-4] are protobuf metadata before the DER encoded private key
|
|
||||||
// byte 0 is "Tag 1 which is a varint"
|
|
||||||
// byte 1 is the value of the varint
|
|
||||||
// byte 2 is "Tag 2 which is a type 2, length delimited field"
|
|
||||||
// bytes 3 & 4 is a varint with the value of 1191, which is the number of bytes that follow
|
|
||||||
|
|
||||||
if (!libp2p_crypto_private_key_protobuf_decode(decode_base64, decode_base64_size, &private_key))
|
if (!libp2p_crypto_private_key_protobuf_decode(decode_base64, decode_base64_size, &private_key))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// 2) take the bytes of the private key and turn it back into a private key struct
|
// 2) take the bytes of the private key and turn it back into an RSA private key struct
|
||||||
|
//TODO: should verify that this key is RSA
|
||||||
if (!libp2p_crypto_encoding_x509_der_to_private_key(private_key->data, private_key->data_size, &rsa_private_key))
|
if (!libp2p_crypto_encoding_x509_der_to_private_key(private_key->data, private_key->data_size, &rsa_private_key))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -41,10 +40,7 @@ int test_protobuf_private_key() {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// 3) grab the public key, hash it, then base58 it
|
// 3) grab the public key, hash it, then base58 it
|
||||||
unsigned char hashed[32];
|
|
||||||
ID_FromPK_non_null_terminated((char*)hashed, (unsigned char*)rsa_private_key.public_key_der, rsa_private_key.public_key_length);
|
ID_FromPK_non_null_terminated((char*)hashed, (unsigned char*)rsa_private_key.public_key_der, rsa_private_key.public_key_length);
|
||||||
size_t final_id_size = 1600;
|
|
||||||
unsigned char final_id[final_id_size];
|
|
||||||
memset(final_id, 0, final_id_size);
|
memset(final_id, 0, final_id_size);
|
||||||
if (!PrettyID(final_id, &final_id_size, hashed, 32))
|
if (!PrettyID(final_id, &final_id_size, hashed, 32))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "libp2p/crypto/rsa.h"
|
#include "libp2p/crypto/rsa.h"
|
||||||
#include "libp2p/crypto/encoding/base64.h"
|
#include "libp2p/crypto/encoding/base64.h"
|
||||||
#include "libp2p/crypto/encoding/x509.h"
|
#include "libp2p/crypto/encoding/x509.h"
|
||||||
#include "libp2p/peerutils.h"
|
#include "libp2p/crypto/peerutils.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,9 +123,11 @@ int test_public_der_to_private_der() {
|
||||||
|
|
||||||
int test_crypto_rsa_public_key_to_peer_id() {
|
int test_crypto_rsa_public_key_to_peer_id() {
|
||||||
// this is the base64 encoded private key from the config file
|
// this is the base64 encoded private key from the config file
|
||||||
char* orig_priv_key = "CAASpwkwggSjAgEAAoIBAQDTDJBWjDzS/HxDNOHazvzH2bu9CPMVHUrrvKRdBUM5ansL6/CC3MVZ6HVm4O6QHRapN6EF2CbrTgI4KBOXIL125Xo8MlROnyfXYk3O5q2tgwL/MbW8kXjtkyCfBak7MUoLOdLU7Svg0gkl3l+uDAiDcCLnwJVcFfq9ch6z4wMOhYJqE5dtx0uXxn6IuKWl1B69FTvBXCc0thw8Rw54b941FDcsBH5ttV9mRNCJym3poZ5qalNgXlxoIIB+PUx5QD+aq7KMJdpAX8HkapBntCOahP/QUceRmma0grlZLeYkH6/oi/hIrM6se3KUZ+F6tBuDFys8UAZy/X2BCUbKjbxtAgMBAAECggEANWfQfpYuLhXGPBt9q6kFPm1SnJtPJ+CpvM2XqhJS2IyhZnrl+bd0GTRBwS7aL42s1lVFYf04nAK5fQxnKK8YQqX/MIxr2RldM5ukpN6qxGWKtJkXrAgD2dqJPrRoBpqKahzPxSHfIJ0Fw5dqDtjsrpYJvyt0oEDPmnDuZAbmFx4sJqnesPNhKxtRMBx1+yxGVuRVJjHcqAgqPqwNiuoMEaYMY+G9yzT6vza8ovCpbX7BBIgM5fAT9PD8TBG//Vu9THvj/ZomiVG2qv6RL0qQyVb+DUzPZz1amBsSvahtXCl72jA3JwAZ943RxSR66P934S0ashkVwLUi46z/EAbJ4QKBgQDojGIO07BEVL2+7VxlGL9XGZQp4Y3qlhh2zDDQGwkCq/KQ+BdNYWitPwqRl9GqFLgpmeQIhyHTOa/IThx+AXGKVQ24ROH+skUs4IbO6R3qY7BKtb5lkZE/Yln09x70BBngUYAzh/rtnsXO3cl1x2XDDqUbCwlGcDAs8Jh/6UnvQwKBgQDoVSQs7Uq9MJCGIUM2bixX89tHzSxq5mn9wMD3/XRVfT5Ua8YkYBuzcmlcT39N7L5BwuyFqX3Vi7lv/Ya/qaQP6XkrZ8W1OAaTlYewfE5ZgknJqSpXcNWhABKeNmqndvqyQ/8HNCv/j8AdraGB2DGO57Xso5J0CQ43W/U9+QIyjwKBgHLL2hw3o+wXaRO3WMUPUmVM2zdRgR0suybp5a7Vqb0H5NZrohUw4NulIzJ8H6Q2VjMzJL6Q9sGu2HepF6ecTtBa7ErqtiVlG4Dr1aCOs5XhYEWBMlwxX+JKSt4Cn+UVoTB7Cy5lEhn7JurX0Xuy0ylXMWoIKKv89cs5eg6quzTBAoGAaq9eEztLjKCWXOE9SetBdYnG8aunb9cqaJlwgu/h0bfXPVDYBbAUSEyLURY4MQI7Q1tM3Pu9iqfEmUZj7/LoIV5mg6X9RX/alT6etk3+dF+9nlqN1OU9U9cCtZ/rTcb2y5EptJcidRH/eCFY/pTV/PcttOJPx/S4kHcroC+N8MUCgYEA6DA5QHxHfNN6Nxv+pEzy2DIxFe9RrBxS+KPBsra1C8jgdeMf4EmfU0Nox92V0q0bRrD5ztqQwSONI0hSRb1iiMWR6MuFnAFajUJfASjjIlZ6nIQjQslI7vjlvYyyHS/p/Codxap+yJlTLWwVEOXp2D9pWwiMq1xEyf0TH1BosvM=";
|
//char* orig_priv_key = "CAASpwkwggSjAgEAAoIBAQDTDJBWjDzS/HxDNOHazvzH2bu9CPMVHUrrvKRdBUM5ansL6/CC3MVZ6HVm4O6QHRapN6EF2CbrTgI4KBOXIL125Xo8MlROnyfXYk3O5q2tgwL/MbW8kXjtkyCfBak7MUoLOdLU7Svg0gkl3l+uDAiDcCLnwJVcFfq9ch6z4wMOhYJqE5dtx0uXxn6IuKWl1B69FTvBXCc0thw8Rw54b941FDcsBH5ttV9mRNCJym3poZ5qalNgXlxoIIB+PUx5QD+aq7KMJdpAX8HkapBntCOahP/QUceRmma0grlZLeYkH6/oi/hIrM6se3KUZ+F6tBuDFys8UAZy/X2BCUbKjbxtAgMBAAECggEANWfQfpYuLhXGPBt9q6kFPm1SnJtPJ+CpvM2XqhJS2IyhZnrl+bd0GTRBwS7aL42s1lVFYf04nAK5fQxnKK8YQqX/MIxr2RldM5ukpN6qxGWKtJkXrAgD2dqJPrRoBpqKahzPxSHfIJ0Fw5dqDtjsrpYJvyt0oEDPmnDuZAbmFx4sJqnesPNhKxtRMBx1+yxGVuRVJjHcqAgqPqwNiuoMEaYMY+G9yzT6vza8ovCpbX7BBIgM5fAT9PD8TBG//Vu9THvj/ZomiVG2qv6RL0qQyVb+DUzPZz1amBsSvahtXCl72jA3JwAZ943RxSR66P934S0ashkVwLUi46z/EAbJ4QKBgQDojGIO07BEVL2+7VxlGL9XGZQp4Y3qlhh2zDDQGwkCq/KQ+BdNYWitPwqRl9GqFLgpmeQIhyHTOa/IThx+AXGKVQ24ROH+skUs4IbO6R3qY7BKtb5lkZE/Yln09x70BBngUYAzh/rtnsXO3cl1x2XDDqUbCwlGcDAs8Jh/6UnvQwKBgQDoVSQs7Uq9MJCGIUM2bixX89tHzSxq5mn9wMD3/XRVfT5Ua8YkYBuzcmlcT39N7L5BwuyFqX3Vi7lv/Ya/qaQP6XkrZ8W1OAaTlYewfE5ZgknJqSpXcNWhABKeNmqndvqyQ/8HNCv/j8AdraGB2DGO57Xso5J0CQ43W/U9+QIyjwKBgHLL2hw3o+wXaRO3WMUPUmVM2zdRgR0suybp5a7Vqb0H5NZrohUw4NulIzJ8H6Q2VjMzJL6Q9sGu2HepF6ecTtBa7ErqtiVlG4Dr1aCOs5XhYEWBMlwxX+JKSt4Cn+UVoTB7Cy5lEhn7JurX0Xuy0ylXMWoIKKv89cs5eg6quzTBAoGAaq9eEztLjKCWXOE9SetBdYnG8aunb9cqaJlwgu/h0bfXPVDYBbAUSEyLURY4MQI7Q1tM3Pu9iqfEmUZj7/LoIV5mg6X9RX/alT6etk3+dF+9nlqN1OU9U9cCtZ/rTcb2y5EptJcidRH/eCFY/pTV/PcttOJPx/S4kHcroC+N8MUCgYEA6DA5QHxHfNN6Nxv+pEzy2DIxFe9RrBxS+KPBsra1C8jgdeMf4EmfU0Nox92V0q0bRrD5ztqQwSONI0hSRb1iiMWR6MuFnAFajUJfASjjIlZ6nIQjQslI7vjlvYyyHS/p/Codxap+yJlTLWwVEOXp2D9pWwiMq1xEyf0TH1BosvM=";
|
||||||
|
char* orig_priv_key = "CAASqgkwggSmAgEAAoIBAQD0a4RI+bF/ov7IVOGSJ8dQfnK1DwM0gwVuJAd+3LXxIZEPZzsKIKia0TojDbTdLvOJ23wsaojTF/4bSzBK5otdAz8YSgez4vTRUV5pUqvCkK0dSJJ1DHTdrFUwvzlXuKbwNbvWyzjmKfeaE9a9YLzhrUIUTRvKyqhZXr++vMy3hw4fdtGUTJWeiqmoIuJWIZ1748Ff6LjcP7TdG7OvY4q+U9ilEJYdF4aM+TJY193zKp0GNWohunuVrtOUnL9VQaSSDbvGdFS1Mg9iCN6kRBQTHVQvFzvuEw/Y2LvoPH3yFG1zj6bDLWfOBhegy/6Zi6fi4E1UfgJNFN1sjWF+gZoHAgMBAAECggEBALTqBD9zuoMsJYQo99IT6X7WKZeE5i1vMYzF1Fp9iZpS6ylIkrW7WLFHXs3lblMtVoxazn2d2WrOXoLbU4KNROhy57fVy//FZMqufMBetc3NAqYjOmyy7KnLzj7Hu+0HO2GflEq3n4UV2TTNrGv+d7BfawLV1FV1TcjgzfKjkq/gMDCTPMgfT7lcF4TGSqv6Pgudp8RRn/R7EKOx+I8/XkJsZWP3XJ0zj4ciqDmKrX2j7wZMT8CH/8wfyg4NGk1+TN4xBB2CXgulIWJg5yhzu+JgbGnHEL/Ga+i40XJe+RnlKDpjQ+ZFyrOkmHpIldasjWNGFeKwLjzrDQfyDRwex5ECgYEA+fFGJ+zbi2YJwHDO/44PmvcoCWpho0ah7y+O5/LEVROTYEoNRqodLet+z+LMKDq/o2qTNaYJLiDGMBZzhqyJIFR5ZJ5MhgLloY1gL8s0a7KMWDbh7giiWSu5zqhB3Du8Tom+8bYZUxOL4zhzCGrFitRqiEIIjy1/c5qyRQZaZx8CgYEA+lf6tdO6kKiAOxm7sdZ3rEl4UGFY+tEqgivKwurLRIor0XDfhCKr1hCfsZggpR8SMLfjCuNEgKbceofcKMa8OtyDbMPRz0mYNkCELTUYA+r8Ib/LvleQApMcLn+TDNwEnGlglSrrF33RVAUK+i/WfSXUvZRVpLQpRmdAqHjJeBkCgYEA0+Zz/iFXOGW32slJFWxRWqYz8VeZk52saGY/l/I/9Yj1J2tgugo7VtUS3BiB0ZGNK3SNfaxYmBz9KYO/Sew5DYnQqTdz1SHboQ2FAMAcnznutlNBVFdJnKPvkX8g5yBV05gApFgoPECUFn2jOP2coMjZ0M97Bjgil9YNUWvDdS0CgYEA4beFs3+tzVRAGgl/tD7dNBgiRMchBTSmkSuO6+PrVmcGTxboUSk5qg7fDa9Ob9LuAcMrENwNHbpVPJ1WoeVePewpC14bxDxk4zWUd3ZRquaqYnud5obor4mYdUxNd+DAv447qQNDaLDmlkzdsuqDB9+eSzh9Z72RIYtjPwN5E7ECgYEAsbqkMZXfK1tTRfduX+7KOlPMfcSr29X6nuDglcna4dHec6FAOzp3xL2722nnFt6gygc7pErrm0m0Wd/6BMTb4T3+GYwkDiMjM2CsTZYjpzrUri/VfRR509rScxHVR0/1PTFWN0K0+VZbEAyXDbbs4opq40tW0dWtcKxaNlimMw8=";
|
||||||
// this is the peer id from the config file
|
// this is the peer id from the config file
|
||||||
char* orig_peer_id = "QmRskXriTSRjAftYX7QG1i1jAhouz5AHaLYZKNhEWRu5Fq";
|
//char* orig_peer_id = "QmRskXriTSRjAftYX7QG1i1jAhouz5AHaLYZKNhEWRu5Fq";
|
||||||
|
char* orig_peer_id = "QmbTyKkUuv6yaSpTuCFq1Ft6Q3g4wTtFJk1BLGMPRdAEP8";
|
||||||
size_t orig_peer_id_size = strlen(orig_peer_id);
|
size_t orig_peer_id_size = strlen(orig_peer_id);
|
||||||
// if we take the private key, retrieve the public key, hash it, we should come up with the peer id
|
// if we take the private key, retrieve the public key, hash it, we should come up with the peer id
|
||||||
|
|
||||||
|
|
35
test/test_multistream.h
Normal file
35
test/test_multistream.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include "libp2p/net/multistream.h"
|
||||||
|
|
||||||
|
int test_multistream_connect() {
|
||||||
|
int retVal = 0, socket_fd = -1;
|
||||||
|
char* response;
|
||||||
|
size_t response_size;
|
||||||
|
|
||||||
|
socket_fd = libp2p_net_multistream_connect("www.jmjatlanta.com", 4001);
|
||||||
|
if (socket_fd < 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// try to respond something, perhaps either the protocol id or the ls command
|
||||||
|
//const unsigned char* out = "/multistream/1.0.0\n";
|
||||||
|
const unsigned char* out = "ls";
|
||||||
|
|
||||||
|
if (libp2p_net_multistream_send(socket_fd, out, strlen((char*)out)) <= 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// retrieve response
|
||||||
|
retVal = libp2p_net_multistream_receive(socket_fd, &response, &response_size);
|
||||||
|
if (retVal <= 0)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
retVal = 1;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
|
||||||
|
return retVal > 0;
|
||||||
|
}
|
55
test/test_secio.h
Normal file
55
test/test_secio.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "libp2p/secio/secio.h"
|
||||||
|
|
||||||
|
|
||||||
|
int test_secio_handshake() {
|
||||||
|
int retVal = 0;
|
||||||
|
size_t decode_base64_size = 0;
|
||||||
|
unsigned char* decode_base64;
|
||||||
|
// 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
|
||||||
|
char* orig_priv_key = "CAASqgkwggSmAgEAAoIBAQD0a4RI+bF/ov7IVOGSJ8dQfnK1DwM0gwVuJAd+3LXxIZEPZzsKIKia0TojDbTdLvOJ23wsaojTF/4bSzBK5otdAz8YSgez4vTRUV5pUqvCkK0dSJJ1DHTdrFUwvzlXuKbwNbvWyzjmKfeaE9a9YLzhrUIUTRvKyqhZXr++vMy3hw4fdtGUTJWeiqmoIuJWIZ1748Ff6LjcP7TdG7OvY4q+U9ilEJYdF4aM+TJY193zKp0GNWohunuVrtOUnL9VQaSSDbvGdFS1Mg9iCN6kRBQTHVQvFzvuEw/Y2LvoPH3yFG1zj6bDLWfOBhegy/6Zi6fi4E1UfgJNFN1sjWF+gZoHAgMBAAECggEBALTqBD9zuoMsJYQo99IT6X7WKZeE5i1vMYzF1Fp9iZpS6ylIkrW7WLFHXs3lblMtVoxazn2d2WrOXoLbU4KNROhy57fVy//FZMqufMBetc3NAqYjOmyy7KnLzj7Hu+0HO2GflEq3n4UV2TTNrGv+d7BfawLV1FV1TcjgzfKjkq/gMDCTPMgfT7lcF4TGSqv6Pgudp8RRn/R7EKOx+I8/XkJsZWP3XJ0zj4ciqDmKrX2j7wZMT8CH/8wfyg4NGk1+TN4xBB2CXgulIWJg5yhzu+JgbGnHEL/Ga+i40XJe+RnlKDpjQ+ZFyrOkmHpIldasjWNGFeKwLjzrDQfyDRwex5ECgYEA+fFGJ+zbi2YJwHDO/44PmvcoCWpho0ah7y+O5/LEVROTYEoNRqodLet+z+LMKDq/o2qTNaYJLiDGMBZzhqyJIFR5ZJ5MhgLloY1gL8s0a7KMWDbh7giiWSu5zqhB3Du8Tom+8bYZUxOL4zhzCGrFitRqiEIIjy1/c5qyRQZaZx8CgYEA+lf6tdO6kKiAOxm7sdZ3rEl4UGFY+tEqgivKwurLRIor0XDfhCKr1hCfsZggpR8SMLfjCuNEgKbceofcKMa8OtyDbMPRz0mYNkCELTUYA+r8Ib/LvleQApMcLn+TDNwEnGlglSrrF33RVAUK+i/WfSXUvZRVpLQpRmdAqHjJeBkCgYEA0+Zz/iFXOGW32slJFWxRWqYz8VeZk52saGY/l/I/9Yj1J2tgugo7VtUS3BiB0ZGNK3SNfaxYmBz9KYO/Sew5DYnQqTdz1SHboQ2FAMAcnznutlNBVFdJnKPvkX8g5yBV05gApFgoPECUFn2jOP2coMjZ0M97Bjgil9YNUWvDdS0CgYEA4beFs3+tzVRAGgl/tD7dNBgiRMchBTSmkSuO6+PrVmcGTxboUSk5qg7fDa9Ob9LuAcMrENwNHbpVPJ1WoeVePewpC14bxDxk4zWUd3ZRquaqYnud5obor4mYdUxNd+DAv447qQNDaLDmlkzdsuqDB9+eSzh9Z72RIYtjPwN5E7ECgYEAsbqkMZXfK1tTRfduX+7KOlPMfcSr29X6nuDglcna4dHec6FAOzp3xL2722nnFt6gygc7pErrm0m0Wd/6BMTb4T3+GYwkDiMjM2CsTZYjpzrUri/VfRR509rScxHVR0/1PTFWN0K0+VZbEAyXDbbs4opq40tW0dWtcKxaNlimMw8=";
|
||||||
|
struct PrivateKey* private_key = libp2p_crypto_private_key_new();
|
||||||
|
struct RsaPrivateKey rsa_private_key = {0};
|
||||||
|
char* orig_peer_id = "QmbTyKkUuv6yaSpTuCFq1Ft6Q3g4wTtFJk1BLGMPRdAEP8";
|
||||||
|
size_t orig_peer_id_size = strlen(orig_peer_id);
|
||||||
|
unsigned char hashed[32];
|
||||||
|
size_t final_id_size = 1600;
|
||||||
|
unsigned char final_id[final_id_size];
|
||||||
|
|
||||||
|
// 1) take the private key and turn it back into bytes (decode base 64)
|
||||||
|
decode_base64_size = libp2p_crypto_encoding_base64_decode_size(strlen(orig_priv_key));
|
||||||
|
decode_base64 = (unsigned char*)malloc(decode_base64_size);
|
||||||
|
memset(decode_base64, 0, decode_base64_size);
|
||||||
|
|
||||||
|
if (!libp2p_crypto_encoding_base64_decode((unsigned char*)orig_priv_key, strlen(orig_priv_key), &decode_base64[0], decode_base64_size, &decode_base64_size))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (!libp2p_crypto_private_key_protobuf_decode(decode_base64, decode_base64_size, &private_key))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// 2) take the bytes of the private key and turn it back into an RSA private key struct
|
||||||
|
//TODO: should verify that this key is RSA
|
||||||
|
if (!libp2p_crypto_encoding_x509_der_to_private_key(private_key->data, private_key->data_size, &rsa_private_key))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
// 2b) take the private key and fill in the public key DER
|
||||||
|
if (!libp2p_crypto_rsa_private_key_fill_public_key(&rsa_private_key))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
|
||||||
|
struct SecureSession secure_session;
|
||||||
|
|
||||||
|
secure_session.host = "www.jmjatlanta.com";
|
||||||
|
secure_session.port = 4001;
|
||||||
|
secure_session.traffic_type = TCP;
|
||||||
|
|
||||||
|
if (!libp2p_secio_handshake(&secure_session, &rsa_private_key))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
retVal = 1;
|
||||||
|
exit:
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#include "crypto/test_rsa.h"
|
#include "crypto/test_rsa.h"
|
||||||
#include "crypto/test_base58.h"
|
#include "crypto/test_base58.h"
|
||||||
#include "crypto/test_base32.h"
|
#include "crypto/test_base32.h"
|
||||||
|
#include "crypto/test_key.h"
|
||||||
|
#include "test_secio.h"
|
||||||
#include "test_mbedtls.h"
|
#include "test_mbedtls.h"
|
||||||
|
#include "test_multistream.h"
|
||||||
|
|
||||||
const char* names[] = {
|
const char* names[] = {
|
||||||
"test_public_der_to_private_der",
|
"test_public_der_to_private_der",
|
||||||
|
@ -26,7 +27,10 @@ const char* names[] = {
|
||||||
"test_base58_peer_address",
|
"test_base58_peer_address",
|
||||||
//"test_mbedtls_pk_write_key_der",
|
//"test_mbedtls_pk_write_key_der",
|
||||||
//"test_crypto_rsa_sign",
|
//"test_crypto_rsa_sign",
|
||||||
"test_crypto_encoding_base32_encode"
|
"test_crypto_encoding_base32_encode",
|
||||||
|
"test_protobuf_private_key",
|
||||||
|
"test_secio_handshake",
|
||||||
|
"test_multistream_connect"
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*funcs[])(void) = {
|
int (*funcs[])(void) = {
|
||||||
|
@ -48,7 +52,10 @@ int (*funcs[])(void) = {
|
||||||
test_base58_peer_address,
|
test_base58_peer_address,
|
||||||
//test_mbedtls_pk_write_key_der,
|
//test_mbedtls_pk_write_key_der,
|
||||||
//test_crypto_rsa_sign,
|
//test_crypto_rsa_sign,
|
||||||
test_crypto_encoding_base32_encode
|
test_crypto_encoding_base32_encode,
|
||||||
|
test_protobuf_private_key,
|
||||||
|
test_secio_handshake,
|
||||||
|
test_multistream_connect
|
||||||
};
|
};
|
||||||
|
|
||||||
int testit(const char* name, int (*func)(void)) {
|
int testit(const char* name, int (*func)(void)) {
|
||||||
|
@ -98,8 +105,8 @@ int main(int argc, char** argv) {
|
||||||
if (tests_ran == 0)
|
if (tests_ran == 0)
|
||||||
printf("***** No tests found *****\n");
|
printf("***** No tests found *****\n");
|
||||||
else {
|
else {
|
||||||
if (counter > 0) {
|
if (tests_ran - counter > 0) {
|
||||||
printf("***** There were %d failed test(s) *****\n", counter);
|
printf("***** There were %d failed test(s) (%d successful) *****\n", tests_ran - counter, counter);
|
||||||
} else {
|
} else {
|
||||||
printf("All %d tests passed\n", tests_ran);
|
printf("All %d tests passed\n", tests_ran);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue