diff options
Diffstat (limited to 'protocols/WhatsAppWeb')
-rw-r--r-- | protocols/WhatsAppWeb/src/db.h | 7 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/iq.cpp | 5 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/main.cpp | 50 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/noise.cpp | 4 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/proto.h | 7 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/server.cpp | 49 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/signal.cpp | 241 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/stdafx.h | 1 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/utils.cpp | 2 |
9 files changed, 179 insertions, 187 deletions
diff --git a/protocols/WhatsAppWeb/src/db.h b/protocols/WhatsAppWeb/src/db.h index adab0945e7..0686693330 100644 --- a/protocols/WhatsAppWeb/src/db.h +++ b/protocols/WhatsAppWeb/src/db.h @@ -13,12 +13,11 @@ Copyright © 2019-22 George Hazan #define DBKEY_NOISE_PUB "NoisePublicKey" #define DBKEY_NOISE_PRIV "NoisePrivateKey" + #define DBKEY_SIGNED_IDENTITY_PUB "SignedIdentityPublicKey" #define DBKEY_SIGNED_IDENTITY_PRIV "SignedIdentityPrivateKey" -#define DBKEY_PREKEY_PUB "PrekeyPublicKey" -#define DBKEY_PREKEY_PRIV "PrekeyPrivateKey" -#define DBKEY_PREKEY_SIGN "PrekeySignature" -#define DBKEY_PREKEY_KEYID "PrekeyKeyId" + +#define DBKEY_PREKEY "SignedPreKey0" #define DBKEY_PREKEY_NEXT_ID "PrekeyNextId" #define DBKEY_PREKEY_UPLOAD_ID "PrekeyUploadId" diff --git a/protocols/WhatsAppWeb/src/iq.cpp b/protocols/WhatsAppWeb/src/iq.cpp index 07134c0cb8..66545e26ab 100644 --- a/protocols/WhatsAppWeb/src/iq.cpp +++ b/protocols/WhatsAppWeb/src/iq.cpp @@ -148,10 +148,11 @@ void WhatsAppProto::OnReceiveMessage(const WANode &node) bFromMe = m_szJid == participant; auto *pKey = new proto::MessageKey(); - pKey->set_participant(participant); pKey->set_remotejid(szChatId); pKey->set_id(msgId); pKey->set_fromme(bFromMe); + if (participant) + pKey->set_participant(participant); proto::WebMessageInfo msg; msg.set_allocated_key(pKey); @@ -353,7 +354,7 @@ void WhatsAppProto::OnIqPairSuccess(const WANode &node) signal_buffer *result; ec_private_key key = {}; memcpy(key.data, m_signalStore.signedIdentity.priv.data(), m_signalStore.signedIdentity.priv.length()); - if (curve_calculate_signature(g_plugin.pCtx, &result, &key, (BYTE *)buf.data(), buf.length()) != 0) + if (curve_calculate_signature(m_signalStore.CTX(), &result, &key, (BYTE *)buf.data(), buf.length()) != 0) throw "OnIqPairSuccess: cannot calculate account signature, exiting"; account.set_devicesignature(result->data, result->len); diff --git a/protocols/WhatsAppWeb/src/main.cpp b/protocols/WhatsAppWeb/src/main.cpp index 445f22edb3..dc6ac65afe 100644 --- a/protocols/WhatsAppWeb/src/main.cpp +++ b/protocols/WhatsAppWeb/src/main.cpp @@ -45,41 +45,6 @@ CMPlugin::CMPlugin() : ///////////////////////////////////////////////////////////////////////////////////////// // Load -static int hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *) -{ - HMAC_CTX *ctx = HMAC_CTX_new(); - *hmac_context = ctx; - HMAC_Init(ctx, key, (int)key_len, EVP_sha256()); - return 0; -} - -int hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *) -{ - return HMAC_Update((HMAC_CTX *)hmac_context, data, data_len); -} - -int hmac_sha256_final(void *hmac_context, signal_buffer **output, void *) -{ - BYTE data[200]; - unsigned len = 0; - if (!HMAC_Final((HMAC_CTX *)hmac_context, data, &len)) - return 1; - - *output = signal_buffer_create(data, len); - return 0; -} - -void hmac_sha256_cleanup(void *hmac_context, void *) -{ - HMAC_CTX_free((HMAC_CTX *)hmac_context); -} - -static int random_func(uint8_t *pData, size_t size, void *) -{ - Utils_GetRandom(pData, size); - return 0; -} - int CMPlugin::Load() { // InitIcons(); @@ -90,19 +55,6 @@ int CMPlugin::Load() nlu.szSettingsModule = "WhatsApp"; nlu.szDescriptiveName.w = TranslateT("WhatsApp (HTTP)"); hAvatarUser = Netlib_RegisterUser(&nlu); - - ////////////////////////////////////////////////////////////////////////////////////// - signal_context_create(&pCtx, nullptr); - - signal_crypto_provider prov; - memset(&prov, 0xFF, sizeof(prov)); - prov.hmac_sha256_init_func = hmac_sha256_init; - prov.hmac_sha256_final_func = hmac_sha256_final; - prov.hmac_sha256_update_func = hmac_sha256_update; - prov.hmac_sha256_cleanup_func = hmac_sha256_cleanup; - prov.random_func = random_func; - signal_context_set_crypto_provider(pCtx, &prov); - return 0; } @@ -113,7 +65,5 @@ int CMPlugin::Unload() { Netlib_CloseHandle(hAvatarConn); Netlib_CloseHandle(hAvatarUser); - - signal_context_destroy(pCtx); return 0; } diff --git a/protocols/WhatsAppWeb/src/noise.cpp b/protocols/WhatsAppWeb/src/noise.cpp index 4d9dc23956..6a57c8f40e 100644 --- a/protocols/WhatsAppWeb/src/noise.cpp +++ b/protocols/WhatsAppWeb/src/noise.cpp @@ -21,7 +21,7 @@ WANoise::WANoise(WhatsAppProto *_ppro) : // generate ephemeral keys: public & private ec_key_pair *pKeys; - curve_generate_key_pair(g_plugin.pCtx, &pKeys); + curve_generate_key_pair(ppro->m_signalStore.CTX(), &pKeys); auto *pPubKey = ec_key_pair_get_public(pKeys); ephemeral.pub.assign(pPubKey->data, sizeof(pPubKey->data)); @@ -55,7 +55,7 @@ void WANoise::init() // generate noise keys (private & public) ec_key_pair *pKeys; - curve_generate_key_pair(g_plugin.pCtx, &pKeys); + curve_generate_key_pair(ppro->m_signalStore.CTX(), &pKeys); auto *pPubKey = ec_key_pair_get_public(pKeys); db_set_blob(0, ppro->m_szModuleName, DBKEY_NOISE_PUB, pPubKey->data, sizeof(pPubKey->data)); diff --git a/protocols/WhatsAppWeb/src/proto.h b/protocols/WhatsAppWeb/src/proto.h index cbd766ea1c..b7792ec635 100644 --- a/protocols/WhatsAppWeb/src/proto.h +++ b/protocols/WhatsAppWeb/src/proto.h @@ -154,7 +154,8 @@ class MSignalStore { void init(); - signal_protocol_store_context *m_pContext; + signal_context *m_pContext; + signal_protocol_store_context *m_pStore; public: PROTO_INTERFACE *pProto; @@ -177,6 +178,8 @@ public: MSignalStore(PROTO_INTERFACE *_1, const char *_2); ~MSignalStore(); + __forceinline signal_context *CTX() const { return m_pContext; } + MSignalSession *createSession(const CMStringA &szName, int deviceId); MBinBuffer decryptSignalProto(const CMStringA &from, const char *pszType, const MBinBuffer &encrypted); @@ -362,8 +365,6 @@ public: struct CMPlugin : public ACCPROTOPLUGIN<WhatsAppProto> { - signal_context *pCtx = nullptr; - HNETLIBUSER hAvatarUser = nullptr; HNETLIBCONN hAvatarConn = nullptr; bool SaveFile(const char *pszUrl, PROTO_AVATAR_INFORMATION &ai); diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp index f6ca1ef948..57dc3eae50 100644 --- a/protocols/WhatsAppWeb/src/server.cpp +++ b/protocols/WhatsAppWeb/src/server.cpp @@ -90,40 +90,31 @@ void WhatsAppProto::ServerThreadWorker() while (true) { MBinBuffer currPacket; currPacket.assign(netbuf.data() + hdr.headerSize, hdr.payloadSize); - currPacket.append("", 1); // add 0 to use strchr safely - const char *start = currPacket.data(); - switch (hdr.opCode) { case 1: // json packet - case 2: // binary packet - // process a packet here - { - const char *pos = strchr(start, ','); - if (pos != nullptr) - pos++; - else - pos = start; - size_t dataSize = hdr.payloadSize - size_t(pos - start); - - // try to decode - if (hdr.opCode == 2 && hdr.payloadSize > 32) - ProcessBinaryPacket(pos, dataSize); - else { - CMStringA szJson(pos, (int)dataSize); - - JSONNode root = JSONNode::parse(szJson); - if (root) { - debugLogA("JSON received:\n%s", start); - - CMStringA szPrefix(start, int(pos - start - 1)); - auto *pReq = m_arPacketQueue.find((WARequest *)&szPrefix); - if (pReq != nullptr) { - root << CHAR_PARAM("$id$", szPrefix); - } + debugLogA("Text packet, skipping"); + /* + currPacket.append("", 1); // add 0 to use strchr safely + CMStringA szJson(pos, (int)dataSize); + + JSONNode root = JSONNode::parse(szJson); + if (root) { + debugLogA("JSON received:\n%s", start); + + CMStringA szPrefix(start, int(pos - start - 1)); + auto *pReq = m_arPacketQueue.find((WARequest *)&szPrefix); + if (pReq != nullptr) { + root << CHAR_PARAM("$id$", szPrefix); } } } + */ + break; + + case 2: // binary packet + if (hdr.payloadSize > 32) + ProcessBinaryPacket(currPacket.data(), hdr.payloadSize); break; case 8: // close @@ -132,7 +123,7 @@ void WhatsAppProto::ServerThreadWorker() break; default: - Netlib_Dump(m_hServerConn, start, hdr.payloadSize, false, 0); + Netlib_Dump(m_hServerConn, currPacket.data(), hdr.payloadSize, false, 0); } netbuf.remove(hdr.headerSize + hdr.payloadSize); diff --git a/protocols/WhatsAppWeb/src/signal.cpp b/protocols/WhatsAppWeb/src/signal.cpp index b0547f69a8..467572737a 100644 --- a/protocols/WhatsAppWeb/src/signal.cpp +++ b/protocols/WhatsAppWeb/src/signal.cpp @@ -23,81 +23,57 @@ MSignalStore::MSignalStore(PROTO_INTERFACE *_1, const char *_2) : prefix(_2), arSessions(1, &CompareSessions) { - if (pProto->getDword(DBKEY_PREKEY_KEYID, 0xFFFF) == 0xFFFF) { - // generate pre keys - const unsigned int signed_pre_key_id = 1; - pProto->setDword(DBKEY_PREKEY_KEYID, 1); - pProto->setDword(DBKEY_PREKEY_NEXT_ID, 1); - pProto->setDword(DBKEY_PREKEY_UPLOAD_ID, 1); - - // generate signed identity keys (private & public) - ratchet_identity_key_pair *keyPair; - signal_protocol_key_helper_generate_identity_key_pair(&keyPair, g_plugin.pCtx); - - auto *pPubKey = ratchet_identity_key_pair_get_public(keyPair); - db_set_blob(0, pProto->m_szModuleName, DBKEY_SIGNED_IDENTITY_PUB, pPubKey->data, sizeof(pPubKey->data)); - - auto *pPrivKey = ratchet_identity_key_pair_get_private(keyPair); - db_set_blob(0, pProto->m_szModuleName, DBKEY_SIGNED_IDENTITY_PRIV, pPrivKey->data, sizeof(pPrivKey->data)); - - session_signed_pre_key *signed_pre_key; - signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, keyPair, signed_pre_key_id, time(0), g_plugin.pCtx); - SIGNAL_UNREF(keyPair); - - signal_buffer *serialized_signed_pre_key; - session_signed_pre_key_serialize(&serialized_signed_pre_key, signed_pre_key); - - ec_key_pair *pKeys = session_signed_pre_key_get_key_pair(signed_pre_key); - pPubKey = ec_key_pair_get_public(pKeys); - db_set_blob(0, pProto->m_szModuleName, DBKEY_PREKEY_PUB, pPubKey->data, sizeof(pPubKey->data)); + init(); +} - pPrivKey = ec_key_pair_get_private(pKeys); - db_set_blob(0, pProto->m_szModuleName, DBKEY_PREKEY_PRIV, pPrivKey->data, sizeof(pPrivKey->data)); +MSignalStore::~MSignalStore() +{ + signal_protocol_store_context_destroy(m_pStore); + signal_context_destroy(m_pContext); +} - db_set_blob(0, pProto->m_szModuleName, DBKEY_PREKEY_SIGN, (void *)session_signed_pre_key_get_signature(signed_pre_key), (int)session_signed_pre_key_get_signature_len(signed_pre_key)); +///////////////////////////////////////////////////////////////////////////////////////// - // generate and save pre keys set - CMStringA szSetting; - signal_protocol_key_helper_pre_key_list_node *keys_root; - signal_protocol_key_helper_generate_pre_keys(&keys_root, 1, 20, g_plugin.pCtx); - for (auto *it = keys_root; it; it = signal_protocol_key_helper_key_list_next(it)) { - session_pre_key *pre_key = signal_protocol_key_helper_key_list_element(it); - uint32_t pre_key_id = session_pre_key_get_id(pre_key); - { - signal_buffer *serialized_pre_key; - session_pre_key_serialize(&serialized_pre_key, pre_key); - szSetting.Format("PreKey%d", pre_key_id); - db_set_blob(0, pProto->m_szModuleName, szSetting, signal_buffer_data(serialized_pre_key), (unsigned int)signal_buffer_len(serialized_pre_key)); - SIGNAL_UNREF(serialized_pre_key); - } +static void log_func(int level, const char *pmsg, size_t /*msgLen*/, void *pUserData) +{ + auto *pStore = (MSignalStore *)pUserData; + pStore->pProto->debugLogA("libsignal {%d}: %s", level, pmsg); +} - ec_key_pair *pre_key_pair = session_pre_key_get_key_pair(pre_key); - pPubKey = ec_key_pair_get_public(pre_key_pair); - szSetting.Format("PreKey%dPublic", pre_key_id); - db_set_blob(0, pProto->m_szModuleName, szSetting, pPubKey->data, sizeof(pPubKey->data)); - } - signal_protocol_key_helper_key_list_free(keys_root); - } +static int hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *) +{ + HMAC_CTX *ctx = HMAC_CTX_new(); + *hmac_context = ctx; + HMAC_Init(ctx, key, (int)key_len, EVP_sha256()); + return 0; +} - // read resident data from database - signedIdentity.pub = pProto->getBlob(DBKEY_SIGNED_IDENTITY_PUB); - signedIdentity.priv = pProto->getBlob(DBKEY_SIGNED_IDENTITY_PRIV); +static int hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *) +{ + return HMAC_Update((HMAC_CTX *)hmac_context, data, data_len); +} - preKey.pub = pProto->getBlob(DBKEY_PREKEY_PUB); - preKey.priv = pProto->getBlob(DBKEY_PREKEY_PRIV); - preKey.keyid = pProto->getDword(DBKEY_PREKEY_KEYID); - preKey.signature = pProto->getBlob(DBKEY_PREKEY_SIGN); +static int hmac_sha256_final(void *hmac_context, signal_buffer **output, void *) +{ + BYTE data[200]; + unsigned len = 0; + if (!HMAC_Final((HMAC_CTX *)hmac_context, data, &len)) + return 1; - // context cretion - init(); + *output = signal_buffer_create(data, len); + return 0; } -MSignalStore::~MSignalStore() +static void hmac_sha256_cleanup(void *hmac_context, void *) { - signal_protocol_store_context_destroy(m_pContext); + HMAC_CTX_free((HMAC_CTX *)hmac_context); } -///////////////////////////////////////////////////////////////////////////////////////// +static int random_func(uint8_t *pData, size_t size, void *) +{ + Utils_GetRandom(pData, size); + return 0; +} static int contains_session_func(const signal_protocol_address *address, void *user_data) { @@ -228,7 +204,7 @@ static int store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len db_set_blob(0, pStore->pProto->m_szModuleName, szSetting, record, (unsigned int)record_len); session_pre_key *prekey = nullptr; - session_pre_key_deserialize(&prekey, record, record_len, g_plugin.pCtx); //TODO: handle error + session_pre_key_deserialize(&prekey, record, record_len, pStore->CTX()); //TODO: handle error if (prekey) { ec_key_pair *pre_key_pair = session_pre_key_get_key_pair(prekey); signal_buffer *key_buf = nullptr; @@ -248,37 +224,29 @@ static int contains_signed_pre_key(uint32_t signed_pre_key_id, void *user_data) { auto *pStore = (MSignalStore *)user_data; - CMStringA szSetting(FORMAT, "%s_%d", "SignalSignedPreKey", signed_pre_key_id); - DBVARIANT dbv = {}; - dbv.type = DBVT_BLOB; - if (db_get(0, pStore->pProto->m_szModuleName, szSetting, &dbv)) - return 0; - - db_free(&dbv); - return 1; + CMStringA szSetting(FORMAT, "%s%d", "SignedPreKey", signed_pre_key_id); + MBinBuffer blob(pStore->pProto->getBlob(szSetting)); + return blob.data() != 0; } static int load_signed_pre_key(signal_buffer **record, uint32_t signed_pre_key_id, void *user_data) { auto *pStore = (MSignalStore *)user_data; - CMStringA szSetting(FORMAT, "%s_%d", "SignalSignedPreKey", signed_pre_key_id); - DBVARIANT dbv = {}; - dbv.type = DBVT_BLOB; - if (db_get(0, pStore->pProto->m_szModuleName, szSetting, &dbv)) + CMStringA szSetting(FORMAT, "%s%d", "SignedPreKey", signed_pre_key_id); + MBinBuffer blob(pStore->pProto->getBlob(szSetting)); + if (blob.data() == 0) return SG_ERR_INVALID_KEY_ID; - *record = signal_buffer_create(dbv.pbVal, dbv.cpbVal); - db_free(&dbv); + *record = signal_buffer_create(blob.data(), blob.length()); return SG_SUCCESS; //key exist and succesfully loaded - } static int store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len, void *user_data) { auto *pStore = (MSignalStore *)user_data; - CMStringA szSetting(FORMAT, "%s_%d", "SignalSignedPreKey", signed_pre_key_id); + CMStringA szSetting(FORMAT, "%s%d", "SignedPreKey", signed_pre_key_id); db_set_blob(0, pStore->pProto->m_szModuleName, szSetting, record, (unsigned int)record_len); return 0; } @@ -287,33 +255,36 @@ static int remove_signed_pre_key(uint32_t signed_pre_key_id, void *user_data) { auto *pStore = (MSignalStore *)user_data; - CMStringA szSetting(FORMAT, "%s_%d", "SignalSignedPreKey", signed_pre_key_id); + CMStringA szSetting(FORMAT, "%s%d", "SignedPreKey", signed_pre_key_id); pStore->pProto->delSetting(szSetting); return 0; } -int get_identity_key_pair(signal_buffer **public_data, signal_buffer **private_data, void *user_data) +static int get_identity_key_pair(signal_buffer **public_data, signal_buffer **private_data, void *user_data) { auto *pStore = (MSignalStore *)user_data; - *public_data = signal_buffer_create((uint8_t *)pStore->preKey.pub.data(), (int)pStore->preKey.pub.length()); + MBinBuffer buf; + buf.append(KEY_BUNDLE_TYPE, 1); + buf.append(pStore->preKey.pub); + *public_data = signal_buffer_create(buf.data(), (int)buf.length()); + *private_data = signal_buffer_create((uint8_t *)pStore->preKey.priv.data(), (int)pStore->preKey.priv.length()); return 0; } -int get_local_registration_id(void *user_data, uint32_t *registration_id) +static int get_local_registration_id(void *user_data, uint32_t *registration_id) { auto *pStore = (MSignalStore *)user_data; *registration_id = pStore->pProto->getDword(DBKEY_REG_ID); return 0; } -int save_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data) +static int save_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data) { auto *pStore = (MSignalStore *)user_data; CMStringA szSetting(FORMAT, "%s_%s_%d", "SignalIdentity", CMStringA(address->name, (int)address->name_len).c_str(), address->device_id); - if (key_data != nullptr) db_set_blob(0, pStore->pProto->m_szModuleName, szSetting, key_data, (unsigned int)key_len); //TODO: check return value else @@ -321,14 +292,94 @@ int save_identity(const signal_protocol_address *address, uint8_t *key_data, siz return 0; } -int is_trusted_identity(const signal_protocol_address * /*address*/, uint8_t * /*key_data*/, size_t /*key_len*/, void * /*user_data*/) +static int is_trusted_identity(const signal_protocol_address * /*address*/, uint8_t * /*key_data*/, size_t /*key_len*/, void * /*user_data*/) { return 1; } void MSignalStore::init() { - signal_protocol_store_context_create(&m_pContext, g_plugin.pCtx); + signal_context_create(&m_pContext, this); + signal_context_set_log_function(m_pContext, log_func); + + signal_crypto_provider prov; + memset(&prov, 0xFF, sizeof(prov)); + prov.hmac_sha256_init_func = hmac_sha256_init; + prov.hmac_sha256_final_func = hmac_sha256_final; + prov.hmac_sha256_update_func = hmac_sha256_update; + prov.hmac_sha256_cleanup_func = hmac_sha256_cleanup; + prov.random_func = random_func; + signal_context_set_crypto_provider(m_pContext, &prov); + + // default values calculation + if (pProto->getDword(DBKEY_PREKEY_NEXT_ID, 0xFFFF) == 0xFFFF) { + pProto->setDword(DBKEY_PREKEY_NEXT_ID, 1); + pProto->setDword(DBKEY_PREKEY_UPLOAD_ID, 1); + + // generate signed identity keys (private & public) + ratchet_identity_key_pair *keyPair; + signal_protocol_key_helper_generate_identity_key_pair(&keyPair, m_pContext); + + auto *pPubKey = ratchet_identity_key_pair_get_public(keyPair); + db_set_blob(0, pProto->m_szModuleName, DBKEY_SIGNED_IDENTITY_PUB, pPubKey->data, sizeof(pPubKey->data)); + + auto *pPrivKey = ratchet_identity_key_pair_get_private(keyPair); + db_set_blob(0, pProto->m_szModuleName, DBKEY_SIGNED_IDENTITY_PRIV, pPrivKey->data, sizeof(pPrivKey->data)); + + session_signed_pre_key *signed_pre_key; + signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, keyPair, 1, time(0), m_pContext); + SIGNAL_UNREF(keyPair); + + signal_buffer *my_prekey; + session_signed_pre_key_serialize(&my_prekey, signed_pre_key); + db_set_blob(0, pProto->m_szModuleName, DBKEY_PREKEY, my_prekey->data, (int)my_prekey->len); + SIGNAL_UNREF(my_prekey); + + // generate and save pre keys set + CMStringA szSetting; + signal_protocol_key_helper_pre_key_list_node *keys_root; + signal_protocol_key_helper_generate_pre_keys(&keys_root, 1, 20, m_pContext); + for (auto *it = keys_root; it; it = signal_protocol_key_helper_key_list_next(it)) { + session_pre_key *pre_key = signal_protocol_key_helper_key_list_element(it); + uint32_t pre_key_id = session_pre_key_get_id(pre_key); + { + signal_buffer *serialized_pre_key; + session_pre_key_serialize(&serialized_pre_key, pre_key); + szSetting.Format("PreKey%d", pre_key_id); + db_set_blob(0, pProto->m_szModuleName, szSetting, signal_buffer_data(serialized_pre_key), (unsigned int)signal_buffer_len(serialized_pre_key)); + SIGNAL_UNREF(serialized_pre_key); + } + + ec_key_pair *pre_key_pair = session_pre_key_get_key_pair(pre_key); + pPubKey = ec_key_pair_get_public(pre_key_pair); + szSetting.Format("PreKey%dPublic", pre_key_id); + db_set_blob(0, pProto->m_szModuleName, szSetting, pPubKey->data, sizeof(pPubKey->data)); + } + signal_protocol_key_helper_key_list_free(keys_root); + SIGNAL_UNREF(signed_pre_key); + } + + // read resident data from database + signedIdentity.pub = pProto->getBlob(DBKEY_SIGNED_IDENTITY_PUB); + signedIdentity.priv = pProto->getBlob(DBKEY_SIGNED_IDENTITY_PRIV); + + MBinBuffer blob(pProto->getBlob(DBKEY_PREKEY)); + session_signed_pre_key *signed_pre_key; + session_signed_pre_key_deserialize(&signed_pre_key, blob.data(), blob.length(), m_pContext); + + ec_key_pair *pKeys = session_signed_pre_key_get_key_pair(signed_pre_key); + auto *pPubKey = ec_key_pair_get_public(pKeys); + preKey.pub.assign(pPubKey->data, sizeof(pPubKey->data)); + + auto *pPrivKey = ec_key_pair_get_private(pKeys); + preKey.priv.assign(pPrivKey->data, sizeof(pPrivKey->data)); + + preKey.signature.assign(session_signed_pre_key_get_signature(signed_pre_key), session_signed_pre_key_get_signature_len(signed_pre_key)); + preKey.keyid = session_signed_pre_key_get_id(signed_pre_key); + SIGNAL_UNREF(signed_pre_key); + + // create store with callbacks + signal_protocol_store_context_create(&m_pStore, m_pContext); signal_protocol_session_store ss; ss.contains_session_func = &contains_session_func; @@ -339,7 +390,7 @@ void MSignalStore::init() ss.load_session_func = &load_session_func; ss.store_session_func = &store_session_func; ss.user_data = this; - signal_protocol_store_context_set_session_store(m_pContext, &ss); + signal_protocol_store_context_set_session_store(m_pStore, &ss); signal_protocol_pre_key_store sp; sp.contains_pre_key = &contains_pre_key; @@ -348,7 +399,7 @@ void MSignalStore::init() sp.remove_pre_key = &remove_pre_key; sp.store_pre_key = &store_pre_key; sp.user_data = this; - signal_protocol_store_context_set_pre_key_store(m_pContext, &sp); + signal_protocol_store_context_set_pre_key_store(m_pStore, &sp); signal_protocol_signed_pre_key_store ssp; ssp.contains_signed_pre_key = &contains_signed_pre_key; @@ -357,7 +408,7 @@ void MSignalStore::init() ssp.remove_signed_pre_key = &remove_signed_pre_key; ssp.store_signed_pre_key = &store_signed_pre_key; ssp.user_data = this; - signal_protocol_store_context_set_signed_pre_key_store(m_pContext, &ssp); + signal_protocol_store_context_set_signed_pre_key_store(m_pStore, &ssp); signal_protocol_identity_key_store sip; sip.destroy_func = &destroy_func; @@ -366,7 +417,7 @@ void MSignalStore::init() sip.is_trusted_identity = &is_trusted_identity; sip.save_identity = &save_identity; sip.user_data = this; - signal_protocol_store_context_set_identity_key_store(m_pContext, &sip); + signal_protocol_store_context_set_identity_key_store(m_pStore, &sip); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -403,7 +454,7 @@ MSignalSession *MSignalStore::createSession(const CMStringA &szName, int deviceI } if (pSession->cipher == nullptr) - if (session_cipher_create(&pSession->cipher, m_pContext, &pSession->address, g_plugin.pCtx) < 0) + if (session_cipher_create(&pSession->cipher, m_pStore, &pSession->address, m_pContext) < 0) throw "session_cipher_create failure"; return pSession; @@ -423,7 +474,7 @@ MBinBuffer MSignalStore::decryptSignalProto(const CMStringA &from, const char *p memcpy(&pIdentityKey.data, signedIdentity.pub.data(), 32); pre_key_signal_message *pMsg; - if (pre_key_signal_message_deserialize(&pMsg, (BYTE *)encrypted.data(), encrypted.length(), g_plugin.pCtx) < 0) + if (pre_key_signal_message_deserialize(&pMsg, (BYTE *)encrypted.data(), encrypted.length(), m_pContext) < 0) throw "unable to deserialize prekey message"; if (session_cipher_decrypt_pre_key_signal_message(pSession->getCipher(), pMsg, 0, &result) < 0) @@ -433,7 +484,7 @@ MBinBuffer MSignalStore::decryptSignalProto(const CMStringA &from, const char *p } else { signal_message *pMsg; - if (signal_message_deserialize(&pMsg, (BYTE *)encrypted.data(), encrypted.length(), g_plugin.pCtx) < 0) + if (signal_message_deserialize(&pMsg, (BYTE *)encrypted.data(), encrypted.length(), m_pContext) < 0) throw "unable to deserialize signal message"; if (session_cipher_decrypt_signal_message(pSession->getCipher(), pMsg, 0, &result) < 0) diff --git a/protocols/WhatsAppWeb/src/stdafx.h b/protocols/WhatsAppWeb/src/stdafx.h index 29a708c101..bbcda15825 100644 --- a/protocols/WhatsAppWeb/src/stdafx.h +++ b/protocols/WhatsAppWeb/src/stdafx.h @@ -105,6 +105,5 @@ struct ec_private_key : public signal_type_base #include "utils.h" #include "proto.h" #include "resource.h" -#include "pmsg.pb.h" #pragma comment(lib, "libcrypto.lib") diff --git a/protocols/WhatsAppWeb/src/utils.cpp b/protocols/WhatsAppWeb/src/utils.cpp index fdf2721c17..c2b62ca5a1 100644 --- a/protocols/WhatsAppWeb/src/utils.cpp +++ b/protocols/WhatsAppWeb/src/utils.cpp @@ -42,7 +42,7 @@ WAJid::WAJid(const char *pszJid) } bool WAJid::isUser() const -{ return server == S_WHATSAPP_NET; +{ return server == "s.whatsapp.net"; } bool WAJid::isGroup() const |