Incremental commit for secio fixes and connecting to swarms

yamux
John Jones 2017-07-13 07:27:10 -05:00
parent e32837031f
commit cff0e4d6aa
5 changed files with 234 additions and 54 deletions

View File

@ -29,6 +29,11 @@ struct SessionContext {
size_t shared_key_size;
unsigned char* mac;
size_t mac_size;
// the following items carry state for the sha256 stream cipher.
size_t aes_encode_nonce_offset;
unsigned char aes_encode_stream_block[16];
size_t aes_decode_nonce_offset;
unsigned char aes_decode_stream_block[16];
/**
* The mac function to use
* @param 1 the incoming data bytes
@ -38,11 +43,11 @@ struct SessionContext {
*/
int (*mac_function)(const unsigned char*, size_t, unsigned char*);
// local only stuff
char local_nonce[16];
unsigned char local_nonce[16];
struct EphemeralPrivateKey* ephemeral_private_key;
struct StretchedKey* local_stretched_key;
// remote stuff
char remote_nonce[16];
unsigned char remote_nonce[16];
struct PublicKey remote_key;
char* remote_peer_id;
struct StretchedKey* remote_stretched_key;

View File

@ -22,6 +22,7 @@
#include "mbedtls/md.h"
#include "mbedtls/cipher.h"
#include "mbedtls/md_internal.h"
#include "mbedtls/aes.h"
const char* SupportedExchanges = "P-256,P-384,P-521";
const char* SupportedCiphers = "AES-256,AES-128,Blowfish";
@ -55,7 +56,7 @@ void libp2p_secio_secure_session_free(struct SessionContext* in) {
* @param length the length of the nonce
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_secio_generate_nonce(char* results, int length) {
int libp2p_secio_generate_nonce(unsigned char* results, int length) {
FILE* fd = fopen("/dev/urandom", "r");
fread(results, 1, length, fd);
fclose(fd);
@ -86,7 +87,7 @@ int libp2p_secio_hash(unsigned char* key, size_t key_size, unsigned char* nonce,
* @param length the length of a and b
* @returns a -1, 0, or 1
*/
int libp2p_secio_bytes_compare(const char* a, const char* b, int length) {
int libp2p_secio_bytes_compare(const unsigned char* a, const unsigned char* b, int length) {
for(int i = 0; i < length; i++) {
if (b[i] > a[i])
return -1;
@ -96,6 +97,20 @@ int libp2p_secio_bytes_compare(const char* a, const char* b, int length) {
return 0;
}
/***
* Using values in the Propose struct, determine the order that will be used for the MACs
* @param remote the struct from the remote side
* @param local the struct from this side
* @returns -1 or 1 that will be used to determine who is first
*/
int libp2p_secio_determine_order(struct Propose*remote, struct Propose* local) {
unsigned char hash1[32];
unsigned char hash2[32];
libp2p_secio_hash(remote->public_key, remote->public_key_size, local->rand, local->rand_size, hash1);
libp2p_secio_hash(local->public_key, local->public_key_size, remote->rand, remote->rand_size, hash2);
return libp2p_secio_bytes_compare(hash1, hash2, 32);
}
int libp2p_secio_string_allocate(char* in, char** out) {
*out = (char*)malloc(strlen(in) + 1);
strcpy(*out, in);
@ -518,6 +533,19 @@ int libp2p_secio_unencrypted_read(struct SessionContext* session, unsigned char*
return buffer_size;
}
/**
* Initialize state for the sha256 stream cipher
* @param session the SessionContext struct that contains the variables to initialize
* @returns 1
*/
int libp2p_secio_initialize_crypto(struct SessionContext* session) {
session->aes_decode_nonce_offset = 0;
session->aes_encode_nonce_offset = 0;
memset(session->aes_decode_stream_block, 0, 16);
memset(session->aes_encode_stream_block, 0, 16);
return 1;
}
/**
* Encrypt data before being sent out an insecure stream
* @param session the session information
@ -527,24 +555,33 @@ int libp2p_secio_unencrypted_read(struct SessionContext* session, unsigned char*
* @param outgoing_size the amount of memory allocated
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_secio_encrypt(const struct SessionContext* session, const unsigned char* incoming, size_t incoming_size, unsigned char** outgoing, size_t* outgoing_size) {
int libp2p_secio_encrypt(struct SessionContext* session, const unsigned char* incoming, size_t incoming_size, unsigned char** outgoing, size_t* outgoing_size) {
unsigned char* buffer = NULL;
size_t buffer_size = 0, original_buffer_size = 0;
//TODO switch between ciphers
mbedtls_cipher_context_t cipher_ctx;
mbedtls_cipher_init(&cipher_ctx);
mbedtls_cipher_setup(&cipher_ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CTR));
mbedtls_cipher_setkey(&cipher_ctx, session->local_stretched_key->cipher_key, session->local_stretched_key->cipher_size * 8, MBEDTLS_ENCRYPT);
mbedtls_aes_context cipher_ctx;
mbedtls_aes_init(&cipher_ctx);
if (mbedtls_aes_setkey_enc(&cipher_ctx, session->local_stretched_key->cipher_key, session->local_stretched_key->cipher_size * 8)) {
fprintf(stderr, "Unable to set key for cipher\n");
return 0;
}
original_buffer_size = incoming_size;
original_buffer_size += 32;
buffer_size = original_buffer_size;
buffer = malloc(original_buffer_size);
memset(buffer, 0, original_buffer_size);
mbedtls_cipher_crypt(&cipher_ctx, session->local_stretched_key->iv, session->local_stretched_key->iv_size, incoming, incoming_size, buffer, &buffer_size);
if (mbedtls_aes_crypt_ctr(&cipher_ctx, incoming_size, &session->aes_encode_nonce_offset, session->local_stretched_key->iv, session->aes_encode_stream_block, incoming, buffer)) {
fprintf(stderr, "Unable to update cipher\n");
return 0;
}
buffer_size = incoming_size;
// Now, buffer size may be set differently than original_buffer_size
// The "incoming" is now encrypted, and is in the first part of the buffer
mbedtls_cipher_free(&cipher_ctx);
mbedtls_aes_free(&cipher_ctx);
// mac the data
mbedtls_md_context_t ctx;
@ -593,11 +630,10 @@ int libp2p_secio_encrypted_write(void* stream_context, const unsigned char* byte
* @param outgoing_size the amount of memory allocated for the results
* @returns number of unencrypted bytes
*/
int libp2p_secio_decrypt(const struct SessionContext* session, const unsigned char* incoming, size_t incoming_size, unsigned char** outgoing, size_t* outgoing_size) {
int libp2p_secio_decrypt(struct SessionContext* session, const unsigned char* incoming, size_t incoming_size, unsigned char** outgoing, size_t* outgoing_size) {
size_t data_section_size = incoming_size - 32;
*outgoing_size = 0;
unsigned char* buffer;
size_t buffer_size;
// verify MAC
//TODO make this more generic to use more than SHA256
@ -610,23 +646,33 @@ int libp2p_secio_decrypt(const struct SessionContext* session, const unsigned ch
mbedtls_md_free(&ctx);
// 2. check the mac to see if it is the same
int retVal = memcmp(&incoming[data_section_size], generated_mac, 32);
// TODO: This MAC verification is failing.
if (retVal != 0)
if (retVal != 0) {
// MAC verification failed
libp2p_logger_error("secio", "libp2p_secio_decrypt: MAC verification failed");
return 0;
}
mbedtls_cipher_context_t cipher_ctx;
mbedtls_cipher_init(&cipher_ctx);
mbedtls_cipher_setup(&cipher_ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CTR));
mbedtls_cipher_setkey(&cipher_ctx, session->remote_stretched_key->cipher_key, session->remote_stretched_key->cipher_size * 8, MBEDTLS_DECRYPT);
mbedtls_cipher_set_iv(&cipher_ctx, session->remote_stretched_key->iv, session->remote_stretched_key->iv_size);
buffer_size = data_section_size + mbedtls_cipher_get_block_size(&cipher_ctx);
buffer = malloc(buffer_size);
mbedtls_cipher_update(&cipher_ctx, incoming, data_section_size, buffer, &buffer_size);
mbedtls_cipher_free(&cipher_ctx);
*outgoing = malloc(buffer_size);
*outgoing_size = buffer_size;
memcpy(*outgoing, buffer, buffer_size);
// The MAC checks out. Now decipher the data section
mbedtls_aes_context cipher_ctx;
mbedtls_aes_init(&cipher_ctx);
if (mbedtls_aes_setkey_enc(&cipher_ctx, session->remote_stretched_key->cipher_key, session->remote_stretched_key->cipher_size * 8)) {
fprintf(stderr, "Unable to set key for cipher\n");
return 0;
}
buffer = malloc(data_section_size);
if (mbedtls_aes_crypt_ctr(&cipher_ctx, data_section_size, &session->aes_decode_nonce_offset, session->remote_stretched_key->iv, session->aes_decode_stream_block, incoming, buffer)) {
fprintf(stderr, "Unable to update cipher\n");
return 0;
}
mbedtls_aes_free(&cipher_ctx);
*outgoing = malloc(data_section_size);
*outgoing_size = data_section_size;
memcpy(*outgoing, buffer, data_section_size);
free(buffer);
return *outgoing_size;
}
@ -673,8 +719,6 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
struct Propose* propose_out = NULL;
struct Propose* propose_in = NULL;
struct PublicKey* public_key = NULL;
unsigned char order_hash_in[32] = {0};
unsigned char order_hash_out[32] = {0};
int order = 0;;
struct Exchange* exchange_in = NULL;
struct Exchange* exchange_out = NULL;
@ -696,7 +740,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
memcpy(total, protocol, protocol_len);
memcpy(&total[protocol_len], propose_out_bytes, propose_out_size);
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing protocol");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing protocol\n");
bytes_written = libp2p_net_multistream_write(local_session, total, protocol_len + propose_out_size);
free(total);
if (bytes_written <= 0)
@ -704,7 +748,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
if (!remote_requested) {
// we should get back the secio confirmation
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Reading protocol response");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Reading protocol response\n");
bytes_written = libp2p_net_multistream_read(local_session, &results, &results_size, 20);
if (bytes_written < 5 || strstr((char*)results, "secio") == NULL)
goto exit;
@ -760,13 +804,13 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
goto exit;
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing propose_out");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing propose_out\n");
bytes_written = libp2p_secio_unencrypted_write(local_session, propose_out_bytes, propose_out_size);
if (bytes_written < propose_out_size)
goto exit;
// now receive the proposal from the new connection
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "receiving propose_in");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "receiving propose_in\n");
bytes_written = libp2p_secio_unencrypted_read(local_session, &propose_in_bytes, &propose_in_size, 10);
if (bytes_written <= 0)
goto exit;
@ -786,9 +830,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
// negotiate encryption parameters NOTE: SelectBest must match, otherwise this won't work
// first determine order
libp2p_secio_hash(propose_in->public_key, propose_in->public_key_size, propose_out->rand, propose_out->rand_size, order_hash_in);
libp2p_secio_hash(propose_out->public_key, propose_out->public_key_size, propose_in->rand, propose_in->rand_size, order_hash_out);
order = libp2p_secio_bytes_compare((char*)order_hash_in, (char*)order_hash_out, 32);
order = libp2p_secio_determine_order(propose_in, propose_out);
// curve
if (libp2p_secio_select_best(order, propose_out->exchanges, propose_out->exchanges_size, propose_in->exchanges, propose_in->exchanges_size, &local_session->chosen_curve) == 0)
goto exit;
@ -840,7 +882,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
libp2p_secio_exchange_protobuf_encode(exchange_out, exchange_out_protobuf, exchange_out_protobuf_size, &bytes_written);
exchange_out_protobuf_size = bytes_written;
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing exchange_out");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing exchange_out\n");
bytes_written = libp2p_secio_unencrypted_write(local_session, exchange_out_protobuf, exchange_out_protobuf_size);
if (exchange_out_protobuf_size != bytes_written)
goto exit;
@ -849,7 +891,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
// end of send Exchange packet
// receive Exchange packet
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Reading exchagne packet");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Reading exchange packet\n");
bytes_written = libp2p_secio_unencrypted_read(local_session, &results, &results_size, 10);
if (bytes_written == 0)
goto exit;
@ -911,24 +953,38 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
libp2p_secio_make_mac_and_cipher(local_session, local_session->local_stretched_key);
libp2p_secio_make_mac_and_cipher(local_session, local_session->remote_stretched_key);
// now we actually start encrypting things...
libp2p_secio_initialize_crypto(local_session);
// send expected message (their nonce) to verify encryption works
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Sending their nonce");
if (libp2p_secio_encrypted_write(local_session, (unsigned char*)local_session->remote_nonce, 16) <= 0)
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Sending their nonce\n");
if (libp2p_secio_encrypted_write(local_session, (unsigned char*)local_session->remote_nonce, 16) <= 0) {
libp2p_logger_error("secio", "Encrytped write returned 0 or less.\n");
goto exit;
}
// receive our nonce to verify encryption works
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Receiving our nonce");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Receiving our nonce\n");
int bytes_read = libp2p_secio_encrypted_read(local_session, &results, &results_size, 10);
if (bytes_read <= 0) {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Encrypted read returned %d", bytes_read);
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Encrypted read returned %d\n", bytes_read);
goto exit;
}
if (results_size != 16) {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Results_size should be 16 but was %d", results_size);
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Results_size should be 16 but was %d\n", results_size);
goto exit;
}
if (libp2p_secio_bytes_compare((char*)results, local_session->local_nonce, 16) != 0) {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Bytes of nonce did not match");
if (libp2p_secio_bytes_compare(results, (unsigned char*)local_session->local_nonce, 16) != 0) {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Bytes of nonce did not match\n");
// Debug JMJ
fprintf(stderr, "Expected: ");
for(int i = 0; i < 16; i++)
fprintf(stderr, "%03d ", local_session->local_nonce[i]);
fprintf(stderr, "\nActual : ");
for(int i = 0; i < 16; i++)
fprintf(stderr, "%03d ", results[i]);
fprintf(stderr, "\n");
goto exit;
}
@ -941,7 +997,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
retVal = 1;
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake complete");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake complete\n");
exit:
if (propose_in_bytes != NULL)
@ -967,9 +1023,9 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
libp2p_secio_propose_free(propose_in);
if (retVal == 1) {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake success!");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake success!\n");
} else {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake returning false");
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake returning false\n");
}
return retVal;
}

View File

@ -35,7 +35,7 @@ int test_multistream_get_list() {
char* filtered = NULL;
struct SessionContext session;
session.insecure_stream = libp2p_net_multistream_connect("104.131.131.82", 4001);
session.insecure_stream = libp2p_net_multistream_connect("10.211.55.2", 4001);
if (*((int*)session.insecure_stream->socket_descriptor) < 0)
goto exit;

View File

@ -6,14 +6,38 @@
#include "libp2p/net/p2pnet.h"
#include "libp2p/utils/logger.h"
#include "mbedtls/md.h"
#include "mbedtls/cipher.h"
#include "mbedtls/md_internal.h"
#include "mbedtls/aes.h"
void print_stretched_key(struct StretchedKey* key) {
fprintf(stdout, "cipher key: ");
for(int i = 0; i < key->cipher_size; i++) {
fprintf(stdout, "%d ", key->cipher_key[i]);
}
fprintf(stdout, "\nIV: ");
for(int i = 0; i < key->iv_size; i++) {
fprintf(stdout, "%d ", key->iv[i]);
}
fprintf(stdout, "\nMAC: ");
for(int i = 0; i < key->mac_size; i++) {
fprintf(stdout, "%d ", key->mac_key[i]);
}
}
int test_secio_handshake() {
libp2p_logger_add_class("secio");
int retVal = 0;
size_t decode_base64_size = 0;
unsigned char* decode_base64 = NULL;
// 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 = "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 = "QmZigcoDKaAafGSwot2tchJarCafxKapoRmnYTrZ69ckjb";
char* orig_priv_key = "CAASqQkwggSlAgEAAoIBAQCuW+8vGUb2n4xOcfPZLmfVAy6GNJ0sYrD/hVXwxBU1aBas+8lfAuLwYJXPCVBg65wZWYEbbWCevLFjwB/oZyJA1J1g+HohggH8QvuDH164FtSbgyHFip2SPR7oUHgSWRqfKXRJsVW/SPCfEt59S8JH99Q747dU9fvZKpelE9aDLf5yI8nj29TDy3c1RpkxfUwfgnbeoCwsDnakFmVdoSEp3Lnt3JlI05qE0bgvkWAaelcXSNQCmZzDwXeMk9y221FnBkL4Vs3v2lKmjLx+Qr37P/t78T+VxsjnGHPhbZTIMIjwwON6568d0j25Bj9v6biiz8iXzBR4Fmz1CQ0mqU5BAgMBAAECggEAc6EYX/29Z/SrEaLUeiUiSsuPYQUnbrYMd4gvVDpVblOXJiTciJvbcFo9P04H9h6KKO2Ih23j86FjaqmQ/4jV2HSn4hUmuW4EbwzkyzJUmHTbjj5KeTzR/pd2Fc63skNROlg9fFmUagSvPm8/CYziTOP35bfAbyGqYXyzkJA1ZExVVSOi1zGVi+lnlI1fU2Aki5F7W7F/d2AQWsh7NXUwT7e6JP7TL+Gn4bWdn3NvluwAWTMgp6/It8OU1XPgu8OhdpZQWsMBqJwr79KGLbq2SZZXAw8O+ay1JQYmmmvYzwhdDgJwl+MOtf3NiqQWFzZP8RnlHGNcXlLHHPW0FB9H+QKBgQDirtBOqjCtND6m4hEfy6A24GcITYUBg1+AYQ7uM5uZl5u9AyxfG4bPxyrspz3yS0DOV4HNQ88iwmUE8+8ZHCLSY/YIp73Nk4m8t2s46CuI7Y5GrwCnh9xTMwaUrNx4IRTWyR3OxjQtUyrXtPR6uJ83FDenXvNi//Mrzp+myxX4wwKBgQDE6L8qiVA6n9k5dyUxxMUKJqynwPcBeC+wI85gr/9wwlRYDrgMYeH6/D5prZ3N5m8+zugVQQJKLfXBG0i8BRh5xLYFCZnV2O3NwvCdENlZJZrNNoz9jM3yRV+c7OdrclxDiN0bjGEBWv8GHutNFAwuUfMe0TMdfFYpM7gBHjEMqwKBgQCWHwOhNSCrdDARwSFqFyZxcUeKvhvZlrFGigCjS9Y+b6MaF+Ho0ogDTnlk5JUnwyKWBGnYEJI7CNZx40JzNKjzAHRN4xjV7mGHc0k1FLzQH9LbiMY8LMOC7gXrrFcNz4rHe8WbzLN9WNjEpfhK1b3Lcj4xP7ab17mpR1t/0HsqlQKBgQC3S6lYIUZLrCz7b0tyTqbU0jd6WQgVmBlcL5iXLH3uKxd0eQ8eh6diiZhXq0PwPQdlQhmMX12QS8QupAVK8Ltd7p05hzxqcmq7VTHCI8MPVxAI4zTPeVjko2tjmqu5u1TjkO2yDTTnnBs1SWbj8zt7itFz6G1ajzltVTV95OrnzQKBgQDEwZxnJA2vDJEDaJ82CiMiUAFzwsoK8hDvz63kOKeEW3/yESySnUbzpxDEjzYNsK74VaXHKCGI40fDRUqZxU/+qCrFf3xDfYS4r4wfFd2Jh+tn4NzSV/EhIr9KR/ZJW+TvGks+pWUJ3mhjPEvNtlt3M64/j2D0RP2aBQtoSpeezQ==";
char* orig_peer_id = "QmRKm1d9kSCRpMFtLYpfhhCQ3DKuSSPJa3qn9wWXfwnWnY";
size_t orig_peer_id_size = strlen(orig_peer_id);
struct RsaPrivateKey* rsa_private_key = NULL;
unsigned char hashed[32] = {0};
@ -44,8 +68,8 @@ int test_secio_handshake() {
if (!libp2p_crypto_rsa_private_key_fill_public_key(rsa_private_key))
goto exit;
secure_session.host = "www.jmjatlanta.com";
//secure_session.host = "127.0.0.1";
//secure_session.host = "www.jmjatlanta.com";
secure_session.host = "10.211.55.2";
secure_session.port = 4001;
secure_session.traffic_type = TCP;
// connect to host
@ -55,12 +79,40 @@ int test_secio_handshake() {
goto exit;
}
if (!libp2p_secio_handshake(&secure_session, rsa_private_key, 0)) {
/*
fprintf(stdout, "Shared key: ");
for(int i = 0; i < secure_session.shared_key_size; i++)
fprintf(stdout, "%d ", secure_session.shared_key[i]);
fprintf(stdout, "\nLocal stretched key: ");
print_stretched_key(secure_session.local_stretched_key);
fprintf(stdout, "\nRemote stretched key: ");
print_stretched_key(secure_session.remote_stretched_key);
fprintf(stdout, "\n");
*/
fprintf(stderr, "test_secio_handshake: Unable to do handshake\n");
goto exit;
}
fprintf(stdout, "Shared key: ");
for(int i = 0; i < secure_session.shared_key_size; i++)
fprintf(stdout, "%d ", secure_session.shared_key[i]);
fprintf(stdout, "\nLocal stretched key: ");
print_stretched_key(secure_session.local_stretched_key);
fprintf(stdout, "\nRemote stretched key: ");
print_stretched_key(secure_session.remote_stretched_key);
fprintf(stdout, "\n");
// now attempt to do something with it...
secure_session.secure_stream->write(&secure_session, "/multistream/1.0.0\n", 3);
unsigned char* results;
size_t results_size;
secure_session.secure_stream->read(&secure_session, &results, &results_size, 10);
fprintf(stdout, "test_secio_handshake: Results from multistream: Size: %lu string: %s", results_size, results);
for(int i = 0; i < results_size; i++)
fprintf(stdout, "%d ", results[i]);
fprintf(stdout, "\n");
retVal = 1;
exit:
if (secure_session.insecure_stream != NULL)
@ -174,3 +226,68 @@ int test_secio_exchange_protobuf_encode() {
libp2p_secio_exchange_free(exch);
return retVal;
}
int test_secio_encrypt_like_go() {
// GO version keys:
// local keys
unsigned char keyIv[] = { 233, 20, 188, 79, 55, 204, 132, 231, 82, 167, 63, 211, 74, 253, 20, 109 };
unsigned char keyMac[] = { 224, 94, 119, 190, 68, 213, 247, 204, 211, 25, 42, 154, 145, 96, 86, 8, 103, 187, 133, 15 };
unsigned char keyCipher[] = { 137, 132, 0, 154, 131, 200, 29, 70, 88, 158, 170, 177, 220, 101, 113, 212, 98, 180, 25, 96, 15, 208, 210, 204, 167, 161, 238, 207, 229, 69, 83, 29 };
// with the above keys, the "nonce" below should give the expected result
unsigned char nonce_string[] = { 253, 17, 36, 85, 95, 130, 6, 14, 184, 204, 131, 114, 143, 245, 74, 51 };
unsigned char expected_nonce[] = { 71, 244, 156, 168, 60, 181, 227, 199, 116, 155, 82, 29, 7, 237, 234, 27 };
int incoming_size = 16;
size_t result_size = 255;
unsigned char result[result_size];
memset(result, 0, result_size);
// do nonce
mbedtls_aes_context cipher_ctx;
mbedtls_aes_init(&cipher_ctx);
if (mbedtls_aes_setkey_enc(&cipher_ctx, keyCipher, 32 * 8)) {
fprintf(stderr, "Unable to set key for cipher\n");
return 0;
}
size_t nonce_offset = 0;
unsigned char stream_block[16];
memset(stream_block, 0, 16);
if (mbedtls_aes_crypt_ctr(&cipher_ctx, incoming_size, &nonce_offset, keyIv, stream_block, nonce_string, result)) {
fprintf(stderr, "Unable to update cipher\n");
return 0;
}
// do comparison
for(int i = 0; i < incoming_size; i++) {
if (result[i] != expected_nonce[i]) {
fprintf(stderr, "Nonce: At position %d expected %u but got %u\n", i, expected_nonce[i], result[i]);
return 0;
}
}
// now try multistream
result_size = 255;
memset(result, 0, result_size);
unsigned char multistream_string[] = { 19, 47, 109, 117, 108, 116, 105, 115, 116, 114, 101, 97, 109, 47, 49, 46, 48, 46, 48, 10 };
unsigned char expected_multistream[] = { 105, 218, 190, 138, 115, 254, 188, 113, 192, 128, 162, 148, 118, 164, 178, 140, 239, 185, 53, 17 };
incoming_size = 20;
if (mbedtls_aes_crypt_ctr(&cipher_ctx, incoming_size, &nonce_offset, keyIv, stream_block, multistream_string, result)) {
fprintf(stderr, "Unable to update cipher\n");
return 0;
}
mbedtls_aes_free(&cipher_ctx);
// do comparison
for(int i = 0; i < incoming_size; i++) {
if (result[i] != expected_multistream[i]) {
fprintf(stderr, "Multistream: At position %d expected %d but got %d\n", i, expected_multistream[i], result[i]);
return 0;
}
}
return 1;
}

View File

@ -41,6 +41,7 @@ const char* names[] = {
"test_secio_handshake",
"test_secio_encrypt_decrypt",
"test_secio_exchange_protobuf_encode",
"test_secio_encrypt_like_go",
"test_multistream_connect",
"test_multistream_get_list",
"test_ephemeral_key_generate",
@ -84,6 +85,7 @@ int (*funcs[])(void) = {
test_secio_handshake,
test_secio_encrypt_decrypt,
test_secio_exchange_protobuf_encode,
test_secio_encrypt_like_go,
test_multistream_connect,
test_multistream_get_list,
test_ephemeral_key_generate,