Skip to content

Commit

Permalink
Merge moderation portion of new groupchats codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
JFreegman committed Mar 23, 2022
1 parent 2dcb946 commit b696dcc
Show file tree
Hide file tree
Showing 13 changed files with 1,639 additions and 22 deletions.
16 changes: 11 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -229,19 +229,25 @@ set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/friend_requests.c
toxcore/friend_requests.h)

# LAYER 6: Tox messenger
# LAYER 6: DHT based group chats
# ----------------------------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/group_moderation.c
toxcore/group_moderation.h)

# LAYER 7: Tox messenger
# ----------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/Messenger.c
toxcore/Messenger.h)

# LAYER 7: Group chats
# LAYER 8: Conferences
# --------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/group.c
toxcore/group.h)

# LAYER 8: Public API
# LAYER 9: Public API
# -------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/tox_api.c
Expand All @@ -250,7 +256,7 @@ set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/tox_private.h)
set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxcore/tox.h^tox)

# LAYER 9: New async events API
# LAYER 10: New async events API
# -------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/events/conference_connected.c
Expand Down Expand Up @@ -288,7 +294,7 @@ set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxcore/tox
set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${MSGPACK_LIBRARIES})
set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} msgpack)

# LAYER 10: Dispatch recorded events to callbacks.
# LAYER 11: Dispatch recorded events to callbacks.
# -------------------
set(toxcore_SOURCES ${toxcore_SOURCES}
toxcore/tox_dispatch.c
Expand Down
40 changes: 40 additions & 0 deletions toxcore/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@rules_cc//cc:defs.bzl", "cc_test")
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
load("//tools:no_undefined.bzl", "cc_library")

package(features = ["layering_check"])
Expand Down Expand Up @@ -51,6 +52,7 @@ cc_library(
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":ccompat",
"//c-toxcore/testing/fuzzing:fuzz_adapter",
"@libsodium",
],
)
Expand Down Expand Up @@ -121,6 +123,7 @@ cc_library(
],
deps = [
":ccompat",
"//c-toxcore/testing/fuzzing:fuzz_adapter",
"@pthread",
],
)
Expand Down Expand Up @@ -148,6 +151,7 @@ cc_library(
],
deps = [
":attributes",
":ccompat",
":crypto_core",
"@pthread",
],
Expand All @@ -169,6 +173,7 @@ cc_library(
":logger",
":mono_time",
":util",
"//c-toxcore/testing/fuzzing:fuzz_adapter",
"@libsodium",
"@psocket",
"@pthread",
Expand Down Expand Up @@ -461,6 +466,41 @@ cc_library(
],
)

cc_library(
name = "group_moderation",
srcs = ["group_moderation.c"],
hdrs = ["group_moderation.h"],
deps = [
":DHT",
":ccompat",
":crypto_core",
":logger",
":mono_time",
":network",
":util",
"@libsodium",
],
)

cc_test(
name = "group_moderation_test",
size = "small",
srcs = ["group_moderation_test.cc"],
deps = [
":crypto_core",
":group_moderation",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)

cc_fuzz_test(
name = "group_moderation_fuzz_test",
srcs = ["group_moderation_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:group_moderation_fuzz_test"],
deps = [":group_moderation"],
)

cc_library(
name = "Messenger",
srcs = ["Messenger.c"],
Expand Down
12 changes: 7 additions & 5 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -1800,7 +1800,7 @@ 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)) {
|| *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
uint32_t rand_node = random_range_u32(num_nodes);

if ((num_nodes - 1) != rand_node) {
Expand Down Expand Up @@ -1855,8 +1855,8 @@ static void do_Close(DHT *dht)
dht->num_to_bootstrap = 0;

const uint8_t not_killed = do_ping_and_sendnode_requests(
dht, &dht->close_lastgetnodes, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times,
false);
dht, &dht->close_lastgetnodes, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times,
false);

if (not_killed != 0) {
return;
Expand Down Expand Up @@ -2568,7 +2568,8 @@ static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_

/*----------------------------------------------------------------------------------*/

DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled)
DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled,
bool lan_discovery_enabled)
{
if (net == nullptr) {
return nullptr;
Expand Down Expand Up @@ -2761,7 +2762,8 @@ void dht_save(const DHT *dht, uint8_t *data)
}
}

state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num, clients, num), DHT_STATE_TYPE_NODES);
state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num,
clients, num), DHT_STATE_TYPE_NODES);

free(clients);
}
Expand Down
6 changes: 5 additions & 1 deletion toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
extern "C" {
#endif

/* Maximum size of a signature (may be smaller) */
#define SIGNATURE_SIZE CRYPTO_SIGNATURE_SIZE
/** Maximum number of clients stored per friend. */
#define MAX_FRIEND_CLIENTS 8

Expand Down Expand Up @@ -64,6 +66,7 @@ extern "C" {
#define CRYPTO_PACKET_DHTPK 156
#define CRYPTO_PACKET_NAT_PING 254 // NAT ping crypto packet ID.

/* Max size of a packed node for IPV4 and IPV6 respectively */
#define PACKED_NODE_SIZE_IP4 (1 + SIZE_IP4 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE)
#define PACKED_NODE_SIZE_IP6 (1 + SIZE_IP6 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE)

Expand Down Expand Up @@ -467,7 +470,8 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length);

/** Initialize DHT. */
non_null()
DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled);
DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled,
bool lan_discovery_enabled);

non_null()
void kill_dht(DHT *dht);
Expand Down
51 changes: 51 additions & 0 deletions toxcore/crypto_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
#endif

#ifndef VANILLA_NACL
// Need dht because of ENC_SECRET_KEY_SIZE and ENC_PUBLIC_KEY_SIZE
#define ENC_PUBLIC_KEY_SIZE CRYPTO_PUBLIC_KEY_SIZE
#define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE
#endif

//!TOKSTYLE-
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#include "../testing/fuzzing/fuzz_adapter.h"
Expand All @@ -58,6 +64,31 @@ static_assert(CRYPTO_SHA512_SIZE == crypto_hash_sha512_BYTES,
static_assert(CRYPTO_PUBLIC_KEY_SIZE == 32,
"CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_eq to work");

#ifndef VANILLA_NACL
static_assert(CRYPTO_SIGNATURE_SIZE == crypto_sign_BYTES,
"CRYPTO_SIGNATURE_SIZE should be equal to crypto_sign_BYTES");
static_assert(CRYPTO_SIGN_PUBLIC_KEY_SIZE == crypto_sign_PUBLICKEYBYTES,
"CRYPTO_SIGN_PUBLIC_KEY_SIZE should be equal to crypto_sign_PUBLICKEYBYTES");
static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES,
"CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES");
#endif /* VANILLA_NACL */

#ifndef VANILLA_NACL
bool create_extended_keypair(uint8_t *pk, uint8_t *sk)
{
/* create signature key pair */
crypto_sign_keypair(pk + ENC_PUBLIC_KEY_SIZE, sk + ENC_SECRET_KEY_SIZE);

/* convert public signature key to public encryption key */
const int res1 = crypto_sign_ed25519_pk_to_curve25519(pk, pk + ENC_PUBLIC_KEY_SIZE);

/* convert secret signature key to secret encryption key */
const int res2 = crypto_sign_ed25519_sk_to_curve25519(sk, sk + ENC_SECRET_KEY_SIZE);

return res1 == 0 && res2 == 0;
}
#endif

#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
static uint8_t *crypto_malloc(size_t bytes)
{
Expand Down Expand Up @@ -177,6 +208,26 @@ uint32_t random_range_u32(uint32_t upper_bound)
#endif // VANILLA_NACL
}

bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_t message_length,
const uint8_t *secret_key)
{
#ifdef VANILLA_NACL
return false;
#else
return crypto_sign_detached(signature, nullptr, message, message_length, secret_key) == 0;
#endif // VANILLA_NACL
}

bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, uint64_t message_length,
const uint8_t *public_key)
{
#ifdef VANILLA_NACL
return false;
#else
return crypto_sign_verify_detached(signature, message, message_length, public_key) == 0;
#endif
}

bool public_key_valid(const uint8_t *public_key)
{
if (public_key[31] >= 128) { /* Last bit of key is always zero. */
Expand Down
91 changes: 91 additions & 0 deletions toxcore/crypto_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@
extern "C" {
#endif

/**
* The number of bytes in a signature.
*/
#define CRYPTO_SIGNATURE_SIZE 64

/**
* The number of bytes in a Tox public key used for signatures.
*/
#define CRYPTO_SIGN_PUBLIC_KEY_SIZE 32

/**
* The number of bytes in a Tox secret key used for signatures.
*/
#define CRYPTO_SIGN_SECRET_KEY_SIZE 64

/**
* @brief The number of bytes in a Tox public key used for encryption.
*/
Expand Down Expand Up @@ -60,6 +75,41 @@ extern "C" {
*/
#define CRYPTO_SHA512_SIZE 64

/**
* @brief The number of bytes in an encryption public key used by DHT group chats.
*/
#define ENC_PUBLIC_KEY_SIZE CRYPTO_PUBLIC_KEY_SIZE

/**
* @brief The number of bytes in an encryption secret key used by DHT group chats.
*/
#define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE

/**
* @brief The number of bytes in a signature public key.
*/
#define SIG_PUBLIC_KEY_SIZE CRYPTO_SIGN_PUBLIC_KEY_SIZE

/**
* @brief The number of bytes in a signature secret key.
*/
#define SIG_SECRET_KEY_SIZE CRYPTO_SIGN_SECRET_KEY_SIZE

/**
* @brief The number of bytes in a DHT group chat public key identifier.
*/
#define CHAT_ID_SIZE SIG_PUBLIC_KEY_SIZE

/**
* @brief The number of bytes in an extended public key used by DHT group chats.
*/
#define EXT_PUBLIC_KEY_SIZE (ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE)

/**
* @brief The number of bytes in an extended secret key used by DHT group chats.
*/
#define EXT_SECRET_KEY_SIZE (ENC_SECRET_KEY_SIZE + SIG_SECRET_KEY_SIZE)

/**
* @brief A `bzero`-like function which won't be optimised away by the compiler.
*
Expand Down Expand Up @@ -129,6 +179,36 @@ uint64_t random_u64(void);
*/
uint32_t random_range_u32(uint32_t upper_bound);

/** @brief Cryptographically signs a message using the supplied secret key and puts the resulting signature
* in the supplied buffer.
*
* @param signature The buffer for the resulting signature, which must have room for at
* least CRYPTO_SIGNATURE_SIZE bytes.
* @param message The message being signed.
* @param message_length The length in bytes of the message being signed.
* @param secret_key The secret key used to create the signature. The key should be
* produced by either `create_extended_keypair` or the libsodium function `crypto_sign_keypair`.
*
* @retval true on success.
*/
non_null()
bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_t message_length,
const uint8_t *secret_key);

/** @brief Verifies that the given signature was produced by a given message and public key.
*
* @param signature The signature we wish to verify.
* @param message The message we wish to verify.
* @param message_length The length of the message.
* @param public_key The public key counterpart of the secret key that was used to
* create the signature.
*
* @retval true on success.
*/
non_null()
bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, uint64_t message_length,
const uint8_t *public_key);

/**
* @brief Fill the given nonce with random bytes.
*/
Expand All @@ -151,6 +231,17 @@ void random_bytes(uint8_t *bytes, size_t length);
non_null()
bool public_key_valid(const uint8_t *public_key);

/** @brief Creates an extended keypair: curve25519 and ed25519 for encryption and signing
* respectively. The Encryption keys are derived from the signature keys.
*
* @param pk The buffer where the public key will be stored. Must have room for EXT_PUBLIC_KEY_SIZE bytes.
* @param sk The buffer where the secret key will be stored. Must have room for EXT_SECRET_KEY_SIZE bytes.
*
* @retval true on success.
*/
non_null()
bool create_extended_keypair(uint8_t *pk, uint8_t *sk);

/**
* @brief Generate a new random keypair.
*
Expand Down
Loading

0 comments on commit b696dcc

Please sign in to comment.