mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
feat: Add support for custom random number generator.
This can be used by fuzzers to make RNG-driven code deterministic (i.e. based on the fuzzer input).
This commit is contained in:
parent
660e346fce
commit
cc31ff07fa
|
@ -46,15 +46,17 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
|
|||
static void test_basic(void)
|
||||
{
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
Logger *logger = logger_new();
|
||||
logger_callback_log(logger, (logger_cb *)print_debug_log, nullptr, nullptr);
|
||||
|
||||
// Attempt to create a new TCP_Server instance.
|
||||
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
const Network *ns = system_network();
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
|
||||
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS,
|
||||
"Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS);
|
||||
|
@ -81,19 +83,19 @@ static void test_basic(void)
|
|||
uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t f_nonce[CRYPTO_NONCE_SIZE];
|
||||
crypto_new_keypair(f_public_key, f_secret_key);
|
||||
random_nonce(f_nonce);
|
||||
crypto_new_keypair(rng, f_public_key, f_secret_key);
|
||||
random_nonce(rng, f_nonce);
|
||||
|
||||
// Generation of the initial handshake.
|
||||
uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE);
|
||||
ck_assert(handshake_plain != nullptr);
|
||||
crypto_new_keypair(handshake_plain, t_secret_key);
|
||||
crypto_new_keypair(rng, handshake_plain, t_secret_key);
|
||||
memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE);
|
||||
uint8_t *handshake = (uint8_t *)malloc(TCP_CLIENT_HANDSHAKE_SIZE);
|
||||
ck_assert(handshake != nullptr);
|
||||
memcpy(handshake, f_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
// Encrypting handshake
|
||||
int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
|
||||
|
@ -194,7 +196,7 @@ struct sec_TCP_con {
|
|||
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
|
||||
};
|
||||
|
||||
static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time)
|
||||
static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time)
|
||||
{
|
||||
struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con));
|
||||
ck_assert(sec_c != nullptr);
|
||||
|
@ -203,22 +205,22 @@ static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Network *ns,
|
|||
|
||||
IP_Port localhost;
|
||||
localhost.ip = get_loopback();
|
||||
localhost.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
|
||||
bool ok = net_connect(logger, sock, &localhost);
|
||||
ck_assert_msg(ok, "Failed to connect to the test TCP relay server.");
|
||||
|
||||
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(sec_c->public_key, f_secret_key);
|
||||
random_nonce(sec_c->sent_nonce);
|
||||
crypto_new_keypair(rng, sec_c->public_key, f_secret_key);
|
||||
random_nonce(rng, sec_c->sent_nonce);
|
||||
|
||||
uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE];
|
||||
crypto_new_keypair(handshake_plain, t_secret_key);
|
||||
crypto_new_keypair(rng, handshake_plain, t_secret_key);
|
||||
memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, sec_c->sent_nonce, CRYPTO_NONCE_SIZE);
|
||||
uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE];
|
||||
memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
|
||||
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
|
@ -296,19 +298,21 @@ static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, ui
|
|||
static void test_some(void)
|
||||
{
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
Logger *logger = logger_new();
|
||||
const Network *ns = system_network();
|
||||
|
||||
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server");
|
||||
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports.");
|
||||
|
||||
struct sec_TCP_con *con1 = new_TCP_con(logger, ns, tcp_s, mono_time);
|
||||
struct sec_TCP_con *con2 = new_TCP_con(logger, ns, tcp_s, mono_time);
|
||||
struct sec_TCP_con *con3 = new_TCP_con(logger, ns, tcp_s, mono_time);
|
||||
struct sec_TCP_con *con1 = new_TCP_con(logger, rng, ns, tcp_s, mono_time);
|
||||
struct sec_TCP_con *con2 = new_TCP_con(logger, rng, ns, tcp_s, mono_time);
|
||||
struct sec_TCP_con *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time);
|
||||
|
||||
uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE];
|
||||
requ_p[0] = TCP_PACKET_ROUTING_REQUEST;
|
||||
|
@ -484,26 +488,28 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint
|
|||
|
||||
static void test_client(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
Logger *logger = logger_new();
|
||||
|
||||
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
const Network *ns = system_network();
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
|
||||
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports.");
|
||||
|
||||
uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(f_public_key, f_secret_key);
|
||||
crypto_new_keypair(rng, f_public_key, f_secret_key);
|
||||
IP_Port ip_port_tcp_s;
|
||||
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
ip_port_tcp_s.ip = get_loopback();
|
||||
|
||||
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, self_public_key, f_public_key,
|
||||
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key,
|
||||
f_secret_key, nullptr);
|
||||
do_TCP_connection(logger, mono_time, conn, nullptr);
|
||||
c_sleep(50);
|
||||
|
@ -536,9 +542,9 @@ static void test_client(void)
|
|||
|
||||
uint8_t f2_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(f2_public_key, f2_secret_key);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
|
||||
crypto_new_keypair(rng, f2_public_key, f2_secret_key);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
|
||||
f2_secret_key, nullptr);
|
||||
|
||||
// The client should call this function (defined earlier) during the routing process.
|
||||
|
@ -613,22 +619,24 @@ static void test_client(void)
|
|||
// Test how the client handles servers that don't respond.
|
||||
static void test_client_invalid(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
Logger *logger = logger_new();
|
||||
const Network *ns = system_network();
|
||||
|
||||
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
|
||||
uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(f_public_key, f_secret_key);
|
||||
crypto_new_keypair(rng, f_public_key, f_secret_key);
|
||||
IP_Port ip_port_tcp_s;
|
||||
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
ip_port_tcp_s.ip = get_loopback();
|
||||
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s,
|
||||
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s,
|
||||
self_public_key, f_public_key, f_secret_key, nullptr);
|
||||
|
||||
// Run the client's main loop but not the server.
|
||||
|
@ -688,28 +696,30 @@ static void test_tcp_connection(void)
|
|||
{
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
Logger *logger = logger_new();
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
|
||||
tcp_data_callback_called = 0;
|
||||
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
|
||||
|
||||
TCP_Proxy_Info proxy_info;
|
||||
proxy_info.proxy_type = TCP_PROXY_NONE;
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_1 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
|
||||
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
|
||||
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_2 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
|
||||
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
|
||||
|
||||
IP_Port ip_port_tcp_s;
|
||||
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
ip_port_tcp_s.ip = get_loopback();
|
||||
|
||||
int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123);
|
||||
|
@ -717,7 +727,7 @@ static void test_tcp_connection(void)
|
|||
ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0,
|
||||
"Could not add tcp relay to connection\n");
|
||||
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
connection = new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123);
|
||||
ck_assert_msg(connection == 0, "Connection id wrong");
|
||||
ck_assert_msg(add_tcp_relay_connection(tc_2, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0,
|
||||
|
@ -795,6 +805,8 @@ static void test_tcp_connection2(void)
|
|||
{
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
Logger *logger = logger_new();
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
|
||||
tcp_oobdata_callback_called = 0;
|
||||
|
@ -802,23 +814,23 @@ static void test_tcp_connection2(void)
|
|||
|
||||
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
|
||||
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
|
||||
|
||||
TCP_Proxy_Info proxy_info;
|
||||
proxy_info.proxy_type = TCP_PROXY_NONE;
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_1 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
|
||||
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
|
||||
|
||||
crypto_new_keypair(self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_2 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
|
||||
crypto_new_keypair(rng, self_public_key, self_secret_key);
|
||||
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
|
||||
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
|
||||
|
||||
IP_Port ip_port_tcp_s;
|
||||
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
ip_port_tcp_s.ip = get_loopback();
|
||||
|
||||
int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123);
|
||||
|
|
|
@ -165,12 +165,12 @@ static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes)
|
|||
* returns a random index at which a list of booleans is false
|
||||
* (some such index is required to exist)
|
||||
*/
|
||||
static uint32_t random_false_index(bool *list, const uint32_t length)
|
||||
static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
do {
|
||||
index = random_u32() % length;
|
||||
index = random_u32(rng) % length;
|
||||
} while (list[index]);
|
||||
|
||||
return index;
|
||||
|
@ -287,6 +287,8 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations)
|
|||
|
||||
static void run_conference_tests(AutoTox *autotoxes)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
bool disabled[NUM_AV_GROUP_TOX] = {0};
|
||||
|
||||
test_audio(autotoxes, disabled, false);
|
||||
|
@ -302,7 +304,7 @@ static void run_conference_tests(AutoTox *autotoxes)
|
|||
ck_assert(NUM_AV_DISCONNECT < NUM_AV_GROUP_TOX);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_DISCONNECT; ++i) {
|
||||
uint32_t disconnect = random_false_index(disconnected, NUM_AV_GROUP_TOX);
|
||||
uint32_t disconnect = random_false_index(rng, disconnected, NUM_AV_GROUP_TOX);
|
||||
disconnected[disconnect] = true;
|
||||
|
||||
if (i < NUM_AV_DISCONNECT / 2) {
|
||||
|
@ -358,7 +360,7 @@ static void run_conference_tests(AutoTox *autotoxes)
|
|||
ck_assert(NUM_AV_DISABLE < NUM_AV_GROUP_TOX);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) {
|
||||
uint32_t disable = random_false_index(disabled, NUM_AV_GROUP_TOX);
|
||||
uint32_t disable = random_false_index(rng, disabled, NUM_AV_GROUP_TOX);
|
||||
disabled[disable] = true;
|
||||
printf("Disabling #%u\n", autotoxes[disable].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(autotoxes[disable].tox, 0, audio_callback, &autotoxes[disable]) != 0,
|
||||
|
|
|
@ -179,12 +179,12 @@ static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes)
|
|||
* returns a random index at which a list of booleans is false
|
||||
* (some such index is required to exist)
|
||||
*/
|
||||
static uint32_t random_false_index(bool *list, const uint32_t length)
|
||||
static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
do {
|
||||
index = random_u32() % length;
|
||||
index = random_u32(rng) % length;
|
||||
} while (list[index]);
|
||||
|
||||
return index;
|
||||
|
@ -192,6 +192,8 @@ static uint32_t random_false_index(bool *list, const uint32_t length)
|
|||
|
||||
static void run_conference_tests(AutoTox *autotoxes)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
/* disabling name change propagation check for now, as it occasionally
|
||||
* fails due to disconnections too short to trigger freezing */
|
||||
const bool check_name_change_propagation = false;
|
||||
|
@ -215,7 +217,7 @@ static void run_conference_tests(AutoTox *autotoxes)
|
|||
ck_assert(NUM_DISCONNECT < NUM_GROUP_TOX);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_DISCONNECT; ++i) {
|
||||
uint32_t disconnect = random_false_index(disconnected, NUM_GROUP_TOX);
|
||||
uint32_t disconnect = random_false_index(rng, disconnected, NUM_GROUP_TOX);
|
||||
disconnected[disconnect] = true;
|
||||
|
||||
if (i < NUM_DISCONNECT / 2) {
|
||||
|
@ -292,7 +294,7 @@ static void run_conference_tests(AutoTox *autotoxes)
|
|||
Tox_Err_Conference_Send_Message err;
|
||||
ck_assert_msg(
|
||||
tox_conference_send_message(
|
||||
autotoxes[random_u32() % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE,
|
||||
autotoxes[random_u32(rng) % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE,
|
||||
sizeof(GROUP_MESSAGE) - 1, &err) != 0, "failed to send group message");
|
||||
ck_assert_msg(
|
||||
err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, "failed to send group message");
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
#include "../toxcore/net_crypto.h"
|
||||
#include "check_compat.h"
|
||||
|
||||
static void rand_bytes(uint8_t *b, size_t blen)
|
||||
static void rand_bytes(const Random *rng, uint8_t *b, size_t blen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < blen; i++) {
|
||||
b[i] = random_u08();
|
||||
b[i] = random_u08(rng);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,9 @@ static void test_fast_known(void)
|
|||
|
||||
static void test_endtoend(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
// Test 100 random messages and keypairs
|
||||
for (uint8_t testno = 0; testno < 100; testno++) {
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
|
@ -152,13 +155,13 @@ static void test_endtoend(void)
|
|||
uint8_t m4[sizeof(m)];
|
||||
|
||||
//Generate random message (random length from 10 to 50)
|
||||
const uint16_t mlen = (random_u32() % (M_SIZE - 10)) + 10;
|
||||
rand_bytes(m, mlen);
|
||||
rand_bytes(n, CRYPTO_NONCE_SIZE);
|
||||
const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10;
|
||||
rand_bytes(rng, m, mlen);
|
||||
rand_bytes(rng, n, CRYPTO_NONCE_SIZE);
|
||||
|
||||
//Generate keypairs
|
||||
crypto_new_keypair(pk1, sk1);
|
||||
crypto_new_keypair(pk2, sk2);
|
||||
crypto_new_keypair(rng, pk1, sk1);
|
||||
crypto_new_keypair(rng, pk2, sk2);
|
||||
|
||||
//Precompute shared keys
|
||||
encrypt_precompute(pk2, sk1, k1);
|
||||
|
@ -193,6 +196,8 @@ static void test_endtoend(void)
|
|||
|
||||
static void test_large_data(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
uint8_t k[CRYPTO_SHARED_KEY_SIZE];
|
||||
uint8_t n[CRYPTO_NONCE_SIZE];
|
||||
|
||||
|
@ -208,12 +213,12 @@ static void test_large_data(void)
|
|||
ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr);
|
||||
|
||||
//Generate random messages
|
||||
rand_bytes(m1, m1_size);
|
||||
rand_bytes(m2, m2_size);
|
||||
rand_bytes(n, CRYPTO_NONCE_SIZE);
|
||||
rand_bytes(rng, m1, m1_size);
|
||||
rand_bytes(rng, m2, m2_size);
|
||||
rand_bytes(rng, n, CRYPTO_NONCE_SIZE);
|
||||
|
||||
//Generate key
|
||||
rand_bytes(k, CRYPTO_SHARED_KEY_SIZE);
|
||||
rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE);
|
||||
|
||||
const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1);
|
||||
const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2);
|
||||
|
@ -235,6 +240,8 @@ static void test_large_data(void)
|
|||
|
||||
static void test_large_data_symmetric(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE];
|
||||
|
||||
uint8_t n[CRYPTO_NONCE_SIZE];
|
||||
|
@ -247,11 +254,11 @@ static void test_large_data_symmetric(void)
|
|||
ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr);
|
||||
|
||||
//Generate random messages
|
||||
rand_bytes(m1, m1_size);
|
||||
rand_bytes(n, CRYPTO_NONCE_SIZE);
|
||||
rand_bytes(rng, m1, m1_size);
|
||||
rand_bytes(rng, n, CRYPTO_NONCE_SIZE);
|
||||
|
||||
//Generate key
|
||||
new_symmetric_key(k);
|
||||
new_symmetric_key(rng, k);
|
||||
|
||||
const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1);
|
||||
ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data");
|
||||
|
@ -289,12 +296,15 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num)
|
|||
|
||||
static void test_increment_nonce(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
uint32_t i;
|
||||
|
||||
uint8_t n[CRYPTO_NONCE_SIZE];
|
||||
|
||||
for (i = 0; i < CRYPTO_NONCE_SIZE; ++i) {
|
||||
n[i] = random_u08();
|
||||
n[i] = random_u08(rng);
|
||||
}
|
||||
|
||||
uint8_t n1[CRYPTO_NONCE_SIZE];
|
||||
|
@ -308,7 +318,7 @@ static void test_increment_nonce(void)
|
|||
}
|
||||
|
||||
for (i = 0; i < (1 << 18); ++i) {
|
||||
const uint32_t r = random_u32();
|
||||
const uint32_t r = random_u32(rng);
|
||||
increment_nonce_number_cmp(n, r);
|
||||
increment_nonce_number(n1, r);
|
||||
ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce_number function");
|
||||
|
|
|
@ -169,7 +169,9 @@ static void test_keys(void)
|
|||
ck_assert(encrypted2a != nullptr);
|
||||
uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a);
|
||||
ck_assert(in_plaintext2a != nullptr);
|
||||
random_bytes(in_plaintext2a, plaintext_length2a);
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
random_bytes(rng, in_plaintext2a, plaintext_length2a);
|
||||
ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr);
|
||||
ck_assert_msg(ret, "tox_pass_encrypt failure 2a: %d", encerr);
|
||||
|
||||
|
|
|
@ -162,19 +162,12 @@ static void test_ip_equal(void)
|
|||
ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET6, ::1}, {TOX_AF_INET6, ::2} ): expected result 0, got %d.", res);
|
||||
}
|
||||
|
||||
static void network_suite(void)
|
||||
{
|
||||
networking_at_startup();
|
||||
|
||||
test_addr_resolv_localhost();
|
||||
test_ip_equal();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
network_suite();
|
||||
test_addr_resolv_localhost();
|
||||
test_ip_equal();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -169,10 +169,10 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac
|
|||
* Use Onion_Path path to send data of length to dest.
|
||||
* Maximum length of data is ONION_MAX_DATA_SIZE.
|
||||
*/
|
||||
static void send_onion_packet(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
|
||||
static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
const int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
|
||||
const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length);
|
||||
ck_assert_msg(len != -1, "failed to create onion packet");
|
||||
ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet");
|
||||
}
|
||||
|
@ -195,12 +195,14 @@ static void test_basic(void)
|
|||
Logger *log2 = logger_new();
|
||||
logger_callback_log(log2, (logger_cb *)print_debug_log, nullptr, &index[1]);
|
||||
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
Mono_Time *mono_time1 = mono_time_new();
|
||||
Mono_Time *mono_time2 = mono_time_new();
|
||||
|
||||
IP ip = get_loopback();
|
||||
Onion *onion1 = new_onion(log1, mono_time1, new_dht(log1, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false));
|
||||
Onion *onion2 = new_onion(log2, mono_time2, new_dht(log2, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false));
|
||||
Onion *onion1 = new_onion(log1, mono_time1, rng, new_dht(log1, rng, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false));
|
||||
Onion *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, rng, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false));
|
||||
ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing.");
|
||||
networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST_OLD, &handle_test_1, onion2);
|
||||
|
||||
|
@ -225,8 +227,8 @@ static void test_basic(void)
|
|||
nodes[2] = n1;
|
||||
nodes[3] = n2;
|
||||
Onion_Path path;
|
||||
create_onion_path(onion1->dht, &path, nodes);
|
||||
send_onion_packet(onion1->net, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
|
||||
create_onion_path(rng, onion1->dht, &path, nodes);
|
||||
send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
|
||||
|
||||
handled_test_1 = 0;
|
||||
|
||||
|
@ -243,16 +245,16 @@ static void test_basic(void)
|
|||
do_onion(mono_time2, onion2);
|
||||
} while (handled_test_2 == 0);
|
||||
|
||||
Onion_Announce *onion1_a = new_onion_announce(log1, mono_time1, onion1->dht);
|
||||
Onion_Announce *onion2_a = new_onion_announce(log2, mono_time2, onion2->dht);
|
||||
Onion_Announce *onion1_a = new_onion_announce(log1, rng, mono_time1, onion1->dht);
|
||||
Onion_Announce *onion2_a = new_onion_announce(log2, rng, mono_time2, onion2->dht);
|
||||
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3, onion1);
|
||||
ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing.");
|
||||
uint8_t zeroes[64] = {0};
|
||||
random_bytes(sb_data, sizeof(sb_data));
|
||||
random_bytes(rng, sb_data, sizeof(sb_data));
|
||||
uint64_t s;
|
||||
memcpy(&s, sb_data, sizeof(uint64_t));
|
||||
memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
int ret = send_announce_request(onion1->net, &path, &nodes[3],
|
||||
int ret = send_announce_request(onion1->net, rng, &path, &nodes[3],
|
||||
dht_get_self_public_key(onion1->dht),
|
||||
dht_get_self_secret_key(onion1->dht),
|
||||
zeroes,
|
||||
|
@ -267,12 +269,12 @@ static void test_basic(void)
|
|||
c_sleep(50);
|
||||
} while (handled_test_3 == 0);
|
||||
|
||||
random_bytes(sb_data, sizeof(sb_data));
|
||||
random_bytes(rng, sb_data, sizeof(sb_data));
|
||||
memcpy(&s, sb_data, sizeof(uint64_t));
|
||||
memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2));
|
||||
networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
|
||||
send_announce_request(onion1->net, &path, &nodes[3],
|
||||
send_announce_request(onion1->net, rng, &path, &nodes[3],
|
||||
dht_get_self_public_key(onion1->dht),
|
||||
dht_get_self_secret_key(onion1->dht),
|
||||
test_3_ping_id,
|
||||
|
@ -293,11 +295,11 @@ static void test_basic(void)
|
|||
|
||||
Mono_Time *mono_time3 = mono_time_new();
|
||||
|
||||
Onion *onion3 = new_onion(log3, mono_time3, new_dht(log3, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false));
|
||||
Onion *onion3 = new_onion(log3, mono_time3, rng, new_dht(log3, rng, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false));
|
||||
ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
|
||||
|
||||
random_nonce(nonce);
|
||||
ret = send_data_request(onion3->net, &path, &nodes[3].ip_port,
|
||||
random_nonce(rng, nonce);
|
||||
ret = send_data_request(onion3->net, rng, &path, &nodes[3].ip_port,
|
||||
dht_get_self_public_key(onion1->dht),
|
||||
dht_get_self_public_key(onion1->dht),
|
||||
nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo"));
|
||||
|
@ -358,7 +360,7 @@ typedef struct {
|
|||
Onion_Client *onion_c;
|
||||
} Onions;
|
||||
|
||||
static Onions *new_onions(uint16_t port, uint32_t *index)
|
||||
static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index)
|
||||
{
|
||||
IP ip = get_loopback();
|
||||
ip.ip.v6.uint8[15] = 1;
|
||||
|
@ -395,7 +397,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
DHT *dht = new_dht(on->log, ns, on->mono_time, net, true, false);
|
||||
DHT *dht = new_dht(on->log, rng, ns, on->mono_time, net, true, false);
|
||||
|
||||
if (!dht) {
|
||||
kill_networking(net);
|
||||
|
@ -405,7 +407,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
on->onion = new_onion(on->log, on->mono_time, dht);
|
||||
on->onion = new_onion(on->log, on->mono_time, rng, dht);
|
||||
|
||||
if (!on->onion) {
|
||||
kill_dht(dht);
|
||||
|
@ -416,7 +418,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
on->onion_a = new_onion_announce(on->log, on->mono_time, dht);
|
||||
on->onion_a = new_onion_announce(on->log, rng, on->mono_time, dht);
|
||||
|
||||
if (!on->onion_a) {
|
||||
kill_onion(on->onion);
|
||||
|
@ -429,7 +431,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index)
|
|||
}
|
||||
|
||||
TCP_Proxy_Info inf = {{{{0}}}};
|
||||
on->onion_c = new_onion_client(on->log, on->mono_time, new_net_crypto(on->log, on->mono_time, ns, dht, &inf));
|
||||
on->onion_c = new_onion_client(on->log, rng, on->mono_time, new_net_crypto(on->log, rng, ns, on->mono_time, dht, &inf));
|
||||
|
||||
if (!on->onion_c) {
|
||||
kill_onion_announce(on->onion_a);
|
||||
|
@ -532,10 +534,12 @@ static void test_announce(void)
|
|||
uint32_t i, j;
|
||||
uint32_t index[NUM_ONIONS];
|
||||
Onions *onions[NUM_ONIONS];
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
for (i = 0; i < NUM_ONIONS; ++i) {
|
||||
index[i] = i + 1;
|
||||
onions[i] = new_onions(i + 36655, &index[i]);
|
||||
onions[i] = new_onions(rng, i + 36655, &index[i]);
|
||||
ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32
|
|||
|
||||
static void test_reconnect(AutoTox *autotoxes)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const time_t test_start_time = time(nullptr);
|
||||
|
||||
printf("letting connections settle\n");
|
||||
|
@ -59,7 +61,7 @@ static void test_reconnect(AutoTox *autotoxes)
|
|||
iterate_all_wait(autotoxes, TOX_COUNT, ITERATION_INTERVAL);
|
||||
} while (time(nullptr) - test_start_time < 2);
|
||||
|
||||
uint16_t disconnect = random_u16() % TOX_COUNT;
|
||||
const uint16_t disconnect = random_u16(rng) % TOX_COUNT;
|
||||
printf("disconnecting #%u\n", autotoxes[disconnect].index);
|
||||
|
||||
do {
|
||||
|
|
|
@ -19,13 +19,13 @@ struct test_data {
|
|||
bool received_status_message;
|
||||
};
|
||||
|
||||
static void set_random(Tox *m, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length)
|
||||
static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length)
|
||||
{
|
||||
VLA(uint8_t, text, length);
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
text[i] = random_u08();
|
||||
text[i] = random_u08(rng);
|
||||
}
|
||||
|
||||
setter(m, text, SIZEOF_VLA(text), nullptr);
|
||||
|
@ -86,10 +86,12 @@ int main(void)
|
|||
ck_assert(reference_name != nullptr);
|
||||
ck_assert(reference_status != nullptr);
|
||||
|
||||
set_random(tox1, tox_self_set_name, tox_max_name_length());
|
||||
set_random(tox2, tox_self_set_name, tox_max_name_length());
|
||||
set_random(tox1, tox_self_set_status_message, tox_max_status_message_length());
|
||||
set_random(tox2, tox_self_set_status_message, tox_max_status_message_length());
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
set_random(tox1, rng, tox_self_set_name, tox_max_name_length());
|
||||
set_random(tox2, rng, tox_self_set_name, tox_max_name_length());
|
||||
set_random(tox1, rng, tox_self_set_status_message, tox_max_status_message_length());
|
||||
set_random(tox2, rng, tox_self_set_status_message, tox_max_status_message_length());
|
||||
|
||||
tox_self_get_name(tox2, reference_name);
|
||||
tox_self_get_status_message(tox2, reference_status);
|
||||
|
|
|
@ -41,6 +41,8 @@ static uint16_t tcp_relay_port = 33448;
|
|||
|
||||
static void test_many_clients_tcp(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
long long unsigned int cur_time = time(nullptr);
|
||||
Tox *toxes[NUM_TOXES_TCP];
|
||||
uint32_t index[NUM_TOXES_TCP];
|
||||
|
@ -88,8 +90,8 @@ static void test_many_clients_tcp(void)
|
|||
|
||||
for (i = 0; i < NUM_FRIENDS; ++i) {
|
||||
loop_top:
|
||||
pairs[i].tox1 = random_u32() % NUM_TOXES_TCP;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
|
||||
pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
|
||||
|
@ -142,6 +144,8 @@ loop_top:
|
|||
|
||||
static void test_many_clients_tcp_b(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
long long unsigned int cur_time = time(nullptr);
|
||||
Tox *toxes[NUM_TOXES_TCP];
|
||||
uint32_t index[NUM_TOXES_TCP];
|
||||
|
@ -181,8 +185,8 @@ static void test_many_clients_tcp_b(void)
|
|||
|
||||
for (i = 0; i < NUM_FRIENDS; ++i) {
|
||||
loop_top:
|
||||
pairs[i].tox1 = random_u32() % NUM_TOXES_TCP;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
|
||||
pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
|
||||
|
|
|
@ -26,6 +26,8 @@ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8
|
|||
|
||||
static void test_many_clients(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ck_assert(rng != nullptr);
|
||||
time_t cur_time = time(nullptr);
|
||||
Tox *toxes[TCP_TEST_NUM_TOXES];
|
||||
uint32_t index[TCP_TEST_NUM_TOXES];
|
||||
|
@ -54,8 +56,8 @@ static void test_many_clients(void)
|
|||
|
||||
for (uint32_t i = 0; i < TCP_TEST_NUM_FRIENDS; ++i) {
|
||||
loop_top:
|
||||
pairs[i].tox1 = random_u32() % TCP_TEST_NUM_TOXES;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (TCP_TEST_NUM_TOXES - 1) + 1) % TCP_TEST_NUM_TOXES;
|
||||
pairs[i].tox1 = random_u32(rng) % TCP_TEST_NUM_TOXES;
|
||||
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (TCP_TEST_NUM_TOXES - 1) + 1) % TCP_TEST_NUM_TOXES;
|
||||
|
||||
for (uint32_t j = 0; j < i; ++j) {
|
||||
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
|
||||
|
|
|
@ -143,12 +143,13 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
Mono_Time *mono_time = mono_time_new();
|
||||
const Random *rng = system_random();
|
||||
const uint16_t start_port = PORT;
|
||||
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
|
||||
const Network *ns = system_network();
|
||||
DHT *dht = new_dht(logger, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true);
|
||||
Onion *onion = new_onion(logger, mono_time, dht);
|
||||
const Onion_Announce *onion_a = new_onion_announce(logger, mono_time, dht);
|
||||
DHT *dht = new_dht(logger, rng, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true);
|
||||
Onion *onion = new_onion(logger, mono_time, rng, dht);
|
||||
const Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht);
|
||||
|
||||
#ifdef DHT_NODE_EXTRA_PACKETS
|
||||
bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
|
||||
|
@ -167,7 +168,7 @@ int main(int argc, char *argv[])
|
|||
#ifdef TCP_RELAY_ENABLED
|
||||
#define NUM_PORTS 3
|
||||
uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion);
|
||||
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion);
|
||||
|
||||
if (tcp_s == nullptr) {
|
||||
printf("TCP server failed to initialize.\n");
|
||||
|
|
|
@ -1 +1 @@
|
|||
c40a0017ec22042f0be897893a774b89a6b6fbb621ac4d7f68416134fe4a78a2 /usr/local/bin/tox-bootstrapd
|
||||
f5e4829db74abffd2c625e2413730e474a4c8bf999d56a0d2009a38be9d01dec /usr/local/bin/tox-bootstrapd
|
||||
|
|
|
@ -320,7 +320,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
mono_time_update(mono_time);
|
||||
|
||||
DHT *const dht = new_dht(logger, ns, mono_time, net, true, enable_lan_discovery);
|
||||
const Random *rng = system_random();
|
||||
DHT *const dht = new_dht(logger, rng, ns, mono_time, net, true, enable_lan_discovery);
|
||||
|
||||
if (dht == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
|
||||
|
@ -333,7 +334,7 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
Onion *onion = new_onion(logger, mono_time, dht);
|
||||
Onion *onion = new_onion(logger, mono_time, rng, dht);
|
||||
|
||||
if (!onion) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
|
||||
|
@ -347,7 +348,7 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
Onion_Announce *onion_a = new_onion_announce(logger, mono_time, dht);
|
||||
Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht);
|
||||
|
||||
if (!onion_a) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
|
||||
|
@ -412,8 +413,8 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
tcp_server = new_TCP_server(logger, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports,
|
||||
dht_get_self_secret_key(dht), onion);
|
||||
tcp_server = new_TCP_server(
|
||||
logger, rng, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion);
|
||||
|
||||
free(tcp_relay_ports);
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ int main(int argc, char *argv[])
|
|||
Messenger_Options options = {0};
|
||||
options.ipv6enabled = ipv6enabled;
|
||||
Messenger_Error err;
|
||||
m = new_messenger(mono_time, system_network(), &options, &err);
|
||||
m = new_messenger(mono_time, system_random(), system_network(), &options, &err);
|
||||
|
||||
if (!m) {
|
||||
fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err);
|
||||
|
|
|
@ -131,6 +131,7 @@ cc_library(
|
|||
"//c-toxcore/toxcore:ccompat",
|
||||
"//c-toxcore/toxcore:logger",
|
||||
"//c-toxcore/toxcore:mono_time",
|
||||
"//c-toxcore/toxcore:tox",
|
||||
"//c-toxcore/toxcore:util",
|
||||
"@opus",
|
||||
],
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../toxcore/ccompat.h"
|
||||
#include "../toxcore/logger.h"
|
||||
#include "../toxcore/mono_time.h"
|
||||
#include "../toxcore/tox_struct.h"
|
||||
#include "../toxcore/util.h"
|
||||
|
||||
#define GROUP_JBUF_SIZE 6
|
||||
|
@ -535,7 +536,7 @@ bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber)
|
|||
*/
|
||||
int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata)
|
||||
{
|
||||
const int groupnumber = add_groupchat(g_c, GROUPCHAT_TYPE_AV);
|
||||
const int groupnumber = add_groupchat(g_c, &tox->rng, GROUPCHAT_TYPE_AV);
|
||||
|
||||
if (groupnumber == -1) {
|
||||
return -1;
|
||||
|
|
|
@ -673,7 +673,7 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
|
|||
// First entry is free.
|
||||
session->work_buffer_list->next_free_entry = 0;
|
||||
|
||||
session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32();
|
||||
session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(m->rng);
|
||||
session->payload_type = payload_type;
|
||||
session->m = m;
|
||||
session->tox = tox;
|
||||
|
|
|
@ -6,30 +6,32 @@
|
|||
|
||||
namespace {
|
||||
|
||||
RTPHeader random_header()
|
||||
RTPHeader random_header(const Random *rng)
|
||||
{
|
||||
return {
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u32(),
|
||||
random_u32(),
|
||||
random_u64(),
|
||||
random_u32(),
|
||||
random_u32(),
|
||||
random_u32(),
|
||||
random_u16(),
|
||||
random_u16(),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
random_u32(rng),
|
||||
random_u32(rng),
|
||||
random_u64(rng),
|
||||
random_u32(rng),
|
||||
random_u32(rng),
|
||||
random_u32(rng),
|
||||
random_u16(rng),
|
||||
random_u16(rng),
|
||||
};
|
||||
}
|
||||
|
||||
TEST(Rtp, Deserialisation)
|
||||
{
|
||||
RTPHeader const header = random_header();
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
RTPHeader const header = random_header(rng);
|
||||
|
||||
uint8_t rdata[RTP_HEADER_SIZE];
|
||||
EXPECT_EQ(rtp_header_pack(rdata, &header), RTP_HEADER_SIZE);
|
||||
|
|
|
@ -1065,7 +1065,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
|
|||
LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", (double)loss * 100);
|
||||
|
||||
/* if less than 10% data loss we do nothing! */
|
||||
if (loss < 0.1f) {
|
||||
if (loss < 0.1F) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ struct DHT {
|
|||
const Logger *log;
|
||||
const Network *ns;
|
||||
Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
Networking_Core *net;
|
||||
|
||||
bool hole_punching_enabled;
|
||||
|
@ -342,8 +343,9 @@ void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *publi
|
|||
* @retval -1 on failure.
|
||||
* @return the length of the created packet on success.
|
||||
*/
|
||||
int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
|
||||
const uint8_t *recv_public_key, const uint8_t *data, uint32_t data_length, uint8_t request_id)
|
||||
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
uint8_t *packet, const uint8_t *recv_public_key,
|
||||
const uint8_t *data, uint32_t data_length, uint8_t request_id)
|
||||
{
|
||||
if (send_public_key == nullptr || packet == nullptr || recv_public_key == nullptr || data == nullptr) {
|
||||
return -1;
|
||||
|
@ -354,7 +356,7 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke
|
|||
}
|
||||
|
||||
uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2;
|
||||
random_nonce(nonce);
|
||||
random_nonce(rng, nonce);
|
||||
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE] = {0};
|
||||
temp[0] = request_id;
|
||||
memcpy(temp + 1, data, data_length);
|
||||
|
@ -514,7 +516,7 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
|
|||
}
|
||||
|
||||
non_null()
|
||||
static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
static int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t *shared_key, const uint8_t type,
|
||||
const uint8_t *plain, size_t plain_length, uint8_t *packet)
|
||||
{
|
||||
|
@ -525,7 +527,7 @@ static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
|||
return -1;
|
||||
}
|
||||
|
||||
random_nonce(nonce);
|
||||
random_nonce(rng, nonce);
|
||||
|
||||
const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
|
||||
|
||||
|
@ -1371,7 +1373,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c
|
|||
|
||||
uint64_t ping_id = 0;
|
||||
|
||||
ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
|
||||
ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, dht->rng, plain_message, sizeof(receiver));
|
||||
|
||||
if (ping_id == 0) {
|
||||
LOGGER_ERROR(dht->log, "adding ping id failed");
|
||||
|
@ -1387,7 +1389,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c
|
|||
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
|
||||
dht_get_shared_key_sent(dht, shared_key, public_key);
|
||||
|
||||
const int len = dht_create_packet(dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
|
||||
const int len = dht_create_packet(dht->rng, dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
|
||||
plain, sizeof(plain), data);
|
||||
|
||||
crypto_memzero(shared_key, sizeof(shared_key));
|
||||
|
@ -1438,8 +1440,8 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
|
|||
const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
|
||||
VLA(uint8_t, data, 1 + nodes_length + length + crypto_size);
|
||||
|
||||
const int len = dht_create_packet(dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
|
||||
plain, 1 + nodes_length + length, data);
|
||||
const int len = dht_create_packet(dht->rng, dht->self_public_key, shared_encryption_key,
|
||||
NET_PACKET_SEND_NODES_IPV6, plain, 1 + nodes_length + length, data);
|
||||
|
||||
if (len != SIZEOF_VLA(data)) {
|
||||
return -1;
|
||||
|
@ -1655,7 +1657,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
|
|||
*dht_friend = empty_dht_friend;
|
||||
memcpy(dht_friend->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
dht_friend->nat.nat_ping_id = random_u64();
|
||||
dht_friend->nat.nat_ping_id = random_u64(dht->rng);
|
||||
++dht->num_friends;
|
||||
|
||||
dht_friend_lock(dht_friend, ip_callback, data, number, lock_count);
|
||||
|
@ -1802,10 +1804,10 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
|||
|
||||
if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
|
||||
|| *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
|
||||
uint32_t rand_node = random_range_u32(num_nodes);
|
||||
uint32_t rand_node = random_range_u32(dht->rng, num_nodes);
|
||||
|
||||
if ((num_nodes - 1) != rand_node) {
|
||||
rand_node += random_range_u32(num_nodes - (rand_node + 1));
|
||||
rand_node += random_range_u32(dht->rng, num_nodes - (rand_node + 1));
|
||||
}
|
||||
|
||||
dht_getnodes(dht, &assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key);
|
||||
|
@ -2162,7 +2164,7 @@ static uint32_t routeone_to_friend(const DHT *dht, const uint8_t *friend_id, con
|
|||
return 0;
|
||||
}
|
||||
|
||||
const uint32_t rand_idx = random_range_u32(n);
|
||||
const uint32_t rand_idx = random_range_u32(dht->rng, n);
|
||||
const int retval = send_packet(dht->net, &ip_list[rand_idx], *packet);
|
||||
|
||||
if ((unsigned int)retval == packet->length) {
|
||||
|
@ -2185,8 +2187,8 @@ static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping
|
|||
memcpy(data + 1, &ping_id, sizeof(uint64_t));
|
||||
/* 254 is NAT ping request packet id */
|
||||
const int len = create_request(
|
||||
dht->self_public_key, dht->self_secret_key, packet_data, public_key, data,
|
||||
sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
|
||||
dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
|
||||
data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
|
@ -2239,7 +2241,7 @@ static int handle_NATping(void *object, const IP_Port *source, const uint8_t *so
|
|||
|
||||
if (packet[0] == NAT_PING_RESPONSE) {
|
||||
if (dht_friend->nat.nat_ping_id == ping_id) {
|
||||
dht_friend->nat.nat_ping_id = random_u64();
|
||||
dht_friend->nat.nat_ping_id = random_u64(dht->rng);
|
||||
dht_friend->nat.hole_punching = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2416,8 +2418,8 @@ static void do_NAT(DHT *dht)
|
|||
* @return the number of nodes.
|
||||
*/
|
||||
non_null()
|
||||
static uint16_t list_nodes(const Client_data *list, size_t length, uint64_t cur_time,
|
||||
Node_format *nodes, uint16_t max_num)
|
||||
static uint16_t list_nodes(const Random *rng, const Client_data *list, size_t length,
|
||||
uint64_t cur_time, Node_format *nodes, uint16_t max_num)
|
||||
{
|
||||
if (max_num == 0) {
|
||||
return 0;
|
||||
|
@ -2435,7 +2437,7 @@ static uint16_t list_nodes(const Client_data *list, size_t length, uint64_t cur_
|
|||
if (!assoc_timeout(cur_time, &list[i - 1].assoc6)) {
|
||||
if (assoc == nullptr) {
|
||||
assoc = &list[i - 1].assoc6;
|
||||
} else if ((random_u08() % 2) != 0) {
|
||||
} else if ((random_u08(rng) % 2) != 0) {
|
||||
assoc = &list[i - 1].assoc6;
|
||||
}
|
||||
}
|
||||
|
@ -2465,10 +2467,11 @@ uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num)
|
|||
}
|
||||
|
||||
uint16_t count = 0;
|
||||
const uint32_t r = random_u32();
|
||||
const uint32_t r = random_u32(dht->rng);
|
||||
|
||||
for (size_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
|
||||
count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, dht->cur_time,
|
||||
count += list_nodes(dht->rng, dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list,
|
||||
MAX_FRIEND_CLIENTS, dht->cur_time,
|
||||
nodes + count, max_num - count);
|
||||
|
||||
if (count >= max_num) {
|
||||
|
@ -2485,7 +2488,7 @@ uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num)
|
|||
*/
|
||||
uint16_t closelist_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num)
|
||||
{
|
||||
return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->cur_time, nodes, max_num);
|
||||
return list_nodes(dht->rng, dht->close_clientlist, LCLIENT_LIST, dht->cur_time, nodes, max_num);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
@ -2569,7 +2572,7 @@ static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_
|
|||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Networking_Core *net,
|
||||
DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net,
|
||||
bool hole_punching_enabled, bool lan_discovery_enabled)
|
||||
{
|
||||
if (net == nullptr) {
|
||||
|
@ -2587,11 +2590,12 @@ DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Network
|
|||
dht->cur_time = mono_time_get(mono_time);
|
||||
dht->log = log;
|
||||
dht->net = net;
|
||||
dht->rng = rng;
|
||||
|
||||
dht->hole_punching_enabled = hole_punching_enabled;
|
||||
dht->lan_discovery_enabled = lan_discovery_enabled;
|
||||
|
||||
dht->ping = ping_new(mono_time, dht);
|
||||
dht->ping = ping_new(mono_time, rng, dht);
|
||||
|
||||
if (dht->ping == nullptr) {
|
||||
kill_dht(dht);
|
||||
|
@ -2604,7 +2608,7 @@ DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Network
|
|||
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
|
||||
|
||||
crypto_new_keypair(dht->self_public_key, dht->self_secret_key);
|
||||
crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key);
|
||||
|
||||
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
||||
|
||||
|
@ -2617,7 +2621,7 @@ DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Network
|
|||
uint8_t random_public_key_bytes[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t random_secret_key_bytes[CRYPTO_SECRET_KEY_SIZE];
|
||||
|
||||
crypto_new_keypair(random_public_key_bytes, random_secret_key_bytes);
|
||||
crypto_new_keypair(rng, random_public_key_bytes, random_secret_key_bytes);
|
||||
|
||||
if (dht_addfriend(dht, random_public_key_bytes, nullptr, nullptr, 0, nullptr) != 0) {
|
||||
kill_dht(dht);
|
||||
|
|
|
@ -92,9 +92,9 @@ extern "C" {
|
|||
* @return the length of the created packet on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_request(
|
||||
const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
|
||||
const uint8_t *recv_public_key, const uint8_t *data, uint32_t data_length, uint8_t request_id);
|
||||
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
uint8_t *packet, const uint8_t *recv_public_key,
|
||||
const uint8_t *data, uint32_t data_length, uint8_t request_id);
|
||||
|
||||
/**
|
||||
* @brief Decrypts and unpacks a DHT request packet.
|
||||
|
@ -470,7 +470,7 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
|
|||
|
||||
/** Initialize DHT. */
|
||||
non_null()
|
||||
DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Networking_Core *net,
|
||||
DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net,
|
||||
bool hole_punching_enabled, bool lan_discovery_enabled);
|
||||
|
||||
non_null()
|
||||
|
|
|
@ -16,7 +16,7 @@ struct KeyPair {
|
|||
PublicKey pk;
|
||||
SecretKey sk;
|
||||
|
||||
KeyPair() { crypto_new_keypair(pk.data(), sk.data()); }
|
||||
explicit KeyPair(const Random *rng) { crypto_new_keypair(rng, pk.data(), sk.data()); }
|
||||
};
|
||||
|
||||
template <typename T, size_t N>
|
||||
|
@ -27,17 +27,20 @@ std::array<T, N> to_array(T const (&arr)[N])
|
|||
return stdarr;
|
||||
}
|
||||
|
||||
PublicKey random_pk()
|
||||
PublicKey random_pk(const Random *rng)
|
||||
{
|
||||
PublicKey pk;
|
||||
random_bytes(pk.data(), pk.size());
|
||||
random_bytes(rng, pk.data(), pk.size());
|
||||
return pk;
|
||||
}
|
||||
|
||||
TEST(IdClosest, IdenticalKeysAreSameDistance)
|
||||
{
|
||||
PublicKey pk0 = random_pk();
|
||||
PublicKey pk1 = random_pk();
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
PublicKey pk0 = random_pk(rng);
|
||||
PublicKey pk1 = random_pk(rng);
|
||||
PublicKey pk2 = pk1;
|
||||
|
||||
EXPECT_EQ(id_closest(pk0.data(), pk1.data(), pk2.data()), 0);
|
||||
|
@ -45,10 +48,13 @@ TEST(IdClosest, IdenticalKeysAreSameDistance)
|
|||
|
||||
TEST(IdClosest, DistanceIsCommutative)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < 100; ++i) {
|
||||
PublicKey pk0 = random_pk();
|
||||
PublicKey pk1 = random_pk();
|
||||
PublicKey pk2 = random_pk();
|
||||
PublicKey pk0 = random_pk(rng);
|
||||
PublicKey pk1 = random_pk(rng);
|
||||
PublicKey pk2 = random_pk(rng);
|
||||
|
||||
ASSERT_NE(pk1, pk2); // RNG can't produce the same random key twice
|
||||
|
||||
|
@ -124,9 +130,12 @@ TEST(AddToList, OverridesKeysWithCloserKeys)
|
|||
|
||||
TEST(Request, CreateAndParse)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
// Peers.
|
||||
const KeyPair sender;
|
||||
const KeyPair receiver;
|
||||
const KeyPair sender(rng);
|
||||
const KeyPair receiver(rng);
|
||||
const uint8_t sent_pkt_id = CRYPTO_PACKET_FRIEND_REQ;
|
||||
|
||||
// Encoded packet.
|
||||
|
@ -139,17 +148,17 @@ TEST(Request, CreateAndParse)
|
|||
|
||||
// Request data: maximum payload is 918 bytes, so create a payload 1 byte larger than max.
|
||||
std::vector<uint8_t> outgoing(919);
|
||||
random_bytes(outgoing.data(), outgoing.size());
|
||||
random_bytes(rng, outgoing.data(), outgoing.size());
|
||||
|
||||
EXPECT_LT(create_request(sender.pk.data(), sender.sk.data(), packet.data(), receiver.pk.data(),
|
||||
outgoing.data(), outgoing.size(), sent_pkt_id),
|
||||
EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(),
|
||||
receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id),
|
||||
0);
|
||||
|
||||
// Pop one element so the payload is 918 bytes. Packing should now succeed.
|
||||
outgoing.pop_back();
|
||||
|
||||
const int max_sent_length = create_request(sender.pk.data(), sender.sk.data(), packet.data(),
|
||||
receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
|
||||
const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
|
||||
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
|
||||
ASSERT_GT(max_sent_length, 0); // success.
|
||||
|
||||
// Check that handle_request rejects packets larger than the maximum created packet size.
|
||||
|
@ -160,8 +169,8 @@ TEST(Request, CreateAndParse)
|
|||
// Now try all possible packet sizes from max (918) to 0.
|
||||
while (!outgoing.empty()) {
|
||||
// Pack:
|
||||
const int sent_length = create_request(sender.pk.data(), sender.sk.data(), packet.data(),
|
||||
receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
|
||||
const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
|
||||
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
|
||||
ASSERT_GT(sent_length, 0);
|
||||
|
||||
// Unpack:
|
||||
|
|
|
@ -3151,7 +3151,7 @@ static void m_handle_friend_request(
|
|||
*
|
||||
* if error is not NULL it will be set to one of the values in the enum above.
|
||||
*/
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Options *options, Messenger_Error *error)
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error)
|
||||
{
|
||||
if (options == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -3168,6 +3168,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti
|
|||
}
|
||||
|
||||
m->mono_time = mono_time;
|
||||
m->rng = rng;
|
||||
m->ns = ns;
|
||||
|
||||
m->fr = friendreq_new();
|
||||
|
@ -3215,7 +3216,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
m->dht = new_dht(m->log, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled);
|
||||
m->dht = new_dht(m->log, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled);
|
||||
|
||||
if (m->dht == nullptr) {
|
||||
kill_networking(m->net);
|
||||
|
@ -3225,7 +3226,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
m->net_crypto = new_net_crypto(m->log, m->mono_time, m->ns, m->dht, &options->proxy_info);
|
||||
m->net_crypto = new_net_crypto(m->log, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
|
||||
|
||||
if (m->net_crypto == nullptr) {
|
||||
kill_dht(m->dht);
|
||||
|
@ -3236,9 +3237,9 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
m->onion = new_onion(m->log, m->mono_time, m->dht);
|
||||
m->onion_a = new_onion_announce(m->log, m->mono_time, m->dht);
|
||||
m->onion_c = new_onion_client(m->log, m->mono_time, m->net_crypto);
|
||||
m->onion = new_onion(m->log, m->mono_time, m->rng, m->dht);
|
||||
m->onion_a = new_onion_announce(m->log, m->rng, m->mono_time, m->dht);
|
||||
m->onion_c = new_onion_client(m->log, m->rng, m->mono_time, m->net_crypto);
|
||||
m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
|
||||
|
||||
if (m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) {
|
||||
|
@ -3256,7 +3257,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti
|
|||
}
|
||||
|
||||
if (options->tcp_server_port != 0) {
|
||||
m->tcp_server = new_TCP_server(m->log, m->ns, options->ipv6enabled, 1, &options->tcp_server_port,
|
||||
m->tcp_server = new_TCP_server(m->log, m->rng, m->ns, options->ipv6enabled, 1, &options->tcp_server_port,
|
||||
dht_get_self_secret_key(m->dht), m->onion);
|
||||
|
||||
if (m->tcp_server == nullptr) {
|
||||
|
@ -3281,7 +3282,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti
|
|||
|
||||
m->options = *options;
|
||||
friendreq_init(m->fr, m->fr_c);
|
||||
set_nospam(m->fr, random_u32());
|
||||
set_nospam(m->fr, random_u32(m->rng));
|
||||
set_filter_function(m->fr, &friend_already_added, m);
|
||||
|
||||
m->lastdump = 0;
|
||||
|
|
|
@ -234,6 +234,7 @@ typedef struct Friend {
|
|||
struct Messenger {
|
||||
Logger *log;
|
||||
Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
const Network *ns;
|
||||
|
||||
Networking_Core *net;
|
||||
|
@ -754,7 +755,7 @@ typedef enum Messenger_Error {
|
|||
* if error is not NULL it will be set to one of the values in the enum above.
|
||||
*/
|
||||
non_null()
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Options *options, Messenger_Error *error);
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error);
|
||||
|
||||
/** @brief Run this before closing shop.
|
||||
*
|
||||
|
|
|
@ -286,11 +286,11 @@ non_null()
|
|||
static int generate_handshake(TCP_Client_Connection *tcp_conn)
|
||||
{
|
||||
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
|
||||
crypto_new_keypair(plain, tcp_conn->temp_secret_key);
|
||||
random_nonce(tcp_conn->con.sent_nonce);
|
||||
crypto_new_keypair(tcp_conn->con.rng, plain, tcp_conn->temp_secret_key);
|
||||
random_nonce(tcp_conn->con.rng, tcp_conn->con.sent_nonce);
|
||||
memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE);
|
||||
memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
|
||||
sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
|
||||
|
||||
|
@ -529,14 +529,10 @@ void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *o
|
|||
|
||||
/** Create new TCP connection to ip_port/public_key */
|
||||
TCP_Client_Connection *new_TCP_connection(
|
||||
const Logger *logger, const Mono_Time *mono_time, const Network *ns, const IP_Port *ip_port,
|
||||
const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port,
|
||||
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
|
||||
const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
if (networking_at_startup() != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -577,6 +573,7 @@ TCP_Client_Connection *new_TCP_connection(
|
|||
}
|
||||
|
||||
temp->con.ns = ns;
|
||||
temp->con.rng = rng;
|
||||
temp->con.sock = sock;
|
||||
temp->con.ip_port = *ip_port;
|
||||
memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
@ -837,7 +834,7 @@ static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, c
|
|||
tcp_send_ping_request(logger, conn);
|
||||
|
||||
if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
|
||||
uint64_t ping_id = random_u64();
|
||||
uint64_t ping_id = random_u64(conn->con.rng);
|
||||
|
||||
if (ping_id == 0) {
|
||||
++ping_id;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H
|
||||
#define C_TOXCORE_TOXCORE_TCP_CLIENT_H
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mono_time.h"
|
||||
#include "network.h"
|
||||
|
||||
|
@ -55,9 +56,9 @@ non_null()
|
|||
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
|
||||
|
||||
/** Create new TCP connection to ip_port/public_key */
|
||||
non_null(1, 2, 3, 4, 5, 6, 7) nullable(8)
|
||||
non_null(1, 2, 3, 4, 5, 6, 7, 8) nullable(9)
|
||||
TCP_Client_Connection *new_TCP_connection(
|
||||
const Logger *logger, const Mono_Time *mono_time, const Network *ns, const IP_Port *ip_port,
|
||||
const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port,
|
||||
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
|
||||
const TCP_Proxy_Info *proxy_info);
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ void wipe_priority_list(TCP_Priority_List *p);
|
|||
#define MAX_PACKET_SIZE 2048
|
||||
|
||||
typedef struct TCP_Connection {
|
||||
const Random *rng;
|
||||
const Network *ns;
|
||||
Socket sock;
|
||||
IP_Port ip_port; // for debugging.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
struct TCP_Connections {
|
||||
const Logger *logger;
|
||||
const Random *rng;
|
||||
Mono_Time *mono_time;
|
||||
const Network *ns;
|
||||
DHT *dht;
|
||||
|
@ -380,7 +381,7 @@ int send_packet_tcp_connection(const TCP_Connections *tcp_c, int connections_num
|
|||
*/
|
||||
int get_random_tcp_onion_conn_number(const TCP_Connections *tcp_c)
|
||||
{
|
||||
const uint32_t r = random_u32();
|
||||
const uint32_t r = random_u32(tcp_c->rng);
|
||||
|
||||
for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) {
|
||||
const uint32_t index = (i + r) % tcp_c->tcp_connections_length;
|
||||
|
@ -813,7 +814,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
|
|||
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
kill_TCP_connection(tcp_con->connection);
|
||||
tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
|
||||
if (tcp_con->connection == nullptr) {
|
||||
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
|
||||
|
@ -901,7 +902,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
|
|||
}
|
||||
|
||||
tcp_con->connection = new_TCP_connection(
|
||||
tcp_c->logger, tcp_c->mono_time, tcp_c->ns, &tcp_con->ip_port,
|
||||
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port,
|
||||
tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
|
||||
if (tcp_con->connection == nullptr) {
|
||||
|
@ -1186,7 +1187,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port
|
|||
TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number];
|
||||
|
||||
tcp_con->connection = new_TCP_connection(
|
||||
tcp_c->logger, tcp_c->mono_time, tcp_c->ns, &ipp_copy,
|
||||
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
|
||||
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
|
||||
if (tcp_con->connection == nullptr) {
|
||||
|
@ -1354,7 +1355,7 @@ static bool copy_tcp_relay_conn(const TCP_Connections *tcp_c, Node_format *tcp_r
|
|||
*/
|
||||
uint32_t tcp_copy_connected_relays(const TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num)
|
||||
{
|
||||
const uint32_t r = random_u32();
|
||||
const uint32_t r = random_u32(tcp_c->rng);
|
||||
uint32_t copied = 0;
|
||||
|
||||
for (uint32_t i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) {
|
||||
|
@ -1462,8 +1463,9 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
|
|||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, const Network *ns,
|
||||
const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info)
|
||||
TCP_Connections *new_tcp_connections(
|
||||
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, const uint8_t *secret_key,
|
||||
const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
if (secret_key == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -1476,6 +1478,7 @@ TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time,
|
|||
}
|
||||
|
||||
temp->logger = logger;
|
||||
temp->rng = rng;
|
||||
temp->mono_time = mono_time;
|
||||
temp->ns = ns;
|
||||
|
||||
|
|
|
@ -251,8 +251,9 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form
|
|||
* Returns NULL on failure.
|
||||
*/
|
||||
non_null()
|
||||
TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, const Network *ns,
|
||||
const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
|
||||
TCP_Connections *new_tcp_connections(
|
||||
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time,
|
||||
const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
|
||||
|
||||
non_null()
|
||||
int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number);
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct TCP_Secure_Connection {
|
|||
|
||||
struct TCP_Server {
|
||||
const Logger *logger;
|
||||
const Random *rng;
|
||||
const Network *ns;
|
||||
Onion *onion;
|
||||
|
||||
|
@ -327,13 +328,13 @@ static int handle_TCP_handshake(const Logger *logger, TCP_Secure_Connection *con
|
|||
memcpy(con->public_key, data, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
|
||||
crypto_new_keypair(resp_plain, temp_secret_key);
|
||||
random_nonce(con->con.sent_nonce);
|
||||
crypto_new_keypair(con->con.rng, resp_plain, temp_secret_key);
|
||||
random_nonce(con->con.rng, con->con.sent_nonce);
|
||||
memcpy(resp_plain + CRYPTO_PUBLIC_KEY_SIZE, con->con.sent_nonce, CRYPTO_NONCE_SIZE);
|
||||
memcpy(con->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
|
||||
|
||||
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
|
||||
random_nonce(response);
|
||||
random_nonce(con->con.rng, response);
|
||||
|
||||
len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
|
||||
response + CRYPTO_NONCE_SIZE);
|
||||
|
@ -801,6 +802,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
|
|||
|
||||
conn->status = TCP_STATUS_CONNECTED;
|
||||
conn->con.ns = tcp_server->ns;
|
||||
conn->con.rng = tcp_server->rng;
|
||||
conn->con.sock = sock;
|
||||
conn->next_packet_length = 0;
|
||||
|
||||
|
@ -843,8 +845,9 @@ static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns,
|
|||
return sock;
|
||||
}
|
||||
|
||||
TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_enabled, uint16_t num_sockets,
|
||||
const uint16_t *ports, const uint8_t *secret_key, Onion *onion)
|
||||
TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns,
|
||||
bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports,
|
||||
const uint8_t *secret_key, Onion *onion)
|
||||
{
|
||||
if (num_sockets == 0 || ports == nullptr) {
|
||||
LOGGER_ERROR(logger, "no sockets");
|
||||
|
@ -856,11 +859,6 @@ TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_en
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (networking_at_startup() != 0) {
|
||||
LOGGER_ERROR(logger, "network initialisation failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TCP_Server *temp = (TCP_Server *)calloc(1, sizeof(TCP_Server));
|
||||
|
||||
if (temp == nullptr) {
|
||||
|
@ -870,6 +868,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_en
|
|||
|
||||
temp->logger = logger;
|
||||
temp->ns = ns;
|
||||
temp->rng = rng;
|
||||
|
||||
temp->socks_listening = (Socket *)calloc(num_sockets, sizeof(Socket));
|
||||
|
||||
|
@ -1089,7 +1088,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
|||
if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
|
||||
uint8_t ping[1 + sizeof(uint64_t)];
|
||||
ping[0] = TCP_PACKET_PING;
|
||||
uint64_t ping_id = random_u64();
|
||||
uint64_t ping_id = random_u64(conn->con.rng);
|
||||
|
||||
if (ping_id == 0) {
|
||||
++ping_id;
|
||||
|
|
|
@ -33,9 +33,10 @@ non_null()
|
|||
size_t tcp_server_listen_count(const TCP_Server *tcp_server);
|
||||
|
||||
/** Create new TCP server instance. */
|
||||
non_null(1, 2, 5, 6) nullable(7)
|
||||
TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_enabled, uint16_t num_sockets,
|
||||
const uint16_t *ports, const uint8_t *secret_key, Onion *onion);
|
||||
non_null(1, 2, 3, 6, 7) nullable(8)
|
||||
TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns,
|
||||
bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports,
|
||||
const uint8_t *secret_key, Onion *onion);
|
||||
|
||||
/** Run the TCP_server */
|
||||
non_null()
|
||||
|
|
|
@ -173,41 +173,37 @@ bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2)
|
|||
#endif
|
||||
}
|
||||
|
||||
uint8_t random_u08(void)
|
||||
uint8_t random_u08(const Random *rng)
|
||||
{
|
||||
uint8_t randnum;
|
||||
random_bytes(&randnum, 1);
|
||||
random_bytes(rng, &randnum, 1);
|
||||
return randnum;
|
||||
}
|
||||
|
||||
uint16_t random_u16(void)
|
||||
uint16_t random_u16(const Random *rng)
|
||||
{
|
||||
uint16_t randnum;
|
||||
random_bytes((uint8_t *)&randnum, sizeof(randnum));
|
||||
random_bytes(rng, (uint8_t *)&randnum, sizeof(randnum));
|
||||
return randnum;
|
||||
}
|
||||
|
||||
uint32_t random_u32(void)
|
||||
uint32_t random_u32(const Random *rng)
|
||||
{
|
||||
uint32_t randnum;
|
||||
random_bytes((uint8_t *)&randnum, sizeof(randnum));
|
||||
random_bytes(rng, (uint8_t *)&randnum, sizeof(randnum));
|
||||
return randnum;
|
||||
}
|
||||
|
||||
uint64_t random_u64(void)
|
||||
uint64_t random_u64(const Random *rng)
|
||||
{
|
||||
uint64_t randnum;
|
||||
random_bytes((uint8_t *)&randnum, sizeof(randnum));
|
||||
random_bytes(rng, (uint8_t *)&randnum, sizeof(randnum));
|
||||
return randnum;
|
||||
}
|
||||
|
||||
uint32_t random_range_u32(uint32_t upper_bound)
|
||||
uint32_t random_range_u32(const Random *rng, uint32_t upper_bound)
|
||||
{
|
||||
#ifdef VANILLA_NACL
|
||||
return random_u32() % upper_bound;
|
||||
#else
|
||||
return randombytes_uniform(upper_bound);
|
||||
#endif // VANILLA_NACL
|
||||
return rng->funcs->random_uniform(rng->obj, upper_bound);
|
||||
}
|
||||
|
||||
bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_t message_length,
|
||||
|
@ -417,20 +413,20 @@ void increment_nonce_number(uint8_t *nonce, uint32_t increment)
|
|||
}
|
||||
}
|
||||
|
||||
void random_nonce(uint8_t *nonce)
|
||||
void random_nonce(const Random *rng, uint8_t *nonce)
|
||||
{
|
||||
random_bytes(nonce, crypto_box_NONCEBYTES);
|
||||
random_bytes(rng, nonce, crypto_box_NONCEBYTES);
|
||||
}
|
||||
|
||||
void new_symmetric_key(uint8_t *key)
|
||||
void new_symmetric_key(const Random *rng, uint8_t *key)
|
||||
{
|
||||
random_bytes(key, CRYPTO_SYMMETRIC_KEY_SIZE);
|
||||
random_bytes(rng, key, CRYPTO_SYMMETRIC_KEY_SIZE);
|
||||
}
|
||||
|
||||
int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key)
|
||||
int32_t crypto_new_keypair(const Random *rng, uint8_t *public_key, uint8_t *secret_key)
|
||||
{
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
random_bytes(secret_key, CRYPTO_SECRET_KEY_SIZE);
|
||||
random_bytes(rng, secret_key, CRYPTO_SECRET_KEY_SIZE);
|
||||
memset(public_key, 0, CRYPTO_PUBLIC_KEY_SIZE); // Make MSAN happy
|
||||
crypto_scalarmult_curve25519_base(public_key, secret_key);
|
||||
return 0;
|
||||
|
@ -454,7 +450,8 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length)
|
|||
crypto_hash_sha512(hash, data, length);
|
||||
}
|
||||
|
||||
void random_bytes(uint8_t *bytes, size_t length)
|
||||
non_null()
|
||||
static void sys_random_bytes(void *obj, uint8_t *bytes, size_t length)
|
||||
{
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
fuzz_random_bytes(bytes, length);
|
||||
|
@ -462,3 +459,40 @@ void random_bytes(uint8_t *bytes, size_t length)
|
|||
randombytes(bytes, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
non_null()
|
||||
static uint32_t sys_random_uniform(void *obj, uint32_t upper_bound)
|
||||
{
|
||||
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL)
|
||||
uint32_t randnum;
|
||||
sys_random_bytes(obj, (uint8_t *)&randnum, sizeof(randnum));
|
||||
return randnum % upper_bound;
|
||||
#else
|
||||
return randombytes_uniform(upper_bound);
|
||||
#endif // VANILLA_NACL
|
||||
}
|
||||
|
||||
static const Random_Funcs system_random_funcs = {
|
||||
sys_random_bytes,
|
||||
sys_random_uniform,
|
||||
};
|
||||
|
||||
static const Random system_random_obj = {&system_random_funcs};
|
||||
|
||||
const Random *system_random(void)
|
||||
{
|
||||
#ifndef VANILLA_NACL
|
||||
// It is safe to call this function more than once and from different
|
||||
// threads -- subsequent calls won't have any effects.
|
||||
if (sodium_init() == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &system_random_obj;
|
||||
}
|
||||
|
||||
void random_bytes(const Random *rng, uint8_t *bytes, size_t length)
|
||||
{
|
||||
rng->funcs->random_bytes(rng->obj, bytes, length);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,21 @@ extern "C" {
|
|||
*/
|
||||
#define CRYPTO_SHA512_SIZE 64
|
||||
|
||||
typedef void crypto_random_bytes_cb(void *obj, uint8_t *bytes, size_t length);
|
||||
typedef uint32_t crypto_random_uniform_cb(void *obj, uint32_t upper_bound);
|
||||
|
||||
typedef struct Random_Funcs {
|
||||
crypto_random_bytes_cb *random_bytes;
|
||||
crypto_random_uniform_cb *random_uniform;
|
||||
} Random_Funcs;
|
||||
|
||||
typedef struct Random {
|
||||
const Random_Funcs *funcs;
|
||||
void *obj;
|
||||
} Random;
|
||||
|
||||
const Random *system_random(void);
|
||||
|
||||
/**
|
||||
* @brief The number of bytes in an encryption public key used by DHT group chats.
|
||||
*/
|
||||
|
@ -154,22 +169,26 @@ bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2);
|
|||
/**
|
||||
* @brief Return a random 8 bit integer.
|
||||
*/
|
||||
uint8_t random_u08(void);
|
||||
non_null()
|
||||
uint8_t random_u08(const Random *rng);
|
||||
|
||||
/**
|
||||
* @brief Return a random 16 bit integer.
|
||||
*/
|
||||
uint16_t random_u16(void);
|
||||
non_null()
|
||||
uint16_t random_u16(const Random *rng);
|
||||
|
||||
/**
|
||||
* @brief Return a random 32 bit integer.
|
||||
*/
|
||||
uint32_t random_u32(void);
|
||||
non_null()
|
||||
uint32_t random_u32(const Random *rng);
|
||||
|
||||
/**
|
||||
* @brief Return a random 64 bit integer.
|
||||
*/
|
||||
uint64_t random_u64(void);
|
||||
non_null()
|
||||
uint64_t random_u64(const Random *rng);
|
||||
|
||||
/**
|
||||
* @brief Return a random 32 bit integer between 0 and upper_bound (excluded).
|
||||
|
@ -177,7 +196,8 @@ uint64_t random_u64(void);
|
|||
* On libsodium builds this function guarantees a uniform distribution of possible outputs.
|
||||
* On vanilla NACL builds this function is equivalent to `random() % upper_bound`.
|
||||
*/
|
||||
uint32_t random_range_u32(uint32_t upper_bound);
|
||||
non_null()
|
||||
uint32_t random_range_u32(const Random *rng, uint32_t upper_bound);
|
||||
|
||||
/** @brief Cryptographically signs a message using the supplied secret key and puts the resulting signature
|
||||
* in the supplied buffer.
|
||||
|
@ -213,13 +233,13 @@ bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, u
|
|||
* @brief Fill the given nonce with random bytes.
|
||||
*/
|
||||
non_null()
|
||||
void random_nonce(uint8_t *nonce);
|
||||
void random_nonce(const Random *rng, uint8_t *nonce);
|
||||
|
||||
/**
|
||||
* @brief Fill an array of bytes with random values.
|
||||
*/
|
||||
non_null()
|
||||
void random_bytes(uint8_t *bytes, size_t length);
|
||||
void random_bytes(const Random *rng, uint8_t *bytes, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not.
|
||||
|
@ -248,7 +268,7 @@ bool create_extended_keypair(uint8_t *pk, uint8_t *sk);
|
|||
* Every call to this function is likely to generate a different keypair.
|
||||
*/
|
||||
non_null()
|
||||
int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key);
|
||||
int32_t crypto_new_keypair(const Random *rng, uint8_t *public_key, uint8_t *secret_key);
|
||||
|
||||
/**
|
||||
* @brief Derive the public key from a given secret key.
|
||||
|
@ -343,7 +363,7 @@ void increment_nonce_number(uint8_t *nonce, uint32_t increment);
|
|||
* @brief Fill a key @ref CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes.
|
||||
*/
|
||||
non_null()
|
||||
void new_symmetric_key(uint8_t *key);
|
||||
void new_symmetric_key(const Random *rng, uint8_t *key);
|
||||
|
||||
/**
|
||||
* @brief Locks `length` bytes of memory pointed to by `data`.
|
||||
|
|
|
@ -50,6 +50,9 @@ TEST(CryptoCore, IncrementNonceNumber)
|
|||
|
||||
TEST(CryptoCore, Signatures)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
ExtPublicKey pk;
|
||||
ExtSecretKey sk;
|
||||
|
||||
|
@ -59,7 +62,7 @@ TEST(CryptoCore, Signatures)
|
|||
|
||||
// Try a few different sizes, including empty 0 length message.
|
||||
for (uint8_t i = 0; i < 100; ++i) {
|
||||
message.push_back(random_u08());
|
||||
message.push_back(random_u08(rng));
|
||||
Signature signature;
|
||||
EXPECT_TRUE(crypto_signature_create(
|
||||
signature.data(), message.data(), message.size(), get_sig_sk(sk.data())));
|
||||
|
|
|
@ -1309,12 +1309,13 @@ static void remove_connection_reason(Group_Chats *g_c, Group_c *g, uint16_t i, u
|
|||
|
||||
/** @brief Creates a new groupchat and puts it in the chats array.
|
||||
*
|
||||
* @param rng Random number generator used for generating the group ID.
|
||||
* @param type is one of `GROUPCHAT_TYPE_*`
|
||||
*
|
||||
* @return group number on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
int add_groupchat(Group_Chats *g_c, uint8_t type)
|
||||
int add_groupchat(Group_Chats *g_c, const Random *rng, uint8_t type)
|
||||
{
|
||||
const int32_t groupnumber = create_group_chat(g_c);
|
||||
|
||||
|
@ -1326,7 +1327,7 @@ int add_groupchat(Group_Chats *g_c, uint8_t type)
|
|||
|
||||
g->status = GROUPCHAT_STATUS_CONNECTED;
|
||||
g->type = type;
|
||||
new_symmetric_key(g->id);
|
||||
new_symmetric_key(rng, g->id);
|
||||
g->peer_number = 0; /* Founder is peer 0. */
|
||||
memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
const int peer_index = addpeer(g_c, groupnumber, g->real_pk, dht_get_self_public_key(g_c->m->dht), 0, nullptr, true,
|
||||
|
@ -2177,12 +2178,12 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
|
|||
/* TODO(irungentoo): what if two people enter the group at the
|
||||
* same time and are given the same peer_number by different
|
||||
* nodes? */
|
||||
peer_number = random_u16();
|
||||
peer_number = random_u16(m->rng);
|
||||
|
||||
unsigned int tries = 0;
|
||||
|
||||
while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) {
|
||||
peer_number = random_u16();
|
||||
peer_number = random_u16(m->rng);
|
||||
++tries;
|
||||
|
||||
if (tries > 32) {
|
||||
|
|
|
@ -93,13 +93,14 @@ void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *functi
|
|||
|
||||
/** @brief Creates a new groupchat and puts it in the chats array.
|
||||
*
|
||||
* @param rng Random number generator used for generating the group ID.
|
||||
* @param type is one of `GROUPCHAT_TYPE_*`
|
||||
*
|
||||
* @return group number on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
int add_groupchat(Group_Chats *g_c, uint8_t type);
|
||||
int add_groupchat(Group_Chats *g_c, const Random *rng, uint8_t type);
|
||||
|
||||
/** @brief Delete a groupchat from the chats array, informing the group first as
|
||||
* appropriate.
|
||||
|
|
|
@ -84,11 +84,14 @@ TEST(ModList, UnpackingFromEmptyBufferFails)
|
|||
|
||||
TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
Moderation mods{};
|
||||
|
||||
// Fill with random data, check that it's zeroed.
|
||||
ModerationHash hash;
|
||||
random_bytes(hash.data(), hash.size());
|
||||
random_bytes(rng, hash.data(), hash.size());
|
||||
EXPECT_TRUE(mod_list_make_hash(&mods, hash.data()));
|
||||
EXPECT_EQ(hash, ModerationHash{});
|
||||
}
|
||||
|
|
|
@ -127,6 +127,7 @@ static const Crypto_Connection empty_crypto_connection = {{0}};
|
|||
|
||||
struct Net_Crypto {
|
||||
const Logger *log;
|
||||
const Random *rng;
|
||||
Mono_Time *mono_time;
|
||||
const Network *ns;
|
||||
|
||||
|
@ -225,7 +226,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
|
|||
|
||||
dht_get_shared_key_sent(c->dht, shared_key, dht_public_key);
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
random_nonce(c->rng, nonce);
|
||||
packet[0] = NET_PACKET_COOKIE_REQUEST;
|
||||
memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
|
||||
|
@ -245,14 +246,14 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
|
|||
* @retval 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
static int create_cookie(const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
|
||||
static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
|
||||
const uint8_t *encryption_key)
|
||||
{
|
||||
uint8_t contents[COOKIE_CONTENTS_LENGTH];
|
||||
const uint64_t temp_time = mono_time_get(mono_time);
|
||||
memcpy(contents, &temp_time, sizeof(temp_time));
|
||||
memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
|
||||
random_nonce(cookie);
|
||||
random_nonce(rng, cookie);
|
||||
const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) {
|
||||
|
@ -308,13 +309,13 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
|
|||
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
|
||||
|
||||
if (create_cookie(c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
|
||||
if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
|
||||
packet[0] = NET_PACKET_COOKIE_RESPONSE;
|
||||
random_nonce(packet + 1);
|
||||
random_nonce(c->rng, packet + 1);
|
||||
const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
|
||||
|
||||
if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) {
|
||||
|
@ -480,12 +481,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
|
|||
memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (create_cookie(c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
|
||||
if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
|
||||
cookie_plain, c->secret_symmetric_key) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
random_nonce(packet + 1 + COOKIE_LENGTH);
|
||||
random_nonce(c->rng, packet + 1 + COOKIE_LENGTH);
|
||||
const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
|
||||
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE);
|
||||
|
||||
|
@ -2107,8 +2108,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
|
|||
memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE);
|
||||
memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(conn->sent_nonce);
|
||||
crypto_new_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
|
||||
random_nonce(c->rng, conn->sent_nonce);
|
||||
crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key);
|
||||
encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
|
||||
conn->status = CRYPTO_CONN_NOT_CONFIRMED;
|
||||
|
||||
|
@ -2162,8 +2163,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
|
|||
|
||||
conn->connection_number_tcp = connection_number_tcp;
|
||||
memcpy(conn->public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
random_nonce(conn->sent_nonce);
|
||||
crypto_new_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
|
||||
random_nonce(c->rng, conn->sent_nonce);
|
||||
crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key);
|
||||
conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
|
||||
conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
|
||||
conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE;
|
||||
|
@ -2171,7 +2172,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
|
|||
conn->rtt_time = DEFAULT_PING_CONNECTION;
|
||||
memcpy(conn->dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
conn->cookie_request_number = random_u64();
|
||||
conn->cookie_request_number = random_u64(c->rng);
|
||||
uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
|
||||
|
||||
if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
|
||||
|
@ -3048,7 +3049,7 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool
|
|||
|
||||
void new_keys(Net_Crypto *c)
|
||||
{
|
||||
crypto_new_keypair(c->self_public_key, c->self_secret_key);
|
||||
crypto_new_keypair(c->rng, c->self_public_key, c->self_secret_key);
|
||||
}
|
||||
|
||||
/** @brief Save the public and private keys to the keys array.
|
||||
|
@ -3074,7 +3075,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
|
|||
/** @brief Create new instance of Net_Crypto.
|
||||
* Sets all the global connection variables to their default values.
|
||||
*/
|
||||
Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Network *ns, DHT *dht, const TCP_Proxy_Info *proxy_info)
|
||||
Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -3087,10 +3088,11 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Networ
|
|||
}
|
||||
|
||||
temp->log = log;
|
||||
temp->rng = rng;
|
||||
temp->mono_time = mono_time;
|
||||
temp->ns = ns;
|
||||
|
||||
temp->tcp_c = new_tcp_connections(log, mono_time, ns, dht_get_self_secret_key(dht), proxy_info);
|
||||
temp->tcp_c = new_tcp_connections(log, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info);
|
||||
|
||||
if (temp->tcp_c == nullptr) {
|
||||
free(temp);
|
||||
|
@ -3110,7 +3112,7 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Networ
|
|||
temp->dht = dht;
|
||||
|
||||
new_keys(temp);
|
||||
new_symmetric_key(temp->secret_symmetric_key);
|
||||
new_symmetric_key(rng, temp->secret_symmetric_key);
|
||||
|
||||
temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL;
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk);
|
|||
* Sets all the global connection variables to their default values.
|
||||
*/
|
||||
non_null()
|
||||
Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Network *ns, DHT *dht, const TCP_Proxy_Info *proxy_info);
|
||||
Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info);
|
||||
|
||||
/** return the optimal interval in ms for running do_net_crypto. */
|
||||
non_null()
|
||||
|
|
|
@ -608,9 +608,26 @@ static const Network system_network_obj = {&system_network_funcs};
|
|||
|
||||
const Network *system_network(void)
|
||||
{
|
||||
#ifdef OS_WIN32
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
return &system_network_obj;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* TODO(iphydf): Call this from functions that use `system_network()`. */
|
||||
void system_network_deinit(const Network *ns)
|
||||
{
|
||||
#ifdef OS_WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
non_null()
|
||||
static int net_setsockopt(const Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen)
|
||||
{
|
||||
|
@ -979,52 +996,6 @@ void networking_poll(const Networking_Core *net, void *userdata)
|
|||
}
|
||||
}
|
||||
|
||||
//!TOKSTYLE-
|
||||
// Global mutable state is not allowed in Tokstyle.
|
||||
static uint8_t at_startup_ran = 0;
|
||||
//!TOKSTYLE+
|
||||
int networking_at_startup(void)
|
||||
{
|
||||
if (at_startup_ran != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef VANILLA_NACL
|
||||
|
||||
#ifdef USE_RANDOMBYTES_STIR
|
||||
randombytes_stir();
|
||||
#else
|
||||
|
||||
if (sodium_init() == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /*USE_RANDOMBYTES_STIR*/
|
||||
|
||||
#endif/*VANILLA_NACL*/
|
||||
|
||||
#ifdef OS_WIN32
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
at_startup_ran = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO(irungentoo): Put this somewhere */
|
||||
#if 0
|
||||
static void at_shutdown(void)
|
||||
{
|
||||
#ifdef OS_WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief Initialize networking.
|
||||
* Bind to ip and port.
|
||||
* ip must be in network order EX: 127.0.0.1 = (7F000001).
|
||||
|
@ -1066,10 +1037,6 @@ Networking_Core *new_networking_ex(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (networking_at_startup() != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Networking_Core *temp = (Networking_Core *)calloc(1, sizeof(Networking_Core));
|
||||
|
||||
if (temp == nullptr) {
|
||||
|
@ -1273,10 +1240,6 @@ Networking_Core *new_networking_ex(
|
|||
|
||||
Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns)
|
||||
{
|
||||
if (networking_at_startup() != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* this is the easiest way to completely disable UDP without changing too much code. */
|
||||
Networking_Core *net = (Networking_Core *)calloc(1, sizeof(Networking_Core));
|
||||
|
||||
|
@ -1284,6 +1247,7 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
net->ns = ns;
|
||||
net->log = log;
|
||||
net->ns = ns;
|
||||
|
||||
|
@ -1556,10 +1520,6 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
|
|||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
|
||||
|
||||
if (networking_at_startup() != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct addrinfo *server = nullptr;
|
||||
|
||||
const int rc = getaddrinfo(address, nullptr, &hints, &server);
|
||||
|
|
|
@ -428,13 +428,6 @@ Family net_family(const Networking_Core *net);
|
|||
non_null()
|
||||
uint16_t net_port(const Networking_Core *net);
|
||||
|
||||
/** @brief Run this before creating sockets.
|
||||
*
|
||||
* return 0 on success
|
||||
* return -1 on failure
|
||||
*/
|
||||
int networking_at_startup(void);
|
||||
|
||||
/** Close the socket. */
|
||||
non_null()
|
||||
void kill_sock(const Network *ns, Socket sock);
|
||||
|
@ -581,6 +574,7 @@ non_null(1, 2, 3) nullable(6)
|
|||
Networking_Core *new_networking_ex(
|
||||
const Logger *log, const Network *ns, const IP *ip,
|
||||
uint16_t port_from, uint16_t port_to, unsigned int *error);
|
||||
|
||||
non_null()
|
||||
Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns);
|
||||
|
||||
|
|
|
@ -26,12 +26,13 @@
|
|||
#define SEND_1 ONION_SEND_1
|
||||
|
||||
#define KEY_REFRESH_INTERVAL (2 * 60 * 60)
|
||||
|
||||
/** Change symmetric keys every 2 hours to make paths expire eventually. */
|
||||
non_null()
|
||||
static void change_symmetric_key(Onion *onion)
|
||||
{
|
||||
if (mono_time_is_timeout(onion->mono_time, onion->timestamp, KEY_REFRESH_INTERVAL)) {
|
||||
new_symmetric_key(onion->secret_symmetric_key);
|
||||
new_symmetric_key(onion->rng, onion->secret_symmetric_key);
|
||||
onion->timestamp = mono_time_get(onion->mono_time);
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data
|
|||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes)
|
||||
int create_onion_path(const Random *rng, const DHT *dht, Onion_Path *new_path, const Node_format *nodes)
|
||||
{
|
||||
if (new_path == nullptr || nodes == nullptr) {
|
||||
return -1;
|
||||
|
@ -119,11 +120,11 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n
|
|||
uint8_t random_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t random_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
|
||||
crypto_new_keypair(random_public_key, random_secret_key);
|
||||
crypto_new_keypair(rng, random_public_key, random_secret_key);
|
||||
encrypt_precompute(nodes[1].public_key, random_secret_key, new_path->shared_key2);
|
||||
memcpy(new_path->public_key2, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
crypto_new_keypair(random_public_key, random_secret_key);
|
||||
crypto_new_keypair(rng, random_public_key, random_secret_key);
|
||||
encrypt_precompute(nodes[2].public_key, random_secret_key, new_path->shared_key3);
|
||||
memcpy(new_path->public_key3, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
|
@ -170,7 +171,8 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
|
|||
* return -1 on failure.
|
||||
* return length of created packet on success.
|
||||
*/
|
||||
int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
|
||||
int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (1 + length + SEND_1 > max_packet_length || length == 0) {
|
||||
|
@ -183,7 +185,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
|
|||
memcpy(step1 + SIZE_IPPORT, data, length);
|
||||
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
random_nonce(rng, nonce);
|
||||
|
||||
VLA(uint8_t, step2, SIZE_IPPORT + SEND_BASE + length);
|
||||
ipport_pack(step2, &path->ip_port3);
|
||||
|
@ -229,7 +231,8 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
|
|||
* return -1 on failure.
|
||||
* return length of created packet on success.
|
||||
*/
|
||||
int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
|
||||
int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (CRYPTO_NONCE_SIZE + SIZE_IPPORT + SEND_BASE * 2 + length > max_packet_length || length == 0) {
|
||||
|
@ -242,7 +245,7 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O
|
|||
memcpy(step1 + SIZE_IPPORT, data, length);
|
||||
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
random_nonce(rng, nonce);
|
||||
|
||||
VLA(uint8_t, step2, SIZE_IPPORT + SEND_BASE + length);
|
||||
ipport_pack(step2, &path->ip_port3);
|
||||
|
@ -349,7 +352,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I
|
|||
memcpy(data + 1 + CRYPTO_NONCE_SIZE, plain + SIZE_IPPORT, len - SIZE_IPPORT);
|
||||
uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT);
|
||||
uint8_t *ret_part = data + data_len;
|
||||
random_nonce(ret_part);
|
||||
random_nonce(onion->rng, ret_part);
|
||||
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
|
||||
ret_part + CRYPTO_NONCE_SIZE);
|
||||
|
||||
|
@ -404,7 +407,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
|
|||
memcpy(data + 1 + CRYPTO_NONCE_SIZE, plain + SIZE_IPPORT, len - SIZE_IPPORT);
|
||||
uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT);
|
||||
uint8_t *ret_part = data + data_len;
|
||||
random_nonce(ret_part);
|
||||
random_nonce(onion->rng, ret_part);
|
||||
uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
|
||||
ipport_pack(ret_data, source);
|
||||
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
|
||||
|
@ -468,7 +471,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
|
|||
memcpy(data, plain + SIZE_IPPORT, len - SIZE_IPPORT);
|
||||
uint16_t data_len = len - SIZE_IPPORT;
|
||||
uint8_t *ret_part = data + (len - SIZE_IPPORT);
|
||||
random_nonce(ret_part);
|
||||
random_nonce(onion->rng, ret_part);
|
||||
uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
|
||||
ipport_pack(ret_data, source);
|
||||
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
|
||||
|
@ -641,7 +644,7 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o
|
|||
onion->callback_object = object;
|
||||
}
|
||||
|
||||
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, DHT *dht)
|
||||
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -657,7 +660,8 @@ Onion *new_onion(const Logger *log, const Mono_Time *mono_time, DHT *dht)
|
|||
onion->dht = dht;
|
||||
onion->net = dht_get_net(dht);
|
||||
onion->mono_time = mono_time;
|
||||
new_symmetric_key(onion->secret_symmetric_key);
|
||||
onion->rng = rng;
|
||||
new_symmetric_key(rng, onion->secret_symmetric_key);
|
||||
onion->timestamp = mono_time_get(onion->mono_time);
|
||||
|
||||
networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, &handle_send_initial, onion);
|
||||
|
|
|
@ -18,6 +18,7 @@ typedef int onion_recv_1_cb(void *object, const IP_Port *dest, const uint8_t *da
|
|||
typedef struct Onion {
|
||||
const Logger *log;
|
||||
const Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
DHT *dht;
|
||||
Networking_Core *net;
|
||||
uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE];
|
||||
|
@ -78,7 +79,7 @@ typedef struct Onion_Path {
|
|||
* return 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes);
|
||||
int create_onion_path(const Random *rng, const DHT *dht, Onion_Path *new_path, const Node_format *nodes);
|
||||
|
||||
/** @brief Dump nodes in onion path to nodes of length num_nodes.
|
||||
*
|
||||
|
@ -98,7 +99,8 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
|
|||
* return length of created packet on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
|
||||
int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
|
@ -112,7 +114,8 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
|
|||
* return length of created packet on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
|
||||
int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
|
||||
const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *data, uint16_t length);
|
||||
|
||||
/** @brief Create and send a onion response sent initially to dest with.
|
||||
|
@ -143,7 +146,7 @@ non_null(1) nullable(2, 3)
|
|||
void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object);
|
||||
|
||||
non_null()
|
||||
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, DHT *dht);
|
||||
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht);
|
||||
|
||||
non_null()
|
||||
void kill_onion(Onion *onion);
|
||||
|
|
|
@ -45,6 +45,7 @@ typedef struct Onion_Announce_Entry {
|
|||
struct Onion_Announce {
|
||||
const Logger *log;
|
||||
const Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
DHT *dht;
|
||||
Networking_Core *net;
|
||||
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
|
||||
|
@ -97,7 +98,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
|
|||
* return -1 on failure.
|
||||
* return packet length on success.
|
||||
*/
|
||||
int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data)
|
||||
{
|
||||
|
@ -114,7 +115,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
|
|||
sizeof(sendback_data));
|
||||
|
||||
packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD;
|
||||
random_nonce(packet + 1);
|
||||
random_nonce(rng, packet + 1);
|
||||
|
||||
const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
|
||||
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
@ -140,7 +141,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
|
|||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) {
|
||||
|
@ -157,7 +158,7 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8
|
|||
|
||||
uint8_t random_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t random_secret_key[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(random_public_key, random_secret_key);
|
||||
crypto_new_keypair(rng, random_public_key, random_secret_key);
|
||||
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
|
@ -186,13 +187,14 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8
|
|||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_announce_request(const Networking_Core *net, const Onion_Path *path, const Node_format *dest,
|
||||
int send_announce_request(const Networking_Core *net, const Random *rng,
|
||||
const Onion_Path *path, const Node_format *dest,
|
||||
const uint8_t *public_key, const uint8_t *secret_key,
|
||||
const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data)
|
||||
{
|
||||
uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE];
|
||||
int len = create_announce_request(request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
|
||||
int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
|
||||
client_id, data_public_key, sendback_data);
|
||||
|
||||
if (len != sizeof(request)) {
|
||||
|
@ -200,7 +202,7 @@ int send_announce_request(const Networking_Core *net, const Onion_Path *path, co
|
|||
}
|
||||
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
len = create_onion_packet(packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
|
||||
len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
|
@ -229,19 +231,19 @@ int send_announce_request(const Networking_Core *net, const Onion_Path *path, co
|
|||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_data_request(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *public_key,
|
||||
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
|
||||
int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint8_t request[ONION_MAX_DATA_SIZE];
|
||||
int len = create_data_request(request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
|
||||
int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
len = create_onion_packet(packet, sizeof(packet), path, dest, request, len);
|
||||
len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
|
@ -490,7 +492,7 @@ static int handle_announce_request_common(
|
|||
assert(num_nodes <= UINT8_MAX);
|
||||
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
random_nonce(onion_a->rng, nonce);
|
||||
|
||||
const uint16_t nodes_offset = 1 + ONION_PING_ID_SIZE + (want_node_count ? 1 : 0);
|
||||
const uint16_t response_size = nodes_offset
|
||||
|
@ -648,7 +650,7 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_
|
|||
return 0;
|
||||
}
|
||||
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Mono_Time *mono_time, DHT *dht)
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -661,13 +663,14 @@ Onion_Announce *new_onion_announce(const Logger *log, const Mono_Time *mono_time
|
|||
}
|
||||
|
||||
onion_a->log = log;
|
||||
onion_a->rng = rng;
|
||||
onion_a->mono_time = mono_time;
|
||||
onion_a->dht = dht;
|
||||
onion_a->net = dht_get_net(dht);
|
||||
onion_a->extra_data_max_size = 0;
|
||||
onion_a->extra_data_callback = nullptr;
|
||||
onion_a->extra_data_object = nullptr;
|
||||
new_symmetric_key(onion_a->secret_bytes);
|
||||
new_symmetric_key(rng, onion_a->secret_bytes);
|
||||
|
||||
networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_announce_request, onion_a);
|
||||
networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST_OLD, &handle_announce_request_old, onion_a);
|
||||
|
|
|
@ -57,7 +57,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
|
|||
* return packet length on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
|
||||
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data);
|
||||
|
||||
|
@ -74,7 +74,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
|
|||
* return 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
|
||||
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
|
||||
|
||||
/** @brief Create and send an onion announce request packet.
|
||||
|
@ -92,10 +92,11 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8
|
|||
* return 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
int send_announce_request(const Networking_Core *net, const Onion_Path *path, const Node_format *dest,
|
||||
int send_announce_request(const Networking_Core *net, const Random *rng,
|
||||
const Onion_Path *path, const Node_format *dest,
|
||||
const uint8_t *public_key, const uint8_t *secret_key,
|
||||
const uint8_t *ping_id, const uint8_t *client_id,
|
||||
const uint8_t *data_public_key, uint64_t sendback_data);
|
||||
const uint8_t *data_public_key, uint64_t sendback_data);
|
||||
|
||||
/** @brief Create and send an onion data request packet.
|
||||
*
|
||||
|
@ -114,9 +115,9 @@ int send_announce_request(const Networking_Core *net, const Onion_Path *path, co
|
|||
* return 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
int send_data_request(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *public_key,
|
||||
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
|
||||
int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
|
||||
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
|
||||
const uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
typedef int pack_extra_data_cb(void *object, const Logger *logger, const Mono_Time *mono_time,
|
||||
|
@ -128,10 +129,9 @@ void onion_announce_extra_data_callback(Onion_Announce *onion_a, uint16_t extra_
|
|||
pack_extra_data_cb *extra_data_callback, void *extra_data_object);
|
||||
|
||||
non_null()
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Mono_Time *mono_time, DHT *dht);
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht);
|
||||
|
||||
non_null()
|
||||
void kill_onion_announce(Onion_Announce *onion_a);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -100,6 +100,7 @@ typedef struct Onion_Data_Handler {
|
|||
struct Onion_Client {
|
||||
const Mono_Time *mono_time;
|
||||
const Logger *logger;
|
||||
const Random *rng;
|
||||
|
||||
DHT *dht;
|
||||
Net_Crypto *c;
|
||||
|
@ -278,7 +279,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < max_num; ++i) {
|
||||
const uint32_t rand_idx = random_range_u32(num_nodes);
|
||||
const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes);
|
||||
nodes[i] = onion_c->path_nodes[rand_idx];
|
||||
}
|
||||
} else {
|
||||
|
@ -294,7 +295,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
|
|||
nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
|
||||
|
||||
for (unsigned int i = 1; i < max_num; ++i) {
|
||||
const uint32_t rand_idx = random_range_u32(num_nodes);
|
||||
const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes);
|
||||
nodes[i] = onion_c->path_nodes[rand_idx];
|
||||
}
|
||||
} else {
|
||||
|
@ -309,7 +310,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
|
|||
nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
|
||||
|
||||
for (unsigned int i = 1; i < max_num; ++i) {
|
||||
const uint32_t rand_idx = random_range_u32(num_nodes_bs);
|
||||
const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes_bs);
|
||||
nodes[i] = onion_c->path_nodes_bs[rand_idx];
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +380,7 @@ non_null()
|
|||
static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path)
|
||||
{
|
||||
if (pathnum == UINT32_MAX) {
|
||||
pathnum = random_range_u32(NUMBER_ONION_PATHS);
|
||||
pathnum = random_range_u32(onion_c->rng, NUMBER_ONION_PATHS);
|
||||
} else {
|
||||
pathnum = pathnum % NUMBER_ONION_PATHS;
|
||||
}
|
||||
|
@ -394,7 +395,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
|
|||
const int n = is_path_used(onion_c->mono_time, onion_paths, nodes);
|
||||
|
||||
if (n == -1) {
|
||||
if (create_onion_path(onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) {
|
||||
if (create_onion_path(onion_c->rng, onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -402,7 +403,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
|
|||
onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum];
|
||||
onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2;
|
||||
|
||||
uint32_t path_num = random_u32();
|
||||
uint32_t path_num = random_u32(onion_c->rng);
|
||||
path_num /= NUMBER_ONION_PATHS;
|
||||
path_num *= NUMBER_ONION_PATHS;
|
||||
path_num += pathnum;
|
||||
|
@ -478,7 +479,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
|
|||
{
|
||||
if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
const int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
|
||||
const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
|
@ -493,7 +494,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
|
|||
|
||||
if (net_family_is_tcp_family(path->ip_port1.ip.family)) {
|
||||
uint8_t packet[ONION_MAX_PACKET_SIZE];
|
||||
int len = create_onion_packet_tcp(packet, sizeof(packet), path, dest, data, length);
|
||||
const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
|
||||
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
|
@ -529,7 +530,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ
|
|||
memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, ip_port, sizeof(IP_Port));
|
||||
memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
|
||||
*sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data));
|
||||
*sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data));
|
||||
|
||||
if (*sendback == 0) {
|
||||
return -1;
|
||||
|
@ -604,13 +605,15 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
|
|||
int len;
|
||||
|
||||
if (num == 0) {
|
||||
len = create_announce_request(request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
|
||||
nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
|
||||
onion_c->temp_public_key, sendback);
|
||||
len = create_announce_request(
|
||||
onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
|
||||
nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
|
||||
onion_c->temp_public_key, sendback);
|
||||
} else {
|
||||
len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key,
|
||||
onion_c->friends_list[num - 1].temp_secret_key, ping_id,
|
||||
onion_c->friends_list[num - 1].real_public_key, zero_ping_id, sendback);
|
||||
len = create_announce_request(
|
||||
onion_c->rng, request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key,
|
||||
onion_c->friends_list[num - 1].temp_secret_key, ping_id,
|
||||
onion_c->friends_list[num - 1].real_public_key, zero_ping_id, sendback);
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
|
@ -1098,7 +1101,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
|
|||
}
|
||||
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
random_nonce(onion_c->rng, nonce);
|
||||
|
||||
VLA(uint8_t, packet, DATA_IN_RESPONSE_MIN_SIZE + length);
|
||||
memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
@ -1120,8 +1123,9 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
|
|||
}
|
||||
|
||||
uint8_t o_packet[ONION_MAX_PACKET_SIZE];
|
||||
len = create_data_request(o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
|
||||
node_list[good_nodes[i]].data_public_key, nonce, packet, SIZEOF_VLA(packet));
|
||||
len = create_data_request(
|
||||
onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
|
||||
node_list[good_nodes[i]].data_public_key, nonce, packet, SIZEOF_VLA(packet));
|
||||
|
||||
if (len == -1) {
|
||||
continue;
|
||||
|
@ -1154,7 +1158,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
|
|||
}
|
||||
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
random_nonce(nonce);
|
||||
random_nonce(onion_c->rng, nonce);
|
||||
|
||||
VLA(uint8_t, temp, DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length);
|
||||
memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
@ -1168,8 +1172,9 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
|
|||
}
|
||||
|
||||
uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
|
||||
len = create_request(dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
|
||||
onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK);
|
||||
len = create_request(
|
||||
onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
|
||||
onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK);
|
||||
assert(len <= UINT16_MAX);
|
||||
const Packet packet = {packet_data, (uint16_t)len};
|
||||
|
||||
|
@ -1345,7 +1350,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key)
|
|||
|
||||
onion_c->friends_list[index].is_valid = true;
|
||||
memcpy(onion_c->friends_list[index].real_public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
crypto_new_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key);
|
||||
crypto_new_keypair(onion_c->rng, onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key);
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -1679,7 +1684,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
|
|||
o_friend->last_populated = tm;
|
||||
|
||||
for (uint16_t i = 0; i < n; ++i) {
|
||||
const uint32_t num = random_range_u32(num_nodes);
|
||||
const uint32_t num = random_range_u32(onion_c->rng, num_nodes);
|
||||
client_send_announce_request(onion_c, friendnum + 1, &onion_c->path_nodes[num].ip_port,
|
||||
onion_c->path_nodes[num].public_key, nullptr, -1);
|
||||
}
|
||||
|
@ -1789,7 +1794,7 @@ static void do_announce(Onion_Client *onion_c)
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) {
|
||||
const uint32_t num = random_range_u32(num_nodes);
|
||||
const uint32_t num = random_range_u32(onion_c->rng, num_nodes);
|
||||
client_send_announce_request(onion_c, 0, &path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1);
|
||||
}
|
||||
}
|
||||
|
@ -1920,7 +1925,7 @@ void do_onion_client(Onion_Client *onion_c)
|
|||
onion_c->last_run = mono_time_get(onion_c->mono_time);
|
||||
}
|
||||
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Mono_Time *mono_time, Net_Crypto *c)
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c)
|
||||
{
|
||||
if (c == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -1941,11 +1946,12 @@ Onion_Client *new_onion_client(const Logger *logger, const Mono_Time *mono_time,
|
|||
|
||||
onion_c->mono_time = mono_time;
|
||||
onion_c->logger = logger;
|
||||
onion_c->rng = rng;
|
||||
onion_c->dht = nc_get_dht(c);
|
||||
onion_c->net = dht_get_net(onion_c->dht);
|
||||
onion_c->c = c;
|
||||
new_symmetric_key(onion_c->secret_symmetric_key);
|
||||
crypto_new_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
|
||||
new_symmetric_key(rng, onion_c->secret_symmetric_key);
|
||||
crypto_new_keypair(rng, onion_c->temp_public_key, onion_c->temp_secret_key);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_announce_response, onion_c);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
|
||||
oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
|
||||
|
|
|
@ -197,7 +197,7 @@ non_null()
|
|||
void do_onion_client(Onion_Client *onion_c);
|
||||
|
||||
non_null()
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Mono_Time *mono_time, Net_Crypto *c);
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c);
|
||||
|
||||
non_null()
|
||||
void kill_onion_client(Onion_Client *onion_c);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
struct Ping {
|
||||
const Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
DHT *dht;
|
||||
|
||||
Ping_Array *ping_array;
|
||||
|
@ -60,7 +61,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key
|
|||
uint8_t data[PING_DATA_SIZE];
|
||||
pk_copy(data, public_key);
|
||||
memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, ipp, sizeof(IP_Port));
|
||||
ping_id = ping_array_add(ping->ping_array, ping->mono_time, data, sizeof(data));
|
||||
ping_id = ping_array_add(ping->ping_array, ping->mono_time, ping->rng, data, sizeof(data));
|
||||
|
||||
if (ping_id == 0) {
|
||||
crypto_memzero(shared_key, sizeof(shared_key));
|
||||
|
@ -73,7 +74,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key
|
|||
|
||||
pk[0] = NET_PACKET_PING_REQUEST;
|
||||
pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey
|
||||
random_nonce(pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
|
||||
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
|
||||
|
||||
|
||||
rc = encrypt_data_symmetric(shared_key,
|
||||
|
@ -107,7 +108,7 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_
|
|||
|
||||
pk[0] = NET_PACKET_PING_RESPONSE;
|
||||
pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey
|
||||
random_nonce(pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
|
||||
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
|
||||
|
||||
// Encrypt ping_id using recipient privkey
|
||||
const int rc = encrypt_data_symmetric(shared_encryption_key,
|
||||
|
@ -347,7 +348,7 @@ void ping_iterate(Ping *ping)
|
|||
}
|
||||
|
||||
|
||||
Ping *ping_new(const Mono_Time *mono_time, DHT *dht)
|
||||
Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
{
|
||||
Ping *ping = (Ping *)calloc(1, sizeof(Ping));
|
||||
|
||||
|
@ -363,6 +364,7 @@ Ping *ping_new(const Mono_Time *mono_time, DHT *dht)
|
|||
}
|
||||
|
||||
ping->mono_time = mono_time;
|
||||
ping->rng = rng;
|
||||
ping->dht = dht;
|
||||
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
|
||||
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
typedef struct Ping Ping;
|
||||
|
||||
non_null()
|
||||
Ping *ping_new(const struct Mono_Time *mono_time, DHT *dht);
|
||||
Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht);
|
||||
|
||||
non_null()
|
||||
void ping_kill(Ping *ping);
|
||||
|
|
|
@ -103,8 +103,8 @@ static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_t
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uint8_t *data,
|
||||
uint32_t length)
|
||||
uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Random *rng,
|
||||
const uint8_t *data, uint32_t length)
|
||||
{
|
||||
ping_array_clear_timedout(array, mono_time);
|
||||
const uint32_t index = array->last_added % array->total_size;
|
||||
|
@ -124,7 +124,7 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uin
|
|||
array->entries[index].length = length;
|
||||
array->entries[index].ping_time = mono_time_get(mono_time);
|
||||
++array->last_added;
|
||||
uint64_t ping_id = random_u64();
|
||||
uint64_t ping_id = random_u64(rng);
|
||||
ping_id /= array->total_size;
|
||||
ping_id *= array->total_size;
|
||||
ping_id += index;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mono_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -34,7 +35,7 @@ struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout);
|
|||
* @brief Free all the allocated memory in a @ref Ping_Array.
|
||||
*/
|
||||
non_null()
|
||||
void ping_array_kill(struct Ping_Array *array);
|
||||
void ping_array_kill(Ping_Array *array);
|
||||
|
||||
/**
|
||||
* @brief Add a data with length to the @ref Ping_Array list and return a ping_id.
|
||||
|
@ -42,8 +43,8 @@ void ping_array_kill(struct Ping_Array *array);
|
|||
* @return ping_id on success, 0 on failure.
|
||||
*/
|
||||
non_null()
|
||||
uint64_t ping_array_add(struct Ping_Array *array, const struct Mono_Time *mono_time, const uint8_t *data,
|
||||
uint32_t length);
|
||||
uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Random *rng,
|
||||
const uint8_t *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Check if @p ping_id is valid and not timed out.
|
||||
|
@ -53,7 +54,7 @@ uint64_t ping_array_add(struct Ping_Array *array, const struct Mono_Time *mono_t
|
|||
* @return length of data copied on success, -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
int32_t ping_array_check(struct Ping_Array *array, const struct Mono_Time *mono_time, uint8_t *data, size_t length,
|
||||
int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t *data, size_t length,
|
||||
uint64_t ping_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -50,10 +50,12 @@ TEST(PingArray, StoredDataCanBeRetrieved)
|
|||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new());
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint64_t const ping_id
|
||||
= ping_array_add(arr.get(), mono_time.get(), std::vector<uint8_t>{1, 2, 3, 4}.data(), 4);
|
||||
uint64_t const ping_id = ping_array_add(
|
||||
arr.get(), mono_time.get(), rng, std::vector<uint8_t>{1, 2, 3, 4}.data(), 4);
|
||||
EXPECT_NE(ping_id, 0);
|
||||
|
||||
std::vector<uint8_t> data(4);
|
||||
|
@ -65,10 +67,12 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
|
|||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new());
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint64_t const ping_id
|
||||
= ping_array_add(arr.get(), mono_time.get(), (std::vector<uint8_t>{1, 2, 3, 4}).data(), 4);
|
||||
uint64_t const ping_id = ping_array_add(
|
||||
arr.get(), mono_time.get(), rng, (std::vector<uint8_t>{1, 2, 3, 4}).data(), 4);
|
||||
EXPECT_NE(ping_id, 0);
|
||||
|
||||
std::vector<uint8_t> data(4);
|
||||
|
@ -84,10 +88,12 @@ TEST(PingArray, ZeroLengthDataCanBeAdded)
|
|||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new());
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint8_t c = 0;
|
||||
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c));
|
||||
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c));
|
||||
EXPECT_NE(ping_id, 0);
|
||||
|
||||
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1);
|
||||
|
@ -108,10 +114,12 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce)
|
|||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new());
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint8_t c = 0;
|
||||
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c));
|
||||
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c));
|
||||
EXPECT_NE(ping_id, 0);
|
||||
|
||||
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1);
|
||||
|
@ -122,10 +130,12 @@ TEST(PingArray, PingIdMustMatchOnCheck)
|
|||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(1, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new());
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint8_t c = 0;
|
||||
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c));
|
||||
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c));
|
||||
EXPECT_NE(ping_id, 0);
|
||||
|
||||
uint64_t const bad_ping_id = ping_id == 1 ? 2 : 1;
|
||||
|
|
|
@ -549,6 +549,17 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
|||
m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts));
|
||||
}
|
||||
|
||||
const Random *rng = system_random();
|
||||
|
||||
if (rng == nullptr) {
|
||||
// TODO(iphydf): Not quite right, but similar.
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tox->rng = *rng;
|
||||
tox->mono_time = mono_time_new();
|
||||
|
||||
if (tox->mono_time == nullptr) {
|
||||
|
@ -581,7 +592,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
|||
tox_lock(tox);
|
||||
|
||||
Messenger_Error m_error;
|
||||
tox->m = new_messenger(tox->mono_time, &tox->ns, &m_options, &m_error);
|
||||
tox->m = new_messenger(tox->mono_time, &tox->rng, &tox->ns, &m_options, &m_error);
|
||||
|
||||
if (tox->m == nullptr) {
|
||||
if (m_error == MESSENGER_ERROR_PORT) {
|
||||
|
@ -1117,7 +1128,7 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message
|
|||
if (ret >= 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK);
|
||||
tox_unlock(tox);
|
||||
return ret;
|
||||
return (uint32_t)ret;
|
||||
}
|
||||
|
||||
set_friend_error(tox->m->log, ret, error);
|
||||
|
@ -1140,7 +1151,7 @@ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_F
|
|||
if (ret >= 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK);
|
||||
tox_unlock(tox);
|
||||
return ret;
|
||||
return (uint32_t)ret;
|
||||
}
|
||||
|
||||
set_friend_error(tox->m->log, ret, error);
|
||||
|
@ -1184,7 +1195,8 @@ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox
|
|||
}
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK);
|
||||
return ret;
|
||||
assert(ret >= 0);
|
||||
return (uint32_t)ret;
|
||||
}
|
||||
|
||||
bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key,
|
||||
|
@ -1685,7 +1697,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t
|
|||
|
||||
if (file_id == nullptr) {
|
||||
/* Tox keys are 32 bytes like FILE_ID_LENGTH. */
|
||||
new_symmetric_key(f_id);
|
||||
new_symmetric_key(&tox->rng, f_id);
|
||||
file_id = f_id;
|
||||
}
|
||||
|
||||
|
@ -1840,7 +1852,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error)
|
|||
{
|
||||
assert(tox != nullptr);
|
||||
tox_lock(tox);
|
||||
const int ret = add_groupchat(tox->m->conferences_object, GROUPCHAT_TYPE_TEXT);
|
||||
const int ret = add_groupchat(tox->m->conferences_object, &tox->rng, GROUPCHAT_TYPE_TEXT);
|
||||
tox_unlock(tox);
|
||||
|
||||
if (ret == -1) {
|
||||
|
@ -2382,7 +2394,8 @@ uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Confere
|
|||
}
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_ID_OK);
|
||||
return ret;
|
||||
assert(ret >= 0);
|
||||
return (uint32_t)ret;
|
||||
}
|
||||
|
||||
// TODO(iphydf): Delete in 0.3.0.
|
||||
|
|
|
@ -11,8 +11,10 @@ namespace {
|
|||
|
||||
TEST(ToxEvents, UnpackRandomDataDoesntCrash)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
std::array<uint8_t, 128> data;
|
||||
random_bytes(data.data(), data.size());
|
||||
random_bytes(rng, data.data(), data.size());
|
||||
tox_events_free(tox_events_load(data.data(), data.size()));
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ extern "C" {
|
|||
struct Tox {
|
||||
Messenger *m;
|
||||
Mono_Time *mono_time;
|
||||
Random rng;
|
||||
Network ns;
|
||||
pthread_mutex_t *mutex;
|
||||
|
||||
|
|
|
@ -10,14 +10,15 @@
|
|||
|
||||
namespace {
|
||||
|
||||
static void set_random_name_and_status_message(Tox *tox, uint8_t *name, uint8_t *status_message)
|
||||
static void set_random_name_and_status_message(
|
||||
Tox *tox, const Random *rng, uint8_t *name, uint8_t *status_message)
|
||||
{
|
||||
for (uint16_t i = 0; i < tox_max_name_length(); ++i) {
|
||||
name[i] = random_u08();
|
||||
name[i] = random_u08(rng);
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < tox_max_status_message_length(); ++i) {
|
||||
status_message[i] = random_u08();
|
||||
status_message[i] = random_u08(rng);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,10 +85,12 @@ TEST(Tox, OneTest)
|
|||
|
||||
Tox *tox1 = tox_new(options, nullptr);
|
||||
ASSERT_NE(tox1, nullptr);
|
||||
set_random_name_and_status_message(tox1, name.data(), status_message.data());
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
set_random_name_and_status_message(tox1, rng, name.data(), status_message.data());
|
||||
Tox *tox2 = tox_new(options, nullptr);
|
||||
ASSERT_NE(tox2, nullptr);
|
||||
set_random_name_and_status_message(tox2, name2.data(), status_message2.data());
|
||||
set_random_name_and_status_message(tox2, rng, name2.data(), status_message2.data());
|
||||
|
||||
std::array<uint8_t, TOX_ADDRESS_SIZE> address;
|
||||
tox_self_get_address(tox1, address.data());
|
||||
|
|
|
@ -8,24 +8,28 @@ namespace {
|
|||
|
||||
TEST(Util, TwoRandomIdsAreNotEqual)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk2[CRYPTO_SECRET_KEY_SIZE];
|
||||
|
||||
crypto_new_keypair(pk1, sk1);
|
||||
crypto_new_keypair(pk2, sk2);
|
||||
crypto_new_keypair(rng, pk1, sk1);
|
||||
crypto_new_keypair(rng, pk2, sk2);
|
||||
|
||||
EXPECT_FALSE(pk_equal(pk1, pk2));
|
||||
}
|
||||
|
||||
TEST(Util, IdCopyMakesKeysEqual)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
|
||||
|
||||
crypto_new_keypair(pk1, sk1);
|
||||
crypto_new_keypair(rng, pk1, sk1);
|
||||
pk_copy(pk2, pk1);
|
||||
|
||||
EXPECT_TRUE(pk_equal(pk1, pk2));
|
||||
|
|
|
@ -101,7 +101,7 @@ Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_l
|
|||
Tox_Err_Key_Derivation *error)
|
||||
{
|
||||
uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
random_bytes(salt, sizeof(salt));
|
||||
random_bytes(system_random(), salt, sizeof(salt));
|
||||
return tox_pass_key_derive_with_salt(passphrase, passphrase_len, salt, error);
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *plaintext, siz
|
|||
ciphertext += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
|
||||
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
random_nonce(nonce);
|
||||
random_nonce(system_random(), nonce);
|
||||
memcpy(ciphertext, nonce, crypto_box_NONCEBYTES);
|
||||
ciphertext += crypto_box_NONCEBYTES;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user