Commit ec193b12 authored by Matthieu Tanon's avatar Matthieu Tanon

Match X3DH server upgrade to ignore recipient devices which have no keys on server

parent 8ad1cf1f
......@@ -31,6 +31,8 @@
#include "lime-x3dh-encryption-engine.h"
#include "private.h"
#include <algorithm>
using namespace std;
LINPHONE_BEGIN_NAMESPACE
......@@ -245,6 +247,12 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processOutgoingMessage (
try {
limeManager->encrypt(localDeviceId, recipientUserId, recipients, plainMessage, cipherMessage, [localDeviceId, recipients, cipherMessage, message, result, &errorCode] (lime::CallbackReturn returnCode, string errorMessage) {
if (returnCode == lime::CallbackReturn::success) {
// Ignore device which do not have keys on the X3DH server
// The message will still be sent to them but they will not be able to decrypt it
recipients->erase(remove_if(recipients->begin(), recipients->end(), [](const lime::RecipientData &recipient) {
return recipient.peerStatus == lime::PeerDeviceStatus::fail;
}), recipients->end());
list<Content *> contents;
// ---------------------------------------------- SIPFRAG
......@@ -315,7 +323,6 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processIncomingMessage (
const shared_ptr<AbstractChatRoom> chatRoom = message->getChatRoom();
const string &localDeviceId = chatRoom->getLocalAddress().asString();
const string &recipientUserId = chatRoom->getPeerAddress().getAddressWithoutGruu().asString();
lime::PeerDeviceStatus peerDeviceStatus = lime::PeerDeviceStatus::fail;
const Content *internalContent;
if (!message->getInternalContent().isEmpty())
......@@ -356,7 +363,7 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processIncomingMessage (
}
// Discard incoming messages from unsafe peer devices
peerDeviceStatus = limeManager->get_peerDeviceStatus(senderDeviceId);
lime::PeerDeviceStatus peerDeviceStatus = limeManager->get_peerDeviceStatus(senderDeviceId);
if (peerDeviceStatus == lime::PeerDeviceStatus::unsafe) {
lWarning() << "LIME X3DH discard incoming message from unsafe sender device " << senderDeviceId;
errorCode = 488; // Not Acceptable
......
......@@ -4149,6 +4149,79 @@ static void group_chat_lime_x3dh_send_encrypted_message_with_response_and_compos
lime_x3dh_message_test(TRUE, TRUE);
}
static void group_chat_lime_x3dh_encrypted_message_to_devices_with_and_without_keys (void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_lime_x3dh_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_lime_x3dh_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
int dummy = 0;
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Wait for lime users to be created on X3DH server
wait_for_list(coresList, &dummy, 1, x3dhServerDelay);
// Check encryption status for both participants
BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(marie->lc));
BC_ASSERT_TRUE(linphone_core_lime_x3dh_enabled(pauline->lc));
BC_ASSERT_FALSE(linphone_core_lime_x3dh_enabled(laure->lc));
// Marie creates a new group chat room
const char *initialSubject = "Friends";
LinphoneChatRoom *marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, TRUE);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 2, 0);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, 0);
// Marie sends the message
const char *marieMessage = "Hey ! What's up ?";
_send_message(marieCr, marieMessage);
// Check that Pauline received and decrypted the message
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000));
LinphoneChatMessage *paulineLastMsg = pauline->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(paulineLastMsg))
goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(paulineLastMsg), marieMessage);
LinphoneAddress *marieAddr = linphone_address_new(linphone_core_get_identity(marie->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(marieAddr, linphone_chat_message_get_from_address(paulineLastMsg)));
linphone_address_unref(marieAddr);
// Check that Laure did not receive the message because she did not post keys on the X3DH server
BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, initialLaureStats.number_of_LinphoneMessageReceived + 1, 1000));
end:
// Clean local LIME X3DH databases
linphone_core_delete_local_encryption_db(marie->lc);
linphone_core_delete_local_encryption_db(pauline->lc);
linphone_core_delete_local_encryption_db(laure->lc);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_lime_x3dh_send_encrypted_file_with_or_without_text (bool_t with_text) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_lime_x3dh_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_lime_x3dh_rc");
......@@ -5565,18 +5638,18 @@ static void group_chat_lime_x3dh_send_encrypted_message_to_disabled_lime_x3dh (v
linphone_chat_room_compose(marieCr);
// Check that the IsComposing is undecipherable and that an undecipherable message error IMDN is returned to Marie
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 1000));
// Marie sends the message
const char *marieMessage = "What's up ?";
_send_message(marieCr, marieMessage);
// Check that the message is discarded and that an undecipherable message error IMDN is returned to Marie
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000));
// Check the chatrooms security level
BC_ASSERT_EQUAL(linphone_chat_room_get_security_level(marieCr), LinphoneChatRoomSecurityLevelEncrypted, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_security_level(paulineCr), LinphoneChatRoomSecurityLevelEncrypted, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_security_level(paulineCr), LinphoneChatRoomSecurityLevelClearText, int, "%d");
// Clean local LIME X3DH databases
linphone_core_enable_lime_x3dh(pauline->lc, TRUE);
......@@ -6143,6 +6216,7 @@ test_t group_chat_tests[] = {
TEST_TWO_TAGS("LIME X3DH message with composing", group_chat_lime_x3dh_send_encrypted_message_with_composing, "LimeX3DH", "LeaksMemory"),
TEST_TWO_TAGS("LIME X3DH message with response", group_chat_lime_x3dh_send_encrypted_message_with_response, "LimeX3DH", "LeaksMemory"),
TEST_TWO_TAGS("LIME X3DH message with response and composing", group_chat_lime_x3dh_send_encrypted_message_with_response_and_composing, "LimeX3DH", "LeaksMemory"),
TEST_TWO_TAGS("LIME X3DH message to devices with and without keys on server", group_chat_lime_x3dh_encrypted_message_to_devices_with_and_without_keys, "LimeX3DH", "LeaksMemory"),
TEST_ONE_TAG("LIME X3DH send encrypted file", group_chat_lime_x3dh_send_encrypted_file, "LimeX3DH"),
TEST_ONE_TAG("LIME X3DH send encrypted file + text", group_chat_lime_x3dh_send_encrypted_file_plus_text, "LimeX3DH"),
TEST_TWO_TAGS("LIME X3DH verify SAS before message", group_chat_lime_x3dh_verify_sas_before_message, "LimeX3DH", "LeaksMemory"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment