diff --git a/crypto/rsa.c b/crypto/rsa.c index d642192..4033fe4 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -256,20 +256,36 @@ int libp2p_crypto_rsa_rsa_private_key_free(struct RsaPrivateKey* 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 bit key can store a sig in 256 bytes) - * @returns true(1) on successs, otherwise false(0) + * @returns true(1) on success, otherwise false(0) */ int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, const char* message, size_t message_length, unsigned char* result) { unsigned char hash[32]; + int retVal = 0; + char* pers = "libp2p crypto rsa sign"; mbedtls_pk_context private_context; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; - char* pers = "libp2p crypto rsa sign"; + unsigned char* der = NULL; + int der_allocated = 0; + // hash the incoming message libp2p_crypto_hashing_sha256(message, message_length, hash); + // put a null terminator on the key (if ncessary) + if (private_key->der[private_key->der_length-1] != 0) { + der = (unsigned char*)malloc(private_key->der_length + 1); + if (der == NULL) + goto exit; + der_allocated = 1; + memcpy(der, private_key->der, private_key->der_length); + der[private_key->der_length] = 0; + } else { + der = private_key->der; + } // make a pk_context from the private key mbedtls_pk_init(&private_context); - mbedtls_pk_parse_key(&private_context, (unsigned char*)private_key->der, private_key->der_length, NULL, 0); + if (mbedtls_pk_parse_key(&private_context, der, private_key->der_length, NULL, 0) != 0) + goto exit; // get just the RSA portion of the context mbedtls_rsa_context* ctx = mbedtls_pk_rsa(private_context); @@ -279,7 +295,7 @@ int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, const char* messag // seed the routines if( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) != 0 ) - return 0; + goto exit; // sign @@ -293,11 +309,20 @@ int libp2p_crypto_rsa_sign(struct RsaPrivateKey* private_key, const char* messag output, result ); */ - int retVal = mbedtls_rsa_private(ctx, mbedtls_ctr_drbg_random, &ctr_drbg, hash, result); + retVal = mbedtls_rsa_private(ctx, mbedtls_ctr_drbg_random, &ctr_drbg, hash, result); + if (retVal != 0) { + retVal = 0; + goto exit; + } + retVal = 1; // cleanup + exit: mbedtls_ctr_drbg_free(&ctr_drbg); - //mbedtls_pk_free(private_context); - return retVal == 0; + mbedtls_entropy_free(&entropy); + mbedtls_pk_free(&private_context); + if (der_allocated) + free(der); + return retVal; } /** diff --git a/include/libp2p/secio/exchange.h b/include/libp2p/secio/exchange.h index e79d24e..3661a00 100644 --- a/include/libp2p/secio/exchange.h +++ b/include/libp2p/secio/exchange.h @@ -8,6 +8,7 @@ struct Exchange { }; struct Exchange* libp2p_secio_exchange_new(); +void libp2p_secio_exchange_free(struct Exchange* in); /** * retrieves the approximate size of an encoded version of the passed in struct diff --git a/secio/secio.c b/secio/secio.c index c446be4..01664c6 100644 --- a/secio/secio.c +++ b/secio/secio.c @@ -495,13 +495,17 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat unsigned char order_hash_in[32]; unsigned char order_hash_out[32]; int order; - struct Exchange* exchange_out; + struct Exchange* exchange_in = NULL; + struct Exchange* exchange_out = NULL; unsigned char* exchange_out_protobuf; size_t exchange_out_protobuf_size; - struct Exchange* exchange_in; struct Libp2pVector* char_buffer = NULL; struct StretchedKey* k1 = NULL, *k2 = NULL; + struct PrivateKey priv; + struct PublicKey pub_key; + struct SecureSession remote_session; char* remote_peer_id = NULL; + struct EphemeralPrivateKey* e_private_key = NULL; const unsigned char* protocol = (unsigned char*)"/secio/1.0.0\n"; @@ -529,7 +533,6 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat libp2p_secio_propose_set_property((void**)&propose_out->rand, &propose_out->rand_size, local_session->nonce, 16); // public key - protobuf it and stick it in propose_out - struct PublicKey pub_key; pub_key.type = KEYTYPE_RSA; pub_key.data_size = private_key->public_key_length; pub_key.data = malloc(pub_key.data_size); @@ -600,13 +603,11 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat goto exit; // prepare exchange of encryption parameters - struct SecureSession remote_session; remote_session.chosen_cipher = local_session->chosen_cipher; remote_session.chosen_curve = local_session->chosen_curve; remote_session.chosen_hash = local_session->chosen_hash; // generate EphemeralPubKey - struct EphemeralPrivateKey* e_private_key; if (libp2p_crypto_ephemeral_keypair_generate(local_session->chosen_curve, &e_private_key) == 0) goto exit; @@ -614,6 +615,7 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat 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); + e_private_key = NULL; // build buffer to sign char_buffer = libp2p_utils_vector_new(); @@ -628,7 +630,7 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat exchange_out->epubkey = (unsigned char*)malloc(local_session->ephemeral_public_key_size); 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; @@ -641,6 +643,8 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat if (exchange_out_protobuf == NULL) goto exit; libp2p_secio_exchange_protobuf_encode(exchange_out, exchange_out_protobuf, exchange_out_protobuf_size, &bytes_written); + libp2p_secio_exchange_free(exchange_out); + exchange_out = NULL; bytes_written = libp2p_secio_write(local_session, exchange_out_protobuf, exchange_out_protobuf_size); free(exchange_out_protobuf); @@ -707,6 +711,10 @@ int libp2p_secio_handshake(struct SecureSession* local_session, struct RsaPrivat libp2p_crypto_public_key_free(public_key); if (remote_peer_id != NULL) free(remote_peer_id); + if (exchange_out != NULL) + libp2p_secio_exchange_free(exchange_out); + if (e_private_key != NULL) + libp2p_crypto_ephemeral_key_free(e_private_key); libp2p_secio_propose_free(propose_out); libp2p_secio_propose_free(propose_in);