From 869f7daa30b8cedf40e727e37a3498b58c69c9b5 Mon Sep 17 00:00:00 2001 From: adityapk00 Date: Thu, 24 Jan 2019 21:28:40 -0800 Subject: [PATCH] Add nonce checks --- src/websockets.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++---- src/websockets.h | 8 ++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/websockets.cpp b/src/websockets.cpp index 41bf3c3..e9e583d 100644 --- a/src/websockets.cpp +++ b/src/websockets.cpp @@ -73,6 +73,33 @@ void WSServer::socketDisconnected() // ============================== // AppDataServer // ============================== +QString AppDataServer::getSecretHex() { + return "secret"; +} + +QString AppDataServer::getNonceHex(NonceType nt) { + QSettings s; + QString hex; + if (nt == NonceType::LOCAL) { + hex = s.value("mobileapp/localnonce", QString("00").repeated(crypto_secretbox_NONCEBYTES)).toString(); + } + else { + hex = s.value("mobileapp/remotenonce", QString("00").repeated(crypto_secretbox_NONCEBYTES)).toString(); + } + return hex; +} + +void AppDataServer::saveNonceHex(NonceType nt, QString noncehex) { + QSettings s; + assert(noncehex.length() == crypto_secretbox_NONCEBYTES * 2); + if (nt == NonceType::LOCAL) { + s.setValue("mobileapp/localnonce", noncehex); + } + else { + s.setValue("mobileapp/remotenonce", noncehex); + } +} + QJsonDocument AppDataServer::processMessage(QString message, MainWindow* mainWindow) { // First, extract the command from the message auto msg = QJsonDocument::fromJson(message.toUtf8()); @@ -83,15 +110,25 @@ QJsonDocument AppDataServer::processMessage(QString message, MainWindow* mainWin QString noncehex = msg.object().value("nonce").toString(); QString encryptedhex = msg.object().value("payload").toString(); + // Check to make sure that the nonce is greater than the last known remote nonce + QString lastRemoteHex = getNonceHex(NonceType::REMOTE); + unsigned char* lastRemoteBin = new unsigned char[crypto_secretbox_NONCEBYTES]; + sodium_hex2bin(lastRemoteBin, crypto_secretbox_NONCEBYTES, lastRemoteHex.toStdString().c_str(), lastRemoteHex.length(), + NULL, NULL, NULL); + + unsigned char* noncebin = new unsigned char[crypto_secretbox_NONCEBYTES]; + sodium_hex2bin(noncebin, crypto_secretbox_NONCEBYTES, noncehex.toStdString().c_str(), noncehex.length(), + NULL, NULL, NULL); + + assert(sodium_compare(lastRemoteBin, noncebin, crypto_secretbox_NONCEBYTES) == -1); assert(crypto_secretbox_KEYBYTES == crypto_hash_sha256_BYTES); + // Update the last seem remote hex + saveNonceHex(NonceType::REMOTE, noncehex); + unsigned char* secret = new unsigned char[crypto_secretbox_KEYBYTES]; crypto_hash_sha256(secret, (const unsigned char*)"secret", QString("secret").length()); - unsigned char* noncebin = new unsigned char[crypto_secretbox_NONCEBYTES]; - sodium_hex2bin(noncebin, crypto_secretbox_NONCEBYTES, noncehex.toStdString().c_str(), noncehex.length(), - NULL, NULL, NULL); - unsigned char* encrypted = new unsigned char[encryptedhex.length() / 2]; sodium_hex2bin(encrypted, encryptedhex.length() / 2, encryptedhex.toStdString().c_str(), encryptedhex.length(), NULL, NULL, NULL); @@ -109,6 +146,7 @@ QJsonDocument AppDataServer::processMessage(QString message, MainWindow* mainWin qDebug() << "Decrypted to: " << payload; delete[] secret; + delete[] lastRemoteBin; delete[] noncebin; delete[] encrypted; delete[] decrypted; diff --git a/src/websockets.h b/src/websockets.h index 77f388a..a168f27 100644 --- a/src/websockets.h +++ b/src/websockets.h @@ -31,12 +31,20 @@ private: bool m_debug; }; +enum NonceType { + LOCAL = 1, + REMOTE +}; + class AppDataServer { public: static QJsonDocument processSendTx(QJsonObject sendTx, MainWindow* mainwindow); static QJsonDocument processMessage(QString message, MainWindow* mainWindow); static QJsonDocument processGetInfo(MainWindow* mainWindow); static QJsonDocument processGetTransactions(MainWindow* mainWindow); + static QString getSecretHex(); + static QString getNonceHex(NonceType nt); + static void saveNonceHex(NonceType nt, QString noncehex); }; class AppDataModel {