summaryrefslogtreecommitdiff
path: root/protocols/WhatsAppWeb/src/utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/WhatsAppWeb/src/utils.cpp')
-rw-r--r--protocols/WhatsAppWeb/src/utils.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/protocols/WhatsAppWeb/src/utils.cpp b/protocols/WhatsAppWeb/src/utils.cpp
index d956471e48..fba42e8b8d 100644
--- a/protocols/WhatsAppWeb/src/utils.cpp
+++ b/protocols/WhatsAppWeb/src/utils.cpp
@@ -7,6 +7,8 @@ Copyright © 2019 George Hazan
#include "stdafx.h"
+#define sharedKey(A, B, C) crypto_scalarmult((unsigned char*)A, (const unsigned char*)B, (const unsigned char*)C)
+
WAUser* WhatsAppProto::FindUser(const char *szId)
{
mir_cslock lck(m_csUsers);
@@ -234,6 +236,31 @@ void WANoise::mixIntoKey(const void *pData, size_t cbLen)
readCounter = writeCounter = 0;
}
+void WANoise::decrypt(const void *pData, size_t cbLen, MBinBuffer &dest)
+{
+ uint8_t iv[12];
+ memset(iv, 0, 8);
+ memcpy(iv + 8, (bInitFinished) ? &readCounter : &writeCounter, sizeof(int));
+
+ uint8_t outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
+
+ int dec_len = 0, final_len = 0;
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, (BYTE *)decKey.data(), iv);
+ for (size_t len = 0; len < cbLen; len += 1024) {
+ size_t portionSize = cbLen - len;
+ EVP_DecryptUpdate(ctx, outbuf, &dec_len, (BYTE*)pData + len, min(portionSize, 1024));
+ if (len == 0)
+ dest.assign(outbuf, dec_len);
+ else
+ dest.append(outbuf, dec_len);
+ }
+ EVP_DecryptFinal_ex(ctx, outbuf, &final_len);
+ if (final_len)
+ dest.append(outbuf, final_len);
+ EVP_CIPHER_CTX_free(ctx);
+}
+
bool WANoise::decodeFrame(const void *pData, size_t cbLen)
{
if (!bInitFinished) {
@@ -243,10 +270,25 @@ bool WANoise::decodeFrame(const void *pData, size_t cbLen)
auto &static_ = msg.serverhello().static_();
auto &payload = msg.serverhello().payload();
+ uint8_t tmp[32];
+
updateHash(ephemeral.c_str(), ephemeral.size());
- mixIntoKey(ephemeral.c_str(), ephemeral.size());
+ sharedKey(tmp, privKey.data(), ephemeral.c_str());
+ mixIntoKey(tmp, sizeof(tmp));
+
+ MBinBuffer decryptedStatic, decryptedCert;
+ decrypt(static_.c_str(), static_.size(), decryptedStatic);
+
+ sharedKey(tmp, privKey.data(), decryptedStatic.data());
+ mixIntoKey(tmp, sizeof(tmp));
+ decrypt(payload.c_str(), payload.size(), decryptedCert);
+
+ proto::CertChain cert; cert.ParseFromArray(decryptedCert.data(), (int)decryptedCert.length());
+ proto::CertChain::NoiseCertificate::Details details; details.ParseFromString(cert.intermediate().details());
+ if (details.issuerserial() != 0)
+ return false;
}
return true;
}
@@ -271,6 +313,11 @@ void WANoise::encodeFrame(const void *pData, size_t cbLen, MBinBuffer &res)
res.append(pData, cbLen);
}
+void WANoise::encrypt(const void *pData, size_t cbLen, MBinBuffer &dest)
+{
+
+}
+
void WANoise::updateHash(const void *pData, size_t cbLen)
{
if (bInitFinished)