From 332e6c4a4d05682ef5ad70bebd6e8531203fc630 Mon Sep 17 00:00:00 2001 From: sithlord48 Date: Mon, 12 May 2025 20:23:00 -0400 Subject: [PATCH] refactor: do not write sha1 to localdb and no longer send sha1 as part of comparison --- src/lib/common/Constants.h.in | 1 - src/lib/gui/MainWindow.cpp | 32 ++++++----- src/lib/gui/dialogs/FingerprintDialog.cpp | 6 +- src/lib/gui/dialogs/FingerprintDialog.h | 2 +- src/lib/gui/tls/TlsCertificate.cpp | 15 +---- src/lib/gui/widgets/FingerprintPreview.cpp | 67 ++++++---------------- src/lib/gui/widgets/FingerprintPreview.h | 6 +- src/lib/net/FingerprintDatabase.cpp | 13 +++-- src/lib/net/FingerprintDatabase.h | 4 +- src/lib/net/SecureSocket.cpp | 23 +++----- 10 files changed, 63 insertions(+), 106 deletions(-) diff --git a/src/lib/common/Constants.h.in b/src/lib/common/Constants.h.in index 85d3f1dbc..5e71962ba 100644 --- a/src/lib/common/Constants.h.in +++ b/src/lib/common/Constants.h.in @@ -34,7 +34,6 @@ const auto kDebugBuild = false; #endif const auto kTlsDirName = "tls"; -const auto kTlsDbSize = 2; const auto kTlsCertificateFilename = "@CMAKE_PROJECT_NAME@.pem"; const auto kTlsFingerprintLocalFilename = "local-fingerprint"; const auto kTlsFingerprintTrustedServersFilename = "trusted-servers"; diff --git a/src/lib/gui/MainWindow.cpp b/src/lib/gui/MainWindow.cpp index 7612672f8..2d004b7eb 100644 --- a/src/lib/gui/MainWindow.cpp +++ b/src/lib/gui/MainWindow.cpp @@ -153,7 +153,7 @@ MainWindow::MainWindow() FingerprintDatabase db; db.read(Settings::tlsLocalDb()); - if (db.fingerprints().size() != kTlsDbSize) { + if (db.fingerprints().isEmpty()) { regenerateLocalFingerprints(); } } @@ -543,13 +543,21 @@ void MainWindow::showMyFingerprint() FingerprintDatabase db; db.read(Settings::tlsLocalDb()); - if (db.fingerprints().size() != kTlsDbSize) { + if (db.fingerprints().isEmpty()) { if (regenerateLocalFingerprints()) showMyFingerprint(); return; } - FingerprintDialog fingerprintDialog(this, db.fingerprints()); + Fingerprint sha256Print; + for (const auto &f : std::as_const(db.fingerprints())) { + if (f.type == Fingerprint::Type::SHA256) { + sha256Print = f; + break; + } + } + + FingerprintDialog fingerprintDialog(this, sha256Print); fingerprintDialog.exec(); } @@ -762,20 +770,18 @@ void MainWindow::checkConnected(const QString &line) void MainWindow::checkFingerprint(const QString &line) { - static const QRegularExpression re(R"(.*peer fingerprint: \(SHA1\) ([A-F0-9:]+) \(SHA256\) ([A-F0-9:]+))"); - auto match = re.match(line); - if (!match.hasMatch()) { + static const auto tlsPeerMessage = QStringLiteral("peer fingerprint: "); + static const qsizetype msgLen = QString(tlsPeerMessage).length(); + + const qsizetype midStart = line.indexOf(tlsPeerMessage); + if (midStart == -1) return; - } - const Fingerprint sha1 = {Fingerprint::Type::SHA1, QByteArray::fromHex(match.captured(1).remove(":").toLatin1())}; + const auto sha256Text = line.mid(midStart + msgLen).remove(':'); - const auto sha256Text = match.captured(2); - - const Fingerprint sha256 = {Fingerprint::Type::SHA256, QByteArray::fromHex(match.captured(2).remove(":").toLatin1())}; + const Fingerprint sha256 = {Fingerprint::Type::SHA256, QByteArray::fromHex(sha256Text.toLatin1())}; const bool isClient = m_coreProcess.mode() == CoreMode::Client; - if ((isClient && m_checkedServers.contains(sha256Text)) || (!isClient && m_checkedClients.contains(sha256Text))) { qDebug("ignoring fingerprint, already handled"); return; @@ -798,7 +804,7 @@ void MainWindow::checkFingerprint(const QString &line) auto dialogMode = isClient ? FingerprintDialogMode::Client : FingerprintDialogMode::Server; - FingerprintDialog fingerprintDialog(this, {sha1, sha256}, dialogMode); + FingerprintDialog fingerprintDialog(this, sha256, dialogMode); connect(&fingerprintDialog, &FingerprintDialog::requestLocalPrintsDialog, this, &MainWindow::showMyFingerprint); if (fingerprintDialog.exec() == QDialog::Accepted) { diff --git a/src/lib/gui/dialogs/FingerprintDialog.cpp b/src/lib/gui/dialogs/FingerprintDialog.cpp index 21feecac2..3ac92c2cc 100644 --- a/src/lib/gui/dialogs/FingerprintDialog.cpp +++ b/src/lib/gui/dialogs/FingerprintDialog.cpp @@ -13,13 +13,11 @@ #include #include -FingerprintDialog::FingerprintDialog( - QWidget *parent, const QList &fingerprints, FingerprintDialogMode mode -) +FingerprintDialog::FingerprintDialog(QWidget *parent, const Fingerprint &fingerprint, FingerprintDialogMode mode) : QDialog(parent), m_lblHeader{new QLabel(this)}, m_lblFooter{new QLabel(this)}, - m_fingerprintPreview{new FingerprintPreview(this, fingerprints)}, + m_fingerprintPreview{new FingerprintPreview(this, fingerprint)}, m_buttonBox{new QDialogButtonBox(this)} { setWindowIcon(QIcon::fromTheme("fingerprint")); diff --git a/src/lib/gui/dialogs/FingerprintDialog.h b/src/lib/gui/dialogs/FingerprintDialog.h index 9dd44001a..8f104c1cd 100644 --- a/src/lib/gui/dialogs/FingerprintDialog.h +++ b/src/lib/gui/dialogs/FingerprintDialog.h @@ -27,7 +27,7 @@ class FingerprintDialog : public QDialog public: explicit FingerprintDialog( - QWidget *parent = nullptr, const QList &fingerprints = {}, + QWidget *parent = nullptr, const Fingerprint &fingerprint = {}, FingerprintDialogMode mode = FingerprintDialogMode::Local ); ~FingerprintDialog() override = default; diff --git a/src/lib/gui/tls/TlsCertificate.cpp b/src/lib/gui/tls/TlsCertificate.cpp index 1de7036d8..768487a0a 100644 --- a/src/lib/gui/tls/TlsCertificate.cpp +++ b/src/lib/gui/tls/TlsCertificate.cpp @@ -52,18 +52,9 @@ bool TlsCertificate::generateFingerprint(const QString &certificateFilename) { qDebug("generating tls fingerprint"); const std::string certPath = certificateFilename.toStdString(); - try { - FingerprintDatabase db; - db.addTrusted(deskflow::pemFileCertFingerprint(certPath, Fingerprint::Type::SHA1)); - db.addTrusted(deskflow::pemFileCertFingerprint(certPath, Fingerprint::Type::SHA256)); - db.write(Settings::tlsLocalDb()); - - qDebug("tls fingerprint generated"); - return true; - } catch (const std::exception &e) { - qCritical() << "failed to find tls fingerprint: " << e.what(); - return false; - } + FingerprintDatabase db; + db.addTrusted(deskflow::pemFileCertFingerprint(certPath, Fingerprint::Type::SHA256)); + return db.write(Settings::tlsLocalDb()); } int TlsCertificate::getCertKeyLength(const QString &path) diff --git a/src/lib/gui/widgets/FingerprintPreview.cpp b/src/lib/gui/widgets/FingerprintPreview.cpp index 8452a3aac..99d59e7c3 100644 --- a/src/lib/gui/widgets/FingerprintPreview.cpp +++ b/src/lib/gui/widgets/FingerprintPreview.cpp @@ -12,57 +12,36 @@ #include -FingerprintPreview::FingerprintPreview(QWidget *parent, const QList &fingerprints) : QFrame(parent) +FingerprintPreview::FingerprintPreview(QWidget *parent, const Fingerprint &fingerprint) : QFrame(parent) { setFrameShape(QFrame::StyledPanel); setFrameStyle(QFrame::Sunken); setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - QString sha1String; - QString sha256String; - QString sha256Art; + setLayout(fingerprint.type == Fingerprint::Type::SHA256 ? sha256Layout(fingerprint) : emptyLayout()); - for (const auto &fingerprint : fingerprints) { - switch (fingerprint.type) { - case Fingerprint::Type::SHA1: - sha1String = deskflow::formatSSLFingerprint(fingerprint.data); - break; + adjustSize(); + setFixedSize(size()); +} - case Fingerprint::Type::SHA256: - sha256String = deskflow::formatSSLFingerprintColumns(fingerprint.data); - sha256Art = deskflow::generateFingerprintArt(fingerprint.data); - break; - default: - qWarning() << "unknown fingerprint type:" << fingerprint.type; - break; - } - } - - auto labelSha1 = new QLabel(QStringLiteral("SHA1:"), this); - labelSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - auto lblSha1 = new QLabel(sha1String, this); - lblSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - lblSha1->setTextInteractionFlags(Qt::TextSelectableByMouse); - - auto sha1Layout = new QHBoxLayout(); - sha1Layout->addWidget(labelSha1); - sha1Layout->addWidget(lblSha1); - - auto frameSha1 = new QFrame(this); - frameSha1->setFrameShape(QFrame::StyledPanel); - frameSha1->setFrameStyle(QFrame::Sunken); - frameSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - frameSha1->setLayout(sha1Layout); +QLayout *FingerprintPreview::emptyLayout() +{ + auto *label = new QLabel(tr("Invalid hash format")); + auto *layout = new QHBoxLayout(); + layout->addWidget(label); + return layout; +} +QLayout *FingerprintPreview::sha256Layout(const Fingerprint &fingerprint) +{ auto labelSha256 = new QLabel(QStringLiteral("SHA256:"), this); labelSha256->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - auto lblSha256String = new QLabel(sha256String, this); + auto lblSha256String = new QLabel(deskflow::formatSSLFingerprintColumns(fingerprint.data), this); lblSha256String->setAlignment(Qt::AlignTop | Qt::AlignHCenter); lblSha256String->setTextInteractionFlags(Qt::TextSelectableByMouse); - auto lblSha256Art = new QLabel(sha256Art, this); + auto lblSha256Art = new QLabel(deskflow::generateFingerprintArt(fingerprint.data), this); lblSha256Art->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); lblSha256Art->setTextInteractionFlags(Qt::TextSelectableByMouse); @@ -87,19 +66,7 @@ FingerprintPreview::FingerprintPreview(QWidget *parent, const QList frameSha256->setLayout(sha256Layout); auto layout = new QVBoxLayout(); - layout->addWidget(frameSha1); layout->addWidget(frameSha256); - setLayout(layout); - - if (sha1String.isEmpty()) { - frameSha1->setVisible(false); - } - - if (sha256String.isEmpty()) { - frameSha256->setVisible(false); - } - - adjustSize(); - setFixedSize(size()); + return layout; } diff --git a/src/lib/gui/widgets/FingerprintPreview.h b/src/lib/gui/widgets/FingerprintPreview.h index 07eef4fbc..e4f26a987 100644 --- a/src/lib/gui/widgets/FingerprintPreview.h +++ b/src/lib/gui/widgets/FingerprintPreview.h @@ -13,6 +13,10 @@ class FingerprintPreview : public QFrame { Q_OBJECT public: - explicit FingerprintPreview(QWidget *parent, const QList &fingerprints = {}); + explicit FingerprintPreview(QWidget *parent, const Fingerprint &fingerprint = {}); ~FingerprintPreview() override = default; + +private: + QLayout *emptyLayout(); + QLayout *sha256Layout(const Fingerprint &fingerprint = {}); }; diff --git a/src/lib/net/FingerprintDatabase.cpp b/src/lib/net/FingerprintDatabase.cpp index 6e8023f94..68a325583 100644 --- a/src/lib/net/FingerprintDatabase.cpp +++ b/src/lib/net/FingerprintDatabase.cpp @@ -48,29 +48,30 @@ void FingerprintDatabase::readStream(QTextStream &in) } } -void FingerprintDatabase::write(const QString &path) +bool FingerprintDatabase::write(const QString &path) { QFile file(path); if (!file.open(QIODevice::WriteOnly)) - return; + return false; QTextStream out(&file); - writeStream(out); + return (writeStream(out)); } -void FingerprintDatabase::writeStream(QTextStream &out) +bool FingerprintDatabase::writeStream(QTextStream &out) { // Make sure the stream has somewhere to write if (!out.device() && !out.string()) - return; + return false; if (out.device()) { if (!out.device()->isWritable()) - return; + return false; } for (const auto &fingerprint : std::as_const(m_fingerprints)) { out << fingerprint.toDbLine() << "\n"; } + return true; } void FingerprintDatabase::clear() diff --git a/src/lib/net/FingerprintDatabase.h b/src/lib/net/FingerprintDatabase.h index f6be8e1d6..5c61966fe 100644 --- a/src/lib/net/FingerprintDatabase.h +++ b/src/lib/net/FingerprintDatabase.h @@ -15,10 +15,10 @@ class FingerprintDatabase { public: void read(const QString &path); - void write(const QString &path); + bool write(const QString &path); void readStream(QTextStream &in); - void writeStream(QTextStream &out); + bool writeStream(QTextStream &out); void clear(); void addTrusted(const Fingerprint &fingerprint); diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index a4050ffab..a5e5b5fd7 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -645,23 +645,14 @@ void SecureSocket::disconnect() bool SecureSocket::verifyCertFingerprint(const QString &FingerprintDatabasePath) { - Fingerprint sha1; - Fingerprint sha256; - try { - auto cert = SSL_get_peer_certificate(m_ssl->m_ssl); - sha1 = deskflow::sslCertFingerprint(cert, Fingerprint::Type::SHA1); - sha256 = deskflow::sslCertFingerprint(cert, Fingerprint::Type::SHA256); - } catch (const std::exception &e) { - LOG((CLOG_ERR "%s", e.what())); - return false; - } + const auto cert = SSL_get_peer_certificate(m_ssl->m_ssl); + const auto sha256 = deskflow::sslCertFingerprint(cert, Fingerprint::Type::SHA256); - // Gui Must Parse these two lines, DO NOT CHANGE - LOG( - (CLOG_NOTE "peer fingerprint: (SHA1) %s (SHA256) %s", - deskflow::formatSSLFingerprint(sha1.data).toStdString().c_str(), - deskflow::formatSSLFingerprint(sha256.data).toStdString().c_str()) - ); + if (!sha256.isValid()) + return false; + + // Gui Must Parse this line, DO NOT CHANGE + LOG((CLOG_NOTE "peer fingerprint: %s", deskflow::formatSSLFingerprint(sha256.data, false).toStdString().c_str())); QFile file(FingerprintDatabasePath);