summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-04-24 10:53:31 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-04-24 10:56:38 +0300
commit26092086b62afd9bdef93f4756ae7558ec681e9a (patch)
tree56d6a31a681d8c0027e6709a0cd16f29045704b6
parentde9873b0039e8085cb665e0b2ab6946a972e8e3e (diff)
jabber: omemo: improoved 4.4, working on 4.5
fixed few bug in session store implementation improoved session store to avoid possible collisions 4.5 internally done //TODO: wrap all internal data to omemo "MessageElement" and send it
-rwxr-xr-xprotocols/JabberG/src/jabber_omemo.cpp89
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.cpp2
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.h2
3 files changed, 68 insertions, 25 deletions
diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp
index 94fdb1f335..4fdd5e2ee2 100755
--- a/protocols/JabberG/src/jabber_omemo.cpp
+++ b/protocols/JabberG/src/jabber_omemo.cpp
@@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <key_helper.h>
#include <session_builder.h>
#include <session_cipher.h>
+#include <protocol.h>
//c++
#include <cstddef>
@@ -574,6 +575,7 @@ namespace omemo {
struct signal_store_backend_user_data
{
MCONTACT hContact;
+ unsigned int device_id;
CJabberProto *proto;
};
int load_session_func(signal_buffer **record, const signal_protocol_address *address, void *user_data)
@@ -588,6 +590,11 @@ namespace omemo {
* @param address the address of the remote client
* @return 1 if the session was loaded, 0 if the session was not found, negative on failure
*/
+ //some sanity checks
+ if (address->device_id <= 0)
+ return -1;
+ if (address->name_len > 1024)
+ return -1;
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
@@ -845,7 +852,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d", "OmemoSignalSession_", pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d%d", "OmemoSignalSession_", data->device_id, pre_key_id);
DBVARIANT dbv = { 0 };
dbv.type = DBVT_BLOB;
db_get(data->hContact, data->proto->m_szModuleName, setting_name, &dbv);
@@ -874,7 +881,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d", "OmemoSignalSession_", pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d%d", "OmemoSignalSession_", data->device_id, pre_key_id);
db_set_blob(data->hContact, data->proto->m_szModuleName, setting_name, record, (unsigned int)record_len); //TODO: check return value
mir_free(setting_name);
@@ -894,7 +901,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d", "OmemoSignalSession_", pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d%d", "OmemoSignalSession_", data->device_id, pre_key_id);
DBVARIANT dbv = { 0 };
dbv.type = DBVT_BLOB;
db_get(data->hContact, data->proto->m_szModuleName, setting_name, &dbv);
@@ -921,7 +928,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d", "OmemoSignalSession_", pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalPreKey_") + 31, "%s%d%d", "OmemoSignalSession_", data->device_id, pre_key_id);
db_unset(data->hContact, data->proto->m_szModuleName, setting_name);
mir_free(setting_name);
@@ -947,7 +954,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalSignedPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d", "OmemoSignalSignedPreKey_", signed_pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d%d", "OmemoSignalSignedPreKey_", data->device_id, signed_pre_key_id);
DBVARIANT dbv = { 0 };
dbv.type = DBVT_BLOB;
db_get(data->hContact, data->proto->m_szModuleName, setting_name, &dbv);
@@ -977,7 +984,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalSignedPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d", "OmemoSignalSignedPreKey_", signed_pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d%d", "OmemoSignalSignedPreKey_", data->device_id, signed_pre_key_id);
db_set_blob(data->hContact, data->proto->m_szModuleName, setting_name, record, (unsigned int)record_len); //TODO: check return value
mir_free(setting_name);
@@ -997,7 +1004,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalSignedPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d", "OmemoSignalSignedPreKey_", signed_pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d%d", "OmemoSignalSignedPreKey_", data->device_id, signed_pre_key_id);
DBVARIANT dbv = { 0 };
dbv.type = DBVT_BLOB;
db_get(data->hContact, data->proto->m_szModuleName, setting_name, &dbv);
@@ -1024,7 +1031,7 @@ namespace omemo {
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
char *setting_name = (char*)mir_alloc(strlen("OmemoSignalSignedPreKey_") + 32);
- mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d", "OmemoSignalSignedPreKey_", signed_pre_key_id);
+ mir_snprintf(setting_name, strlen("OmemoSignalSignedPreKey_") + 31, "%s%d%d", "OmemoSignalSignedPreKey_", data->device_id, signed_pre_key_id);
db_unset(data->hContact, data->proto->m_szModuleName, setting_name);
mir_free(setting_name);
@@ -1077,9 +1084,10 @@ namespace omemo {
* registration ID, if it was successfully retrieved.
* @return 0 on success, negative on failure
*/
-
+ uint32_t *id = (uint32_t*)mir_alloc(sizeof(uint32_t));
signal_store_backend_user_data* data = (signal_store_backend_user_data*)user_data;
- *registration_id = GetOwnDeviceId(data->proto); //TODO: check it, maybe memory allocation is necessary
+ *id = GetOwnDeviceId(data->proto);
+ registration_id = id;
return 0;
}
@@ -1180,13 +1188,15 @@ namespace omemo {
bool create_session_store(MCONTACT hContact, LPCTSTR device_id, CJabberProto *proto)
{
- sessions_internal[hContact].clear();
+// sessions_internal[hContact].clear();
signal_store_backend_user_data *data[4];
+ unsigned int device_id_int = _wtoi(device_id);
for (int i = 0; i < 4; i++)
{
data[i] = (signal_store_backend_user_data*)mir_alloc(sizeof(signal_store_backend_user_data));
data[i]->hContact = hContact;
data[i]->proto = proto;
+ data[i]->device_id = device_id_int;
}
/* Create the data store context, and add all the callbacks to it */
//TODO: validation of functions return codes
@@ -1238,24 +1248,20 @@ namespace omemo {
/* Instantiate a session_builder for a recipient address. */
char *jid_str = mir_u2a(jid);
int dev_id_int = _wtoi(dev_id);
- signal_protocol_address address =
+ signal_protocol_address *address = (signal_protocol_address*)mir_alloc(sizeof(signal_protocol_address)); //libsignal does not copy structure, so we must allocate one manually, does it free it on exit ?
+ *address =
{
- jid_str,
- mir_strlen(jid_str),
+ jid_str, //will libsignal free arrav for us on exit ?
+ mir_strlen(jid_str),
dev_id_int
};
session_builder *builder;
- if (session_builder_create(&builder, sessions_internal[hContact][dev_id_int].store_context, &address, global_context) < 0)
- {
- mir_free(jid_str);
+ if (session_builder_create(&builder, sessions_internal[hContact][dev_id_int].store_context, address, global_context) < 0)
return false; //failure
- }
sessions_internal[hContact][dev_id_int].builder = builder;
- mir_free(jid_str);
-
int key_id_int = _wtoi(key_id);
char *pre_key_a = mir_u2a(pre_key_public);
@@ -1305,7 +1311,7 @@ namespace omemo {
/* Create the session cipher and encrypt the message */
session_cipher *cipher;
- if (session_cipher_create(&cipher, sessions_internal[hContact][dev_id_int].store_context, &address, global_context) < 0)
+ if (session_cipher_create(&cipher, sessions_internal[hContact][dev_id_int].store_context, address, global_context) < 0)
return false; //failure
sessions_internal[hContact][dev_id_int].cipher = cipher;
@@ -1666,9 +1672,46 @@ void CJabberProto::OmemoOnIqResultGetBundle(HXML iqNode, CJabberIqInfo *pInfo)
}
-void CJabberProto::OmemoEncryptMessage(XmlNode &msg, const wchar_t *msg_text)
+void CJabberProto::OmemoEncryptMessage(XmlNode &msg, const wchar_t *msg_text, MCONTACT hContact)
{
- //TODO:
+ const EVP_CIPHER *cipher = EVP_aes_128_gcm();
+ unsigned char key[16], iv[128];
+ Utils_GetRandom(key, 16);
+ Utils_GetRandom(iv, 128);
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ EVP_EncryptInit(ctx, cipher, key, iv);
+ char *tmp = mir_u2a(msg_text), *out;
+ const int inl = strlen(tmp);
+ int tmp_len = 0, outl;
+ out = (char*)mir_alloc(inl + 16 - 1);
+ for (;;)
+ {
+ EVP_EncryptUpdate(ctx, (unsigned char*)(out + tmp_len), &outl, (unsigned char*)(tmp + tmp_len), inl - tmp_len);
+ tmp_len += outl;
+ if (tmp_len >= inl - 16 + 1)
+ break;
+ }
+ EVP_EncryptFinal(ctx, (unsigned char*)(out + tmp_len), &outl);
+ EVP_CIPHER_CTX_free(ctx);
+ //TODO: check if encryption works properly
+ mir_free(tmp);
+ //TODO: construct "MessageElement" node
+ for (std::map<unsigned int, omemo::omemo_session_jabber_internal_ptrs>::iterator i = omemo::sessions_internal[hContact].begin(), end = omemo::sessions_internal[hContact].end(); i != end; i++) //something wrong with map ...
+ {
+ unsigned int intdev_id = i->first;
+ ciphertext_message *encrypted_key;
+ if (session_cipher_encrypt(i->second.cipher, (uint8_t*)key, 16, &encrypted_key) != SG_SUCCESS)
+ {
+ //TODO: handle encryption error
+ continue;
+ }
+ else
+ {
+ signal_buffer *serialized_encrypted_key = ciphertext_message_get_serialized(encrypted_key);
+ SIGNAL_UNREF(encrypted_key);
+ }
+ }
+ //TODO: add "MessageElement" to msg node
}
bool CJabberProto::OmemoIsEnabled(MCONTACT hContact)
{
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp
index d2ce816639..71e630bd4a 100755
--- a/protocols/JabberG/src/jabber_proto.cpp
+++ b/protocols/JabberG/src/jabber_proto.cpp
@@ -964,7 +964,7 @@ int __cdecl CJabberProto::SendMsg(MCONTACT hContact, int, const char* pszSrc)
if(m_options.UseOMEMO && OmemoIsEnabled(hContact) && !mir_wstrcmp(msgType, L"chat")) //omemo enabled in options, omemo enabled for contact
{
- OmemoEncryptMessage(m, msg);
+ OmemoEncryptMessage(m, msg, hContact);
}
else
{
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h
index 04414012fc..79d4f7d93b 100755
--- a/protocols/JabberG/src/jabber_proto.h
+++ b/protocols/JabberG/src/jabber_proto.h
@@ -344,7 +344,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void OmemoSendBundle();
void OmemoPublishNodes();
bool OmemoCheckSession(MCONTACT hContact);
- void OmemoEncryptMessage(XmlNode &msg, const wchar_t *msg_text);
+ void OmemoEncryptMessage(XmlNode &msg, const wchar_t *msg_text, MCONTACT hContact);
bool OmemoIsEnabled(MCONTACT hContact);
void OmemoOnIqResultGetBundle(HXML iqNode, CJabberIqInfo *pInfo);