From cd27026cb5cd7691e210cb5865bf63a0f5635940 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 20 Feb 2017 07:08:53 -0500 Subject: [PATCH] Fixed bugs around record protobuf --- crypto/rsa.c | 1 + record/record.c | 19 ++++--- test/test_record.h | 131 +++++++++++++++++++++++++++++++++++++++++++++ test/testit.c | 9 +++- 4 files changed, 150 insertions(+), 10 deletions(-) create mode 100644 test/test_record.h diff --git a/crypto/rsa.c b/crypto/rsa.c index c912d38..1f3fb67 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -357,6 +357,7 @@ int libp2p_crypto_rsa_verify(struct RsaPublicKey* public_key, const unsigned cha output, signature); // the actual signature to compare mbedtls_ctr_drbg_free(&ctr_drbg); + mbedtls_pk_free(&public_context); return retVal == 0; } diff --git a/record/record.c b/record/record.c index 1296d16..f6dc7cb 100644 --- a/record/record.c +++ b/record/record.c @@ -123,33 +123,34 @@ int libp2p_record_protobuf_decode(const unsigned char* in, size_t in_size, struc size_t bytes_read = 0; int field_no; enum WireType field_type; - if (protobuf_decode_field_and_type(&in[pos], in_size, &field_no, &field_type, &bytes_read) == 0) { + if (!protobuf_decode_field_and_type(&in[pos], in_size, &field_no, &field_type, &bytes_read)) { goto exit; } pos += bytes_read; switch(field_no) { case (1): // key - if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->key),&((*out)->key_size), &bytes_read) == 0) + if (!protobuf_decode_string(&in[pos], in_size - pos, (char**)&((*out)->key), &bytes_read)) goto exit; + (*out)->key_size = strlen((*out)->key); pos += bytes_read; break; case (2): // value - if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->value), &((*out)->value_size), &bytes_read) == 0) + if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->value), &((*out)->value_size), &bytes_read)) goto exit; pos += bytes_read; break; case (3): // author - if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->author), &((*out)->author_size), &bytes_read) == 0) + if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->author), &((*out)->author_size), &bytes_read)) goto exit; pos += bytes_read; break; case (4): // signature - if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->signature), &((*out)->signature_size), &bytes_read) == 0) + if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->signature), &((*out)->signature_size), &bytes_read)) goto exit; pos += bytes_read; break; case (5): // time - if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->time_received), &((*out)->time_received_size), &bytes_read) == 0) + if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->time_received), &((*out)->time_received_size), &bytes_read)) goto exit; pos += bytes_read; break; @@ -219,8 +220,8 @@ int libp2p_record_make_put_record (char** record_buf, size_t *rec_size, const st size_t sign_length = 0; if (!libp2p_crypto_rsa_sign ((struct RsaPrivateKey*)sk, bytes, bytes_size, &sign_buf, &sign_length)) goto exit; - record.signature = bytes; - record.signature_size = bytes_size; + record.signature = sign_buf; + record.signature_size = sign_length; } // now protobuf the struct @@ -232,6 +233,8 @@ int libp2p_record_make_put_record (char** record_buf, size_t *rec_size, const st if (!libp2p_record_protobuf_encode(&record, *record_buf, protobuf_size, &protobuf_size)) goto exit; + *rec_size = protobuf_size; + // we're done here. Cleanup time. retVal = 0; diff --git a/test/test_record.h b/test/test_record.h new file mode 100644 index 0000000..7e8bf71 --- /dev/null +++ b/test/test_record.h @@ -0,0 +1,131 @@ +#include + +#include "libp2p/record/record.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; +} + +int test_record_protobuf() { + struct Libp2pRecord* record = libp2p_record_new(); + struct Libp2pRecord* results = NULL; + size_t protobuf_size = 0; + char* protobuf = NULL; + int retVal = 0; + + 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"); + + // 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 (strcmp(record->key, results->key) != 0) + goto exit; + if (strcmp(record->value, results->value) != 0) + goto exit; + if (strcmp(record->author, results->author) != 0) + goto exit; + if (strcmp(record->signature, results->signature) != 0) + goto exit; + if (strcmp(record->time_received, results->time_received) != 0) + 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; + + 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, record_value, record_value_length, 1) != 0) + goto exit; + + // unprotobuf and test + if (!libp2p_record_protobuf_decode(protobuf, protobuf_size, &results)) + goto exit; + + if (strcmp(record_key, results->key) != 0) + goto exit; + if (strncmp(record_value, 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], 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, 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; +} diff --git a/test/testit.c b/test/testit.c index 3840d52..59505c8 100644 --- a/test/testit.c +++ b/test/testit.c @@ -9,6 +9,7 @@ #include "test_mbedtls.h" #include "test_multistream.h" #include "test_conn.h" +#include "test_record.h" const char* names[] = { "test_public_der_to_private_der", @@ -37,7 +38,9 @@ const char* names[] = { "test_multistream_get_list", "test_ephemeral_key_generate", "test_dialer_new", - "test_dialer_dial" + "test_dialer_dial", + "test_record_protobuf", + "test_record_make_put_record" }; int (*funcs[])(void) = { @@ -67,7 +70,9 @@ int (*funcs[])(void) = { test_multistream_get_list, test_ephemeral_key_generate, test_dialer_new, - test_dialer_dial + test_dialer_dial, + test_record_protobuf, + test_record_make_put_record }; int testit(const char* name, int (*func)(void)) {