Allow temp secrets for connections
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user