Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for custom random number generator. #2190

Merged
merged 2 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/flags-gcc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ add_flag -Wenum-compare
add_flag -Wfloat-equal
add_flag -Wformat=2
add_flag -Wframe-address
add_flag -Wframe-larger-than=12400
add_flag -Wframe-larger-than=9000
add_flag -Wignored-attributes
add_flag -Wignored-qualifiers
add_flag -Winit-self
Expand Down
110 changes: 64 additions & 46 deletions auto_tests/TCP_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -81,24 +83,28 @@ 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[TCP_HANDSHAKE_PLAIN_SIZE];
crypto_new_keypair(handshake_plain, t_secret_key);
uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE);
ck_assert(handshake_plain != nullptr);
crypto_new_keypair(rng, handshake_plain, t_secret_key);
memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE);
uint8_t handshake[TCP_CLIENT_HANDSHAKE_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,
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE),
"encrypt_data() call failed.");

free(handshake_plain);

// Sending the handshake
ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
Expand All @@ -109,6 +115,8 @@ static void test_basic(void)
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1,
"The attempt to send the last byte of handshake failed.");

free(handshake);

do_TCP_server_delay(tcp_s, mono_time, 50);

// Receiving server response and decrypting it
Expand Down Expand Up @@ -188,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);
Expand All @@ -197,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);
Expand Down Expand Up @@ -290,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;
Expand Down Expand Up @@ -478,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);
Expand Down Expand Up @@ -530,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.
Expand Down Expand Up @@ -607,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.
Expand Down Expand Up @@ -682,36 +696,38 @@ 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);
ck_assert_msg(connection == 0, "Connection id wrong");
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,
Expand Down Expand Up @@ -789,30 +805,32 @@ 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;
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);
Expand Down
10 changes: 6 additions & 4 deletions auto_tests/conference_av_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 6 additions & 4 deletions auto_tests/conference_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,21 @@ 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;
}

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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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");
Expand Down
Loading