From 3b301f823ad3993d25d92fdd3905bdb9b2409487 Mon Sep 17 00:00:00 2001 From: Jose Marcial Vieira Bisneto Date: Thu, 19 Jan 2017 20:45:24 -0300 Subject: [PATCH 1/4] Initial implementation of record/record --- Makefile | 4 ++- include/libp2p/record/record.h | 7 ++++ record/Makefile | 14 ++++++++ record/record.c | 58 ++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 include/libp2p/record/record.h create mode 100644 record/Makefile create mode 100644 record/record.c diff --git a/Makefile b/Makefile index 2373033..87b5aad 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,14 @@ DEBUG = true export DEBUG -OBJS = crypto/*.o crypto/encoding/*.o thirdparty/mbedtls/*.o hashmap/hashmap.o +OBJS = crypto/*.o crypto/encoding/*.o thirdparty/mbedtls/*.o hashmap/hashmap.o record/*.o compile: cd crypto; make all; cd thirdparty; make all; cd hashmap; make all; + cd record; make all; ar rcs libp2p.a $(OBJS) test: compile @@ -21,5 +22,6 @@ clean: cd hashmap; make clean; cd thirdparty; make clean cd test; make clean; + cd record; make clean; rm -rf libp2p.a diff --git a/include/libp2p/record/record.h b/include/libp2p/record/record.h new file mode 100644 index 0000000..0a36b85 --- /dev/null +++ b/include/libp2p/record/record.h @@ -0,0 +1,7 @@ +#ifndef LIBP2P_RECORD_H + #define LIBP2P_RECORD_H + + #define RECORD_BUFSIZE 1024 + + int libp2p_record_make_put_record (char* record, struct RsaPrivateKey* sk, char* key, char* value, size_t vlen, int sign); +#endif // LIBP2P_RECORD_H diff --git a/record/Makefile b/record/Makefile new file mode 100644 index 0000000..f72c847 --- /dev/null +++ b/record/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -g3 +LFLAGS = +DEPS = +OBJS = record.o + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + + +all: $(OBJS) + +clean: + rm -f $(OBJS) diff --git a/record/record.c b/record/record.c new file mode 100644 index 0000000..1d81bac --- /dev/null +++ b/record/record.c @@ -0,0 +1,58 @@ +#include +#include + +#include "libp2p/crypto/rsa.h" +#include "libp2p/record/record.h" +#include "protobuf.h" +#include "mh/hashes.h" +#include "mh/multihash.h" + +// libp2p_record_make_put_record creates and signs a dht record for the given key/value pair +int libp2p_record_make_put_record (char* record, struct RsaPrivateKey* sk, char* key, char* value, size_t vlen, int sign) +{ + char *pkh; + int pkh_len; + size_t len = 0, l; + + record = malloc(RECORD_BUFSIZE); + + if (record) { + memset (record, '\0', len); + if (!protobuf_encode_string (1, WIRETYPE_LENGTH_DELIMITED, key, record, RECORD_BUFSIZE, &l)) { + free (record); + return -1; + } + len += l; + if (!protobuf_encode_length_delimited (2, WIRETYPE_LENGTH_DELIMITED, value, vlen, record+len, RECORD_BUFSIZE-len, &l)) { + free (record); + return -1; + } + len += l; + pkh_len = mh_new_length(MH_H_SHA2_256, sk->public_key_length); + pkh = malloc(pkh_len); + if (!pkh) { + free (record); + return -1; + } + if (mh_new(pkh, MH_H_SHA2_256, sk->public_key_der, sk->public_key_length)) { + free (pkh); + free (record); + return -1; + } + if (!protobuf_encode_length_delimited (3, WIRETYPE_LENGTH_DELIMITED, pkh, pkh_len, record+len, RECORD_BUFSIZE-len, &l)) { + free (pkh); + free (record); + return -1; + } + len += l; + if (sign) { + //TODO: missing signature function at libp2p-crypto ? + //sign(sk, signature, record, len); + //proto encode signature. + free (pkh); + free (record); + return -1; // not implemented. + } + } + return 0; // sucess. +} From e3fc5f640953ef23eb28ccffd086c05e2e7947c2 Mon Sep 17 00:00:00 2001 From: Jose Marcial Vieira Bisneto Date: Thu, 19 Jan 2017 21:31:46 -0300 Subject: [PATCH 2/4] Fixed record pointer, should be pointer of pointer so can return allocated memory. --- include/libp2p/record/record.h | 2 +- record/record.c | 39 +++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/libp2p/record/record.h b/include/libp2p/record/record.h index 0a36b85..b29003f 100644 --- a/include/libp2p/record/record.h +++ b/include/libp2p/record/record.h @@ -3,5 +3,5 @@ #define RECORD_BUFSIZE 1024 - int libp2p_record_make_put_record (char* record, struct RsaPrivateKey* sk, char* key, char* value, size_t vlen, int sign); + int libp2p_record_make_put_record (char** record, size_t *rec_size, struct RsaPrivateKey* sk, char* key, char* value, size_t vlen, int sign); #endif // LIBP2P_RECORD_H diff --git a/record/record.c b/record/record.c index 1d81bac..3cd8af2 100644 --- a/record/record.c +++ b/record/record.c @@ -8,51 +8,60 @@ #include "mh/multihash.h" // libp2p_record_make_put_record creates and signs a dht record for the given key/value pair -int libp2p_record_make_put_record (char* record, struct RsaPrivateKey* sk, char* key, char* value, size_t vlen, int sign) +int libp2p_record_make_put_record (char** record, size_t *rec_size, struct RsaPrivateKey* sk, char* key, char* value, size_t vlen, int sign) { - char *pkh; + char *pkh, *p; int pkh_len; size_t len = 0, l; - record = malloc(RECORD_BUFSIZE); + *record = NULL; *rec_size = 0; + p = malloc(RECORD_BUFSIZE); - if (record) { - memset (record, '\0', len); - if (!protobuf_encode_string (1, WIRETYPE_LENGTH_DELIMITED, key, record, RECORD_BUFSIZE, &l)) { - free (record); + if (p) { + memset (p, '\0', len); + if (!protobuf_encode_string (1, WIRETYPE_LENGTH_DELIMITED, key, p, RECORD_BUFSIZE, &l)) { + free (p); return -1; } len += l; - if (!protobuf_encode_length_delimited (2, WIRETYPE_LENGTH_DELIMITED, value, vlen, record+len, RECORD_BUFSIZE-len, &l)) { - free (record); + if (!protobuf_encode_length_delimited (2, WIRETYPE_LENGTH_DELIMITED, value, vlen, p+len, RECORD_BUFSIZE-len, &l)) { + free (p); return -1; } len += l; pkh_len = mh_new_length(MH_H_SHA2_256, sk->public_key_length); pkh = malloc(pkh_len); if (!pkh) { - free (record); + free (p); return -1; } if (mh_new(pkh, MH_H_SHA2_256, sk->public_key_der, sk->public_key_length)) { free (pkh); - free (record); + free (p); return -1; } - if (!protobuf_encode_length_delimited (3, WIRETYPE_LENGTH_DELIMITED, pkh, pkh_len, record+len, RECORD_BUFSIZE-len, &l)) { + if (!protobuf_encode_length_delimited (3, WIRETYPE_LENGTH_DELIMITED, pkh, pkh_len, p+len, RECORD_BUFSIZE-len, &l)) { free (pkh); - free (record); + free (p); return -1; } + free (pkh); len += l; if (sign) { //TODO: missing signature function at libp2p-crypto ? - //sign(sk, signature, record, len); + //sign(sk, signature, p, len); //proto encode signature. free (pkh); - free (record); + free (p); return -1; // not implemented. } } + *record = realloc(p, len); // Reduces memory used for just what is needed. + if (*record) { + *rec_size = len; + } else { + free (p); + return -1; + } return 0; // sucess. } From 9a7c494436c486498a8fc520cbe13f3a361f9e6c Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Fri, 20 Jan 2017 04:49:38 -0500 Subject: [PATCH 3/4] Added method to rsa sign a message, using pkcs 1.15 --- crypto/encoding/base16.c | 4 ++-- crypto/encoding/base32.c | 6 +++--- crypto/rsa.c | 30 +++++++++++++++++++++++++++++- include/libp2p/crypto/rsa.h | 10 ++++++++++ test/crypto/test_base58.h | 2 +- test/crypto/test_rsa.h | 6 +++--- 6 files changed, 48 insertions(+), 10 deletions(-) diff --git a/crypto/encoding/base16.c b/crypto/encoding/base16.c index bc9b8b4..17d2dcd 100644 --- a/crypto/encoding/base16.c +++ b/crypto/encoding/base16.c @@ -22,7 +22,7 @@ int libp2p_crypto_encoding_base16_encode(const unsigned char* incoming, size_t i *results_length = 0; for(int i = 0; i < incoming_length; i++) { unsigned char buf[3]; - sprintf(buf, "%02x", incoming[i]); + sprintf((char*)buf, "%02x", incoming[i]); results[i * 2] = buf[0]; results[i * 2 + 1] = buf[1]; *results_length += 2; @@ -56,7 +56,7 @@ int libp2p_crypto_encoding_base16_decode(const unsigned char* incoming, size_t i memset(results, 0, *results_length); - unsigned char* pos = (char*)incoming; + char* pos = (char*)incoming; for(int i = 0; i < incoming_length / 2; i++) { sscanf(pos, "%2hhx", &results[i]); diff --git a/crypto/encoding/base32.c b/crypto/encoding/base32.c index b11a35f..bc8d407 100644 --- a/crypto/encoding/base32.c +++ b/crypto/encoding/base32.c @@ -637,9 +637,9 @@ base32_decode_alloc_ctx (struct base32_decode_context *ctx, int libp2p_crypto_encoding_base32_encode(const unsigned char* incoming, size_t incoming_length, unsigned char* results, size_t* results_length) { memset(results, 0, *results_length); - base32_encode(incoming, incoming_length, results, *results_length); + base32_encode((char*)incoming, incoming_length, (char*)results, *results_length); if (results[ (*results_length) -1] == 0) - *results_length = strlen(results); + *results_length = strlen((char*)results); return 1; } @@ -664,7 +664,7 @@ size_t libp2p_crypto_encoding_base32_encode_size(size_t incoming_length) { */ int libp2p_crypto_encoding_base32_decode(const unsigned char* incoming, size_t incoming_length, unsigned char* results, size_t* results_length) { - int retVal = base32_decode_ctx(NULL, incoming, incoming_length, results, results_length); + int retVal = base32_decode_ctx(NULL, (char*)incoming, incoming_length, (char*)results, results_length); // unknown error if (results == NULL) diff --git a/crypto/rsa.c b/crypto/rsa.c index e2fd9ef..e60bdcd 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -2,6 +2,7 @@ #include #include "libp2p/crypto/rsa.h" +#include "libp2p/crypto/sha256.h" // mbedtls stuff #include "mbedtls/config.h" @@ -187,7 +188,7 @@ int libp2p_crypto_rsa_private_key_fill_public_key(struct RsaPrivateKey* private_ // first build the rsa context mbedtls_pk_context ctx; mbedtls_pk_init(&ctx); - mbedtls_pk_parse_key(&ctx, private_key->der, private_key->der_length, NULL, 0); + mbedtls_pk_parse_key(&ctx, (unsigned char*)private_key->der, private_key->der_length, NULL, 0); // buffer size_t buffer_size = 1600; @@ -227,3 +228,30 @@ int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* private_key) { return 1; } +/** + * sign a message + * @param private_key the private key + * @param message the message to be signed + * @param message_length the length of message + * @param result the resultant signature. Note: should be pre-allocated and be the size of the private key (i.e. 2048) + * @returns true(1) on successs, otherwise false(0) + */ +int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, unsigned char* message, size_t message_length, unsigned char* result) { + unsigned char output[32]; + libp2p_crypto_hashing_sha256(message, message_length, output); + + mbedtls_rsa_context ctx; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V15, 0); + mbedtls_ctr_drbg_init(&ctr_drbg); + int retVal = mbedtls_rsa_rsassa_pkcs1_v15_sign( &ctx, + mbedtls_ctr_drbg_random, + &ctr_drbg, + MBEDTLS_RSA_PRIVATE, + MBEDTLS_MD_SHA256, + 32, + output, + result ); + return retVal == 0; +} + diff --git a/include/libp2p/crypto/rsa.h b/include/libp2p/crypto/rsa.h index 24ae22f..1307f73 100644 --- a/include/libp2p/crypto/rsa.h +++ b/include/libp2p/crypto/rsa.h @@ -45,4 +45,14 @@ int libp2p_crypto_rsa_private_key_fill_public_key(struct RsaPrivateKey* private_ */ int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* private_key); +/** + * sign a message + * @param private_key the private key + * @param message the message to be signed + * @param message_length the length of message + * @param result the resultant signature. Note: should be pre-allocated and be the size of the private key (i.e. 2048) + * @returns true(1) on successs, otherwise false(0) + */ +int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, unsigned char* message, size_t message_length, unsigned char* result); + #endif /* rsa_h */ diff --git a/test/crypto/test_base58.h b/test/crypto/test_base58.h index 9c4f7ab..59a837f 100644 --- a/test/crypto/test_base58.h +++ b/test/crypto/test_base58.h @@ -77,7 +77,7 @@ int test_base58_peer_address() { unsigned char* ptr_to_result = result_buffer; memset(result_buffer, 0, result_buffer_length); // now get the decoded address - int return_value = libp2p_crypto_encoding_base58_decode(x_data, x_data_length, &ptr_to_result, &result_buffer_length); + int return_value = libp2p_crypto_encoding_base58_decode((unsigned char*)x_data, x_data_length, &ptr_to_result, &result_buffer_length); if (return_value == 0) return 0; // add 2 bytes to the front for the varint diff --git a/test/crypto/test_rsa.h b/test/crypto/test_rsa.h index 7c8075a..e8098af 100644 --- a/test/crypto/test_rsa.h +++ b/test/crypto/test_rsa.h @@ -135,7 +135,7 @@ int test_crypto_rsa_public_key_to_peer_id() { memset(decode_base64, 0, decode_base64_size); unsigned char* ptr = decode_base64; - int retVal = libp2p_crypto_encoding_base64_decode(orig_priv_key, strlen(orig_priv_key), ptr, decode_base64_size, &decode_base64_size); + int retVal = libp2p_crypto_encoding_base64_decode((unsigned char*)orig_priv_key, strlen(orig_priv_key), ptr, decode_base64_size, &decode_base64_size); if (retVal == 0) return 0; @@ -158,7 +158,7 @@ int test_crypto_rsa_public_key_to_peer_id() { // 3) grab the public key, hash it, then base58 it unsigned char hashed[32]; - ID_FromPK_non_null_terminated(hashed, private_key.public_key_der, private_key.public_key_length); + ID_FromPK_non_null_terminated((char*)hashed, (unsigned char*)private_key.public_key_der, 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); @@ -170,7 +170,7 @@ int test_crypto_rsa_public_key_to_peer_id() { if (orig_peer_id_size != final_id_size) return 0; - if (strncmp(orig_peer_id, final_id, final_id_size) != 0) + if (strncmp(orig_peer_id, (char*)final_id, final_id_size) != 0) return 0; return 1; From 21f8d4527990e5eb7dbc49666e458f12420ced0b Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Fri, 20 Jan 2017 04:53:55 -0500 Subject: [PATCH 4/4] Small adjustment to clarify a comment --- crypto/rsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/rsa.c b/crypto/rsa.c index e60bdcd..ec5976f 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -233,7 +233,7 @@ int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* private_key) { * @param private_key the private key * @param message the message to be signed * @param message_length the length of message - * @param result the resultant signature. Note: should be pre-allocated and be the size of the private key (i.e. 2048) + * @param result the resultant signature. Note: should be pre-allocated and be the size of the private key (i.e. 2048 bit key can store a sig in 256 bytes) * @returns true(1) on successs, otherwise false(0) */ int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, unsigned char* message, size_t message_length, unsigned char* result) {