Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Add libfuzzer integration for libsignal-protocol-c #142

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
20 changes: 20 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,23 @@ add_test(test_fingerprint ${TEST_PATH}/test_fingerprint)
add_executable(test_device_consistency test_device_consistency.c ${common_SRCS})
target_link_libraries(test_device_consistency ${LIBS})
add_test(test_device_consistency ${TEST_PATH}/test_device_consistency)

# Build the fuzzer executable
find_package(Check 0.9.10 REQUIRED)
find_package(OpenSSL 1.0 REQUIRED)
set(LIBS
${CHECK_LDFLAGS}
${OPENSSL_LIBRARIES}
signal-protocol-c
)
add_executable(fuzzer "fuzz_target.c" "test_common_openssl.c")
target_link_libraries(fuzzer ${LIBS})
set_target_properties(fuzzer
PROPERTIES COMPILE_FLAGS "-fsanitize=fuzzer-no-link,address"
)
set_target_properties(fuzzer
PROPERTIES LINK_FLAGS "-fsanitize=fuzzer,address -z muldefs"
)

# And run it for 2048 iterations as part of the test suite (should take at most a few seconds) to ensure it works
add_test(test_fuzzer ${TEST_PATH}/fuzzer -use_value_profile=1 -use_memmem=1 -use_cmp=1 -runs=2048)
137 changes: 137 additions & 0 deletions tests/fuzz_target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include "../src/protocol.c"
#include "../src/protocol.h"
#include "../src/session_builder.h"
#include "../src/session_cipher.h"
#include "../src/signal_protocol.h"
#include "test_common.c"
#include "test_common.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <time.h>

signal_context *global_context;

static signal_protocol_address alice_address = {"+14159998888", 12, 1};

ec_key_pair *bob_signed_pre_key;
int32_t bob_signed_pre_key_id;

// Fuzz the decrypt routine with Data and Size
extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
int result = 0;

// Create a new context
result = signal_context_create(&global_context, 0);
assert(result == 0);

// Set up a test crypto provider using OpenSSL
setup_test_crypto_provider(global_context);

// Create Bob's data store
signal_protocol_store_context *bob_store = 0;
setup_test_store_context(&bob_store, global_context);

// Register Bob
uint32_t bob_local_registration_id = 0;
result = signal_protocol_identity_get_local_registration_id(
bob_store, &bob_local_registration_id);
assert(result == 0);

// Create his keys
ec_key_pair *bob_pre_key_pair = 0;
result = curve_generate_key_pair(global_context, &bob_pre_key_pair);
assert(result == 0);

ec_key_pair *bob_signed_pre_key_pair = 0;
result = curve_generate_key_pair(global_context, &bob_signed_pre_key_pair);
assert(result == 0);

ratchet_identity_key_pair *bob_identity_key_pair = 0;
result = signal_protocol_identity_get_key_pair(bob_store, &bob_identity_key_pair);
assert(result == 0);

signal_buffer *bob_signed_pre_key_public_serialized = 0;
result = ec_public_key_serialize(&bob_signed_pre_key_public_serialized,
ec_key_pair_get_public(bob_signed_pre_key_pair));
assert(result == 0);

signal_buffer *bob_signed_pre_key_signature = 0;
result = curve_calculate_signature(
global_context, &bob_signed_pre_key_signature,
ratchet_identity_key_pair_get_private(bob_identity_key_pair),
signal_buffer_data(bob_signed_pre_key_public_serialized),
signal_buffer_len(bob_signed_pre_key_public_serialized));
assert(result == 0);

session_pre_key_bundle *bob_pre_key = 0;
result = session_pre_key_bundle_create(
&bob_pre_key, bob_local_registration_id,
1, /* device ID */
31337, /* pre key ID */
ec_key_pair_get_public(bob_pre_key_pair),
22, /* signed pre key ID */
ec_key_pair_get_public(bob_signed_pre_key_pair),
signal_buffer_data(bob_signed_pre_key_signature),
signal_buffer_len(bob_signed_pre_key_signature),
ratchet_identity_key_pair_get_public(bob_identity_key_pair));
assert(result == 0);

// And add Bob's pre keys to his data store
session_pre_key *bob_pre_key_record = 0;
result = session_pre_key_create(
&bob_pre_key_record, session_pre_key_bundle_get_pre_key_id(bob_pre_key),
bob_pre_key_pair);
assert(result == 0);

result = signal_protocol_pre_key_store_key(bob_store, bob_pre_key_record);
assert(result == 0);

session_signed_pre_key *bob_signed_pre_key_record = 0;
result = session_signed_pre_key_create(
&bob_signed_pre_key_record, 22, time(0), bob_signed_pre_key_pair,
signal_buffer_data(bob_signed_pre_key_signature),
signal_buffer_len(bob_signed_pre_key_signature));
assert(result == 0);

result = signal_protocol_signed_pre_key_store_key(bob_store,
bob_signed_pre_key_record);
assert(result == 0);

session_cipher *bob_session_cipher = 0;
result = session_cipher_create(&bob_session_cipher, bob_store, &alice_address,
global_context);
assert(result == 0);

// Start of the actual fuzzing, attempt to deserialize the input data
pre_key_signal_message *incoming_message_bad = 0;
result = pre_key_signal_message_deserialize(
&incoming_message_bad, Data, Size, global_context);
if (result != 0) {
goto done;
}

// And if it deserialized okay, then decrypt it
signal_buffer *plaintext = 0;
result = session_cipher_decrypt_pre_key_signal_message(
bob_session_cipher, incoming_message_bad, 0, &plaintext);

// Then free everything
signal_buffer_free(plaintext);
done:
session_cipher_free(bob_session_cipher);
SIGNAL_UNREF(incoming_message_bad);
SIGNAL_UNREF(bob_pre_key);
SIGNAL_UNREF(bob_pre_key_pair);
SIGNAL_UNREF(bob_signed_pre_key_pair);
SIGNAL_UNREF(bob_identity_key_pair);
SIGNAL_UNREF(bob_signed_pre_key_record);
SIGNAL_UNREF(bob_pre_key_record);
signal_buffer_free(bob_signed_pre_key_public_serialized);
signal_buffer_free(bob_signed_pre_key_signature);
signal_protocol_store_context_destroy(bob_store);
signal_context_destroy(global_context);

return 0;
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�b��
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3!�u��$7�#�J��Lq�UpEς׫�.��N!Tl�'�����R��{���D��6|�F��f�"#1�|������& 5ē���<��@@���R��{��}0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
p33
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
p
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:x
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
>07
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
��
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/�
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�������������������������������������������������������������������������������������������������������������������������*
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1c
3 changes: 2 additions & 1 deletion tests/test_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <check.h>
#include <assert.h>

#include "../src/signal_protocol.h"
#include "curve.h"
Expand Down Expand Up @@ -169,7 +170,7 @@ void setup_test_store_context(signal_protocol_store_context **context, signal_co

signal_protocol_store_context *store_context = 0;
result = signal_protocol_store_context_create(&store_context, global_context);
ck_assert_int_eq(result, 0);
assert(result == 0);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swapped to assert in this one case so that this setup function can be used by the fuzzer which is not running as part of a check test suite.


setup_test_session_store(store_context);
setup_test_pre_key_store(store_context);
Expand Down