diff options
Diffstat (limited to 'protocols/WhatsApp/src')
| -rw-r--r-- | protocols/WhatsApp/src/crypt.cpp | 6 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/message.cpp | 10 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/proto.h | 1 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/protobuf-c/protobuf-c.h | 2 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/signal.cpp | 44 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/utils.cpp | 13 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/utils.h | 1 | 
7 files changed, 64 insertions, 13 deletions
| diff --git a/protocols/WhatsApp/src/crypt.cpp b/protocols/WhatsApp/src/crypt.cpp index 09a14f53b0..1efb93dde4 100644 --- a/protocols/WhatsApp/src/crypt.cpp +++ b/protocols/WhatsApp/src/crypt.cpp @@ -21,8 +21,10 @@ MBinBuffer aesDecrypt(  	if (additionalLen)  		EVP_DecryptUpdate(ctx, nullptr, &tag_len, (uint8_t *)additionalData, (int)additionalLen); -	dataLen -= 16; -	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (uint8_t *)data + dataLen); +	if (cipher == EVP_aes_256_gcm()) { +		dataLen -= 16; +		EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (uint8_t *)data + dataLen); +	}  	MBinBuffer ret;  	uint8_t outbuf[2000]; diff --git a/protocols/WhatsApp/src/message.cpp b/protocols/WhatsApp/src/message.cpp index 2479ba0458..1397c7c17c 100644 --- a/protocols/WhatsApp/src/message.cpp +++ b/protocols/WhatsApp/src/message.cpp @@ -129,7 +129,14 @@ void WhatsAppProto::OnReceiveMessage(const WANode &node)  			iDecryptable++; +			auto c = msgBody.data() + msgBody.len() - 1; +			if (*c <= 0x10) +				msgBody.reset(msgBody.len() - *c); +  			proto::Message encMsg(msgBody.data(), msgBody.len()); +			if (!encMsg) +				throw "Invalid decoded message"; +  			if (encMsg->devicesentmessage)  				msg.message = encMsg->devicesentmessage->message;  			else @@ -155,7 +162,8 @@ void WhatsAppProto::OnReceiveMessage(const WANode &node)  			SendReceipt(szChatId, pszReceiptTo, msgId, pszReceiptType);  		} -		catch (const char *) { +		catch (const char *pszError) { +			debugLogA("Message decryption failed with error: %s", pszError);  		}  		if (!iDecryptable) { diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index 965fbb7ce6..5f315d3ace 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -169,6 +169,7 @@ public:  	__forceinline session_cipher* getCipher(void) const { return cipher; }  	__forceinline int getDeviceId() const { return address.device_id; } +	CMStringA getSetting() const;  };  class MSignalStore diff --git a/protocols/WhatsApp/src/protobuf-c/protobuf-c.h b/protocols/WhatsApp/src/protobuf-c/protobuf-c.h index 5fa52da626..c66fa000e3 100644 --- a/protocols/WhatsApp/src/protobuf-c/protobuf-c.h +++ b/protocols/WhatsApp/src/protobuf-c/protobuf-c.h @@ -209,6 +209,8 @@ size_t foo__bar__baz_bah__pack_to_buffer  # define PROTOBUF_C__END_DECLS  #endif +#define PROTOBUF_C_UNPACK_ERROR OutputDebugStringA +  PROTOBUF_C__BEGIN_DECLS  #if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB) diff --git a/protocols/WhatsApp/src/signal.cpp b/protocols/WhatsApp/src/signal.cpp index 8207a7462d..1a59fb443b 100644 --- a/protocols/WhatsApp/src/signal.cpp +++ b/protocols/WhatsApp/src/signal.cpp @@ -35,7 +35,7 @@ MSignalStore::~MSignalStore()  void MSignalStore::logError(int err, const char *pszMessage)  {  	if (err < 0) { -		pProto->debugLogA("libsignal error %d: %s", err, pszMessage); +		pProto->debugLogA("libsignal error %d", err);  		throw pszMessage;  	}  } @@ -100,7 +100,8 @@ static int contains_session_func(const signal_protocol_address *address, void *u  	auto *pStore = (MSignalStore *)user_data;  	MSignalSession tmp(CMStringA(address->name, (int)address->name_len), address->device_id); -	return pStore->arSessions.find(&tmp) == nullptr; +	ptrA data(pStore->pProto->getStringA(tmp.getSetting())); +	return data == nullptr;  }  static int delete_all_sessions_func(const char *name, size_t name_len, void *user_data) @@ -111,6 +112,7 @@ static int delete_all_sessions_func(const char *name, size_t name_len, void *use  	int count = 0;  	for (auto &it : pList.rev_iter()) {  		if (it->hasAddress(name, name_len)) { +			pStore->pProto->delSetting(it->getSetting());  			pList.remove(pList.indexOf(&it));  			count++;  		} @@ -125,8 +127,10 @@ int delete_session_func(const signal_protocol_address *address, void *user_data)  	MSignalSession tmp(CMStringA(address->name, (int)address->name_len), address->device_id);  	int idx = pList.getIndex(&tmp); -	if (idx != -1) +	if (idx != -1) { +		pStore->pProto->delSetting(tmp.getSetting());  		pList.remove(idx); +	}  	return 0;  } @@ -156,13 +160,21 @@ int load_session_func(signal_buffer **record, signal_buffer **user_data_storage,  	auto *pStore = (MSignalStore *)user_data;  	MSignalSession tmp(CMStringA(address->name, (int)address->name_len), address->device_id); -	if (auto *pSession = pStore->arSessions.find(&tmp)) { -		*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()); -		return 1; -	} +	auto *pSession = pStore->arSessions.find(&tmp); +	if (pSession == nullptr) { +		ptrA szSession(pStore->pProto->getStringA(tmp.getSetting())); +		if (szSession == nullptr) +			return 0; -	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()); +	} +		 +	*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()); +	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) @@ -178,6 +190,10 @@ 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());	  	return 0;  } @@ -256,6 +272,9 @@ static int load_signed_pre_key(signal_buffer **record, uint32_t signed_pre_key_i  {  	auto *pStore = (MSignalStore *)user_data; +	if (signed_pre_key_id == 0) +		signed_pre_key_id = 1; +  	CMStringA szSetting(FORMAT, "%s%d", "SignedPreKey", signed_pre_key_id);  	MBinBuffer blob(pStore->pProto->getBlob(szSetting));  	if (blob.data() == 0) { @@ -442,6 +461,11 @@ bool MSignalSession::hasAddress(const char *name, size_t name_len) const  	return memcmp(address.name, name, name_len) == 0;  } +CMStringA MSignalSession::getSetting() const +{ +	return CMStringA(FORMAT, "%s_%s_%d", "SignalSession", szName.c_str(), getDeviceId()); +} +  /////////////////////////////////////////////////////////////////////////////////////////  MSignalSession* MSignalStore::createSession(const CMStringA &szName, int deviceId) @@ -575,6 +599,6 @@ void MSignalStore::generatePrekeys(int count)  ///////////////////////////////////////////////////////////////////////////////////////// -void MSignalStore::processSenderKeyMessage(const Wa__Message__SenderKeyDistributionMessage *) +void MSignalStore::processSenderKeyMessage(const Wa__Message__SenderKeyDistributionMessage *msg)  {  } diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp index 592d509253..983a98a3f7 100644 --- a/protocols/WhatsApp/src/utils.cpp +++ b/protocols/WhatsApp/src/utils.cpp @@ -224,6 +224,19 @@ std::string decodeBinStr(const std::string &buf)  	return res;  } +MBinBuffer decodeBufStr(const std::string &buf) +{ +	MBinBuffer res; +	size_t cbLen; +	void *pData = mir_base64_decode(buf.c_str(), &cbLen); +	if (pData == nullptr) +		return res; + +	res.assign(pData, cbLen); +	mir_free(pData); +	return res; +} +  uint32_t decodeBigEndian(const ProtobufCBinaryData &buf)  {  	uint32_t ret = 0; diff --git a/protocols/WhatsApp/src/utils.h b/protocols/WhatsApp/src/utils.h index a3163ad88d..f102c47c2a 100644 --- a/protocols/WhatsApp/src/utils.h +++ b/protocols/WhatsApp/src/utils.h @@ -203,6 +203,7 @@ CMStringA file2string(const wchar_t *pwszFileName);  CMStringA directPath2url(const char *pszDirectPath);  std::string decodeBinStr(const std::string &buf); +MBinBuffer decodeBufStr(const std::string &buf);  MBinBuffer aesDecrypt(  	const EVP_CIPHER *cipher, | 
