Browse Source

Allow temp secrets for connections

import_zecw
adityapk00 5 years ago
parent
commit
0396fd3444
  1. 2
      src/mainwindow.cpp
  2. 64
      src/websockets.cpp
  3. 5
      src/websockets.h

2
src/mainwindow.cpp

@ -127,6 +127,8 @@ void MainWindow::closeEvent(QCloseEvent* event) {
s.setValue("baltablegeometry", ui->balancesTable->horizontalHeader()->saveState());
s.setValue("tratablegeometry", ui->transactionsTable->horizontalHeader()->saveState());
s.sync();
// Let the RPC know to shut down any running service.
rpc->shutdownZcashd();

64
src/websockets.cpp

@ -83,8 +83,12 @@ QString AppDataServer::getSecretHex() {
void AppDataServer::saveNewSecret(QString secretHex) {
QSettings s;
s.setValue("mobileapp/secret", secretHex);
s.sync();
}
QString AppDataServer::tempSecret;
void AppDataServer::connectAppDialog(QWidget* parent) {
QDialog d(parent);
Ui_MobileAppConnector con;
@ -115,26 +119,23 @@ void AppDataServer::connectAppDialog(QWidget* parent) {
char* secretHex = new char[crypto_secretbox_KEYBYTES*2 + 1];
sodium_bin2hex(secretHex, crypto_secretbox_KEYBYTES*2+1, secretBin, crypto_secretbox_KEYBYTES);
saveNewSecret(secretHex);
QString secretStr(secretHex);
tempSecret = secretStr;
QString codeStr = uri + "," + secretHex;
QString codeStr = uri + "," + secretStr;
con.lblConnStr->setText(codeStr);
con.qrcode->setQrcodeString(codeStr);
con.lblRemoteNonce->setText(AppDataServer::getNonceHex(NonceType::REMOTE));
con.lblLocalNonce->setText(AppDataServer::getNonceHex(NonceType::LOCAL));
AppDataServer::saveNonceHex(NonceType::REMOTE, QString("00").repeated(24));
AppDataServer::saveNonceHex(NonceType::LOCAL, QString("00").repeated(24));
QObject::connect(con.btnDisconnect, &QPushButton::clicked, [=]() {
AppDataServer::saveNonceHex(NonceType::REMOTE, QString("00").repeated(24));
AppDataServer::saveNonceHex(NonceType::LOCAL, QString("00").repeated(24));
});
d.exec();
tempSecret = "";
}
QString AppDataServer::getNonceHex(NonceType nt) {
@ -158,6 +159,7 @@ void AppDataServer::saveNonceHex(NonceType nt, QString noncehex) {
else {
s.setValue("mobileapp/remotenonce", noncehex);
}
s.sync();
}
QString AppDataServer::encryptOutgoing(QString msg) {
@ -212,7 +214,7 @@ QString AppDataServer::encryptOutgoing(QString msg) {
return json.toJson();
}
QString AppDataServer::decryptMessage(QJsonDocument msg, QString secretHex) {
QString AppDataServer::decryptMessage(QJsonDocument msg, QString secretHex, bool skipNonceCheck) {
// Decrypt and then process
QString noncehex = msg.object().value("nonce").toString();
QString encryptedhex = msg.object().value("payload").toString();
@ -227,8 +229,15 @@ QString AppDataServer::decryptMessage(QJsonDocument msg, QString secretHex) {
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);
if (!skipNonceCheck) {
if (sodium_compare(lastRemoteBin, noncebin, crypto_secretbox_NONCEBYTES) != -1) {
// Refuse to accept a lower nonce, return an error
delete[] lastRemoteBin;
delete[] noncebin;
return "error";
}
}
// Update the last seem remote hex
saveNonceHex(NonceType::REMOTE, noncehex);
@ -247,8 +256,7 @@ QString AppDataServer::decryptMessage(QJsonDocument msg, QString secretHex) {
QString payload;
if (result == -1) {
payload = "error";
payload = "error";
} else {
char* decryptedStr = new char[decryptedLen + 1];
sodium_memzero(decryptedStr, decryptedLen + 1);
@ -280,14 +288,42 @@ void AppDataServer::processMessage(QString message, MainWindow* mainWindow, QWeb
}
auto decrypted = decryptMessage(msg, getSecretHex());
if (decrypted == "error") {
// If the dialog is open, then there might be a temporary, new secret key. Attempt to decrypt
// with that.
// If the decryption failed, maybe this is a new connection, so see if the dialog is open and a
// temp secret is in place
auto replyWithError = [=]() {
auto r = QJsonDocument(QJsonObject{
{"error", "Encrption error"}
{"error", "Encryption error"}
}).toJson();
pClient->sendTextMessage(r);
return;
};
if (decrypted == "error") {
// If the dialog is open, then there might be a temporary, new secret key. Attempt to decrypt
// with that.
if (!tempSecret.isEmpty()) {
decrypted = decryptMessage(msg, tempSecret, true);
if (decrypted == "error") {
// Oh, well. Just return an error
replyWithError();
return;
}
else {
// This is a new connection. So, update the nonces and the secret
saveNewSecret(tempSecret);
AppDataServer::saveNonceHex(NonceType::REMOTE, QString("00").repeated(24));
AppDataServer::saveNonceHex(NonceType::LOCAL, QString("00").repeated(24));
// Fall through to processDecryptedMessage
}
}
else {
replyWithError();
return;
}
}
processDecryptedMessage(decrypted, mainWindow, pClient);

5
src/websockets.h

@ -46,7 +46,7 @@ public:
static void processGetInfo(MainWindow* mainWindow, QWebSocket* pClient);
static void processGetTransactions(MainWindow* mainWindow, QWebSocket* pClient);
static QString decryptMessage(QJsonDocument msg, QString secretHex);
static QString decryptMessage(QJsonDocument msg, QString secretHex, bool skipNonceCheck = false);
static QString encryptOutgoing(QString msg);
static QString getSecretHex();
@ -54,6 +54,9 @@ public:
static QString getNonceHex(NonceType nt);
static void saveNonceHex(NonceType nt, QString noncehex);
private:
static QString tempSecret;
};
class AppDataModel {

Loading…
Cancel
Save