diff options
-rw-r--r-- | libs/libsignal/src/signal.def | 8 | ||||
-rw-r--r-- | protocols/WhatsApp/src/message.cpp | 2 | ||||
-rw-r--r-- | protocols/WhatsApp/src/proto.h | 4 | ||||
-rw-r--r-- | protocols/WhatsApp/src/signal.cpp | 75 | ||||
-rw-r--r-- | utils/mir_signal.h | 2 |
5 files changed, 74 insertions, 17 deletions
diff --git a/libs/libsignal/src/signal.def b/libs/libsignal/src/signal.def index b08db777b4..6d8c86827d 100644 --- a/libs/libsignal/src/signal.def +++ b/libs/libsignal/src/signal.def @@ -22,6 +22,9 @@ EXPORTS fingerprint_generator_create_for fingerprint_generator_free fingerprint_get_displayable + group_session_builder_create + group_session_builder_free + group_session_builder_process_session hkdf_create hkdf_destroy hkdf_expand @@ -30,6 +33,11 @@ EXPORTS pre_key_signal_message_get_pre_key_id ratchet_identity_key_pair_get_private ratchet_identity_key_pair_get_public + sender_key_distribution_message_deserialize + sender_key_distribution_message_destroy + sender_key_record_create + sender_key_record_destroy + sender_key_record_serialize session_builder_create session_builder_free session_builder_process_pre_key_bundle diff --git a/protocols/WhatsApp/src/message.cpp b/protocols/WhatsApp/src/message.cpp index 0a9a1e557e..3ae999fcd2 100644 --- a/protocols/WhatsApp/src/message.cpp +++ b/protocols/WhatsApp/src/message.cpp @@ -139,7 +139,7 @@ void WhatsAppProto::OnReceiveMessage(const WANode &node) msg.message = encMsg; if (encMsg->senderkeydistributionmessage) - m_signalStore.processSenderKeyMessage(encMsg->senderkeydistributionmessage); + m_signalStore.processSenderKeyMessage(szAuthor, encMsg->senderkeydistributionmessage); ProcessMessage(type, msg); diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index db86428a28..96a0800b77 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -152,7 +152,7 @@ class MSignalSession : public MZeroedObject public: CMStringA szName; - MBinBuffer sessionData, userData; + MBinBuffer sessionData; MSignalSession(const CMStringA &_1, int _2); ~MSignalSession(); @@ -206,7 +206,7 @@ public: void logError(int code, const char *szMessage); - void processSenderKeyMessage(const Wa__Message__SenderKeyDistributionMessage *msg); + void processSenderKeyMessage(const CMStringA &author, const Wa__Message__SenderKeyDistributionMessage *msg); }; class WhatsAppProto : public PROTO<WhatsAppProto> diff --git a/protocols/WhatsApp/src/signal.cpp b/protocols/WhatsApp/src/signal.cpp index 3459aa5a08..fed694f12e 100644 --- a/protocols/WhatsApp/src/signal.cpp +++ b/protocols/WhatsApp/src/signal.cpp @@ -174,22 +174,20 @@ int load_session_func(signal_buffer **record, signal_buffer **user_data_storage, MSignalSession tmp(CMStringA(address->name, (int)address->name_len), address->device_id); auto *pSession = pStore->arSessions.find(&tmp); if (pSession == nullptr) { - ptrA szSession(pStore->pProto->getStringA(tmp.getSetting())); - if (szSession == nullptr) + MBinBuffer blob(pStore->pProto->getBlob(tmp.getSetting())); + if (blob.data() == nullptr) return 0; - JSONNode root = JSONNode::parse(szSession); pSession = new MSignalSession(tmp); - pSession->sessionData = decodeBufStr(root["data"].as_string()); - pSession->userData = decodeBufStr(root["user"].as_string()); + pSession->sessionData.assign(blob.data(), blob.length()); } *record = signal_buffer_create((uint8_t *)pSession->sessionData.data(), pSession->sessionData.length()); - *user_data_storage = signal_buffer_create((uint8_t *)pSession->userData.data(), pSession->userData.length()); + *user_data_storage = 0; return 1; } -static int store_session_func(const signal_protocol_address *address, uint8_t *record, size_t record_len, uint8_t *user_record, size_t user_record_len, void *user_data) +static int store_session_func(const signal_protocol_address *address, uint8_t *record, size_t record_len, uint8_t *, size_t, void *user_data) { auto *pStore = (MSignalStore *)user_data; @@ -201,11 +199,7 @@ static int store_session_func(const signal_protocol_address *address, uint8_t *r } pSession->sessionData.assign(record, record_len); - pSession->userData.assign(user_record, user_record_len); - - JSONNode root; - root << CHAR_PARAM("data", ptrA(mir_base64_encode(record, record_len))) << CHAR_PARAM("user", ptrA(mir_base64_encode(user_record, user_record_len))); - pStore->pProto->setString(pSession->getSetting(), root.write().c_str()); + db_set_blob(0, pStore->pProto->m_szModuleName, pSession->getSetting(), record, (unsigned)record_len); return 0; } @@ -353,6 +347,28 @@ static int is_trusted_identity(const signal_protocol_address * /*address*/, uint return 1; } +static int load_sender_key(signal_buffer **record, signal_buffer **, const signal_protocol_sender_key_name *skn, void *user_data) +{ + auto *pStore = (MSignalStore *)user_data; + + CMStringA szSetting(FORMAT, "SenderKey_%*s_%*s_%d", (unsigned)skn->group_id_len, skn->group_id, (unsigned)skn->sender.name_len, skn->sender.name, skn->sender.device_id); + MBinBuffer blob(pStore->pProto->getBlob(szSetting)); + if (blob.data() == 0) + return 0; + + *record = signal_buffer_create(blob.data(), blob.length()); + return 1; +} + +static int store_sender_key(const signal_protocol_sender_key_name *skn, uint8_t *record, size_t record_len, uint8_t*, size_t, void *user_data) +{ + auto *pStore = (MSignalStore *)user_data; + + CMStringA szSetting(FORMAT, "SenderKey_%*s_%*s_%d", (unsigned)skn->group_id_len, skn->group_id, (unsigned)skn->sender.name_len, skn->sender.name, skn->sender.device_id); + db_set_blob(0, pStore->pProto->m_szModuleName, szSetting, record, (unsigned)record_len); + return 0; +} + void MSignalStore::init() { signal_context_create(&m_pContext, this); @@ -432,6 +448,13 @@ void MSignalStore::init() sp.user_data = this; signal_protocol_store_context_set_pre_key_store(m_pStore, &sp); + signal_protocol_sender_key_store sk; + sk.destroy_func = destroy_func; + sk.load_sender_key = load_sender_key; + sk.store_sender_key = store_sender_key; + sk.user_data = this; + signal_protocol_store_context_set_sender_key_store(m_pStore, &sk); + signal_protocol_signed_pre_key_store ssp; ssp.contains_signed_pre_key = &contains_signed_pre_key; ssp.destroy_func = &destroy_func; @@ -476,7 +499,7 @@ bool MSignalSession::hasAddress(const char *name, size_t name_len) const CMStringA MSignalSession::getSetting() const { - return CMStringA(FORMAT, "%s_%s_%d", "SignalSession", szName.c_str(), getDeviceId()); + return CMStringA(FORMAT, "SignalSession_%s_%d", szName.c_str(), getDeviceId()); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -621,6 +644,30 @@ void MSignalStore::generatePrekeys(int count) ///////////////////////////////////////////////////////////////////////////////////////// -void MSignalStore::processSenderKeyMessage(const Wa__Message__SenderKeyDistributionMessage *) +void MSignalStore::processSenderKeyMessage(const CMStringA &author, const Wa__Message__SenderKeyDistributionMessage *msg) { + WAJid jid(author); + signal_protocol_sender_key_name senderKeyName; + senderKeyName.group_id = msg->groupid; + senderKeyName.group_id_len = mir_strlen(msg->groupid); + senderKeyName.sender.device_id = 0; + senderKeyName.sender.name = jid.user.c_str(); + senderKeyName.sender.name_len = jid.user.GetLength(); + + group_session_builder *builder; + logError( + group_session_builder_create(&builder, m_pStore, m_pContext), + "unable to create session builder"); + + sender_key_distribution_message *skmsg; + logError( + sender_key_distribution_message_deserialize(&skmsg, msg->axolotlsenderkeydistributionmessage.data, msg->axolotlsenderkeydistributionmessage.len, m_pContext), + "unable to decode skdm builder"); + + logError( + group_session_builder_process_session(builder, &senderKeyName, skmsg), + "unable to process skdm"); + + sender_key_distribution_message_destroy((signal_type_base *)skmsg); + group_session_builder_free(builder); } diff --git a/utils/mir_signal.h b/utils/mir_signal.h index 1f94a9263c..f8fd9a01c2 100644 --- a/utils/mir_signal.h +++ b/utils/mir_signal.h @@ -8,6 +8,8 @@ extern "C" { #include "../libs/libsignal/src/curve.h" #include "../libs/libsignal/src/hkdf.h" + #include "../libs/libsignal/src/group_cipher.h" + #include "../libs/libsignal/src/group_session_builder.h" #include "../libs/libsignal/src/key_helper.h" #include "../libs/libsignal/src/protocol.h" #include "../libs/libsignal/src/session_builder.h" |