From be9f278ebf8a83e378d7aa3af0ce1077a866c19c Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 8 Feb 2017 12:32:41 -0500 Subject: [PATCH] Beginning of testing of handshake --- crypto/rsa.c | 30 +++++++++++++++++++++--------- include/libp2p/crypto/ephemeral.h | 6 ++++++ include/libp2p/crypto/rsa.h | 2 +- net/multistream.c | 16 ++++++++-------- secio/secio.c | 25 +++++++++++++++++++++---- test/test_secio.h | 8 ++++++-- utils/vector.c | 4 ++++ 7 files changed, 67 insertions(+), 24 deletions(-) diff --git a/crypto/rsa.c b/crypto/rsa.c index 93b7c82..d83ea38 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -236,33 +236,45 @@ int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* private_key) { * @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, const unsigned char* message, size_t message_length, unsigned char* result) { - unsigned char output[32]; - libp2p_crypto_hashing_sha256(message, message_length, output); +int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, const char* message, size_t message_length, unsigned char* result) { + unsigned char hash[32]; + mbedtls_pk_context private_context; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + char* pers = "libp2p crypto rsa sign"; + + libp2p_crypto_hashing_sha256(message, message_length, hash); // make a pk_context from the private key - mbedtls_pk_context private_context; mbedtls_pk_init(&private_context); mbedtls_pk_parse_key(&private_context, (unsigned char*)private_key->der, private_key->der_length, NULL, 0); - // gety just the RSA portion of the context + // get just the RSA portion of the context mbedtls_rsa_context* ctx = mbedtls_pk_rsa(private_context); - mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_init(&ctr_drbg); + mbedtls_entropy_init( &entropy ); + + // seed the routines + if( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) != 0 ) + return 0; + + // sign + /* int retVal = mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx, - NULL, //mbedtls_ctr_drbg_random, + mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, 32, output, result ); - //int retVal = mbedtls_rsa_private(&ctx, NULL, NULL, message, result); + */ + int retVal = mbedtls_rsa_private(ctx, mbedtls_ctr_drbg_random, &ctr_drbg, hash, result); // cleanup mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_pk_free(&private_context); + //mbedtls_pk_free(private_context); return retVal == 0; } diff --git a/include/libp2p/crypto/ephemeral.h b/include/libp2p/crypto/ephemeral.h index 19f5b7f..923cd9b 100644 --- a/include/libp2p/crypto/ephemeral.h +++ b/include/libp2p/crypto/ephemeral.h @@ -39,6 +39,12 @@ struct EphemeralPrivateKey { */ int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivateKey** private_key); +/*** + * Remove resources used by generation of ephemeral private key + * @param in the key to destroy + */ +void libp2p_crypto_ephemeral_key_free( struct EphemeralPrivateKey* in); + /** * Routines to help with the StretchedKey struct */ diff --git a/include/libp2p/crypto/rsa.h b/include/libp2p/crypto/rsa.h index 3d0a3fb..ee44cf0 100644 --- a/include/libp2p/crypto/rsa.h +++ b/include/libp2p/crypto/rsa.h @@ -58,7 +58,7 @@ int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* private_key); * @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, const unsigned char* message, size_t message_length, unsigned char* result); +int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, const char* message, size_t message_length, unsigned char* result); int libp2p_crypto_rsa_verify(struct RsaPublicKey* public_key, const unsigned char* message, size_t message_length, const unsigned char* signature); diff --git a/net/multistream.c b/net/multistream.c index 70e15b1..ad90b98 100644 --- a/net/multistream.c +++ b/net/multistream.c @@ -98,14 +98,6 @@ int libp2p_net_multistream_connect(const char* hostname, int port) { if (socket_connect4(socket, ip, port) != 0) goto exit; - // try to receive the protocol id - return_result = libp2p_net_multistream_receive(socket, &results, &results_size); - if (return_result == 0 || results_size < 1) - goto exit; - - if (strstr(results, "multistream") == NULL) { - goto exit; - } // send the multistream handshake char* protocol_buffer = "/multistream/1.0.0\n"; @@ -113,6 +105,14 @@ int libp2p_net_multistream_connect(const char* hostname, int port) { if (num_bytes <= 0) goto exit; + // try to receive the protocol id + return_result = libp2p_net_multistream_receive(socket, &results, &results_size); + if (return_result == 0 || results_size < 1) + goto exit; + + if (strstr(results, "multistream") == NULL) + goto exit; + // we are now in the loop, so we can switch to another protocol (i.e. /secio/1.0.0) retVal = socket; diff --git a/secio/secio.c b/secio/secio.c index 7d46aa4..16d5cfd 100644 --- a/secio/secio.c +++ b/secio/secio.c @@ -190,7 +190,7 @@ int libp2p_secio_verify_signature(struct PublicKey* public_key, const unsigned c return 0; } -int libp2p_secio_sign(struct PrivateKey* private_key, unsigned char* in, size_t in_length, unsigned char** signature, size_t* signature_size) { +int libp2p_secio_sign(struct PrivateKey* private_key, const char* in, size_t in_length, unsigned char** signature, size_t* signature_size) { if (private_key->type == KEYTYPE_RSA) { struct RsaPrivateKey rsa_key; rsa_key.der = (char*)private_key->data; @@ -415,7 +415,15 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat propose_in_bytes = (unsigned char*)strchr((char*)results, '\n'); if (propose_in_bytes == NULL) goto exit; - propose_in_bytes++; + // are we at the end of the buffer? + if (propose_in_bytes - results + 1 >= results_size) { + free(results); + // read some more + bytes_written = libp2p_net_multistream_receive(local_session->socket_descriptor, (char**)&results, &results_size); + propose_in_bytes = results; + } else { + propose_in_bytes++; + } propose_in_size = results_size - (propose_in_bytes - results); if (!libp2p_secio_propose_protobuf_decode(propose_in_bytes, propose_in_size, &propose_in)) @@ -474,7 +482,13 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat // generate EphemeralPubKey struct EphemeralPrivateKey* e_private_key; - libp2p_crypto_ephemeral_keypair_generate(local_session->chosen_curve, &e_private_key); + if (libp2p_crypto_ephemeral_keypair_generate(local_session->chosen_curve, &e_private_key) == 0) + goto exit; + + local_session->ephemeral_public_key = malloc(e_private_key->public_key->bytes_size); + memcpy(local_session->ephemeral_public_key, e_private_key->public_key->bytes, e_private_key->public_key->bytes_size); + local_session->ephemeral_public_key_size = e_private_key->public_key->bytes_size; + libp2p_crypto_ephemeral_key_free(e_private_key); // build buffer to sign char_buffer = libp2p_utils_vector_new(); @@ -490,9 +504,10 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat memcpy(exchange_out->epubkey, local_session->ephemeral_public_key, local_session->ephemeral_public_key_size); exchange_out->epubkey_size = local_session->ephemeral_public_key_size; struct PrivateKey priv; + priv.type = KEYTYPE_RSA; priv.data = (unsigned char*)private_key->der; priv.data_size = private_key->der_length; - libp2p_secio_sign(&priv, char_buffer->buffer, char_buffer->buffer_size, &exchange_out->signature, &exchange_out->signature_size); + libp2p_secio_sign(&priv, (char*)char_buffer->buffer, char_buffer->buffer_size, &exchange_out->signature, &exchange_out->signature_size); libp2p_utils_vector_free(char_buffer); exchange_out_protobuf_size = libp2p_secio_exchange_protobuf_encode_size(exchange_out); @@ -505,6 +520,8 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat // receive Exchange packet bytes_written = libp2p_net_multistream_receive(local_session->socket_descriptor, (char**)&results, &results_size); + if (bytes_written == 0) + goto exit; libp2p_secio_exchange_protobuf_decode(results, results_size, &exchange_in); // parse and verify diff --git a/test/test_secio.h b/test/test_secio.h index 16b0476..309fb01 100644 --- a/test/test_secio.h +++ b/test/test_secio.h @@ -48,11 +48,15 @@ int test_secio_handshake() { secure_session.traffic_type = TCP; // connect to host secure_session.socket_descriptor = libp2p_net_multistream_connect(secure_session.host, secure_session.port); - if (secure_session.socket_descriptor == -1) + if (secure_session.socket_descriptor == -1) { + fprintf(stderr, "test_secio_handshake: Unable to get socket descriptor\n"); goto exit; + } - if (!libp2p_secio_handshake(&secure_session, &rsa_private_key)) + if (!libp2p_secio_handshake(&secure_session, &rsa_private_key)) { + fprintf(stderr, "test_secio_handshake: Unable to do handshake\n"); goto exit; + } retVal = 1; exit: diff --git a/utils/vector.c b/utils/vector.c index 3de22ad..2565221 100644 --- a/utils/vector.c +++ b/utils/vector.c @@ -33,9 +33,13 @@ int libp2p_utils_vector_add(struct Libp2pVector* vector, unsigned char* in_bytes if (in_size > 0) { if (vector->buffer == NULL) { vector->buffer = (unsigned char*)malloc(in_size); + if (vector->buffer == NULL) + return 0; memcpy(vector->buffer, in_bytes, in_size); } else { vector->buffer = (unsigned char*)realloc(vector->buffer, in_size + vector->buffer_size); + if (vector->buffer == NULL) + return 0; memcpy(&vector->buffer[vector->buffer_size], in_bytes, in_size); vector->buffer_size += in_size; }