refactor: do not write sha1 to localdb and no longer send sha1 as part of comparison

This commit is contained in:
sithlord48
2025-05-12 20:23:00 -04:00
committed by Nick Bolton
parent 63e87c16d1
commit 332e6c4a4d
10 changed files with 63 additions and 106 deletions

View File

@ -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";

View File

@ -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) {

View File

@ -13,13 +13,11 @@
#include <QPushButton>
#include <QVBoxLayout>
FingerprintDialog::FingerprintDialog(
QWidget *parent, const QList<Fingerprint> &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"));

View File

@ -27,7 +27,7 @@ class FingerprintDialog : public QDialog
public:
explicit FingerprintDialog(
QWidget *parent = nullptr, const QList<Fingerprint> &fingerprints = {},
QWidget *parent = nullptr, const Fingerprint &fingerprint = {},
FingerprintDialogMode mode = FingerprintDialogMode::Local
);
~FingerprintDialog() override = default;

View File

@ -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)

View File

@ -12,57 +12,36 @@
#include <net/SecureUtils.h>
FingerprintPreview::FingerprintPreview(QWidget *parent, const QList<Fingerprint> &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<Fingerprint>
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;
}

View File

@ -13,6 +13,10 @@ class FingerprintPreview : public QFrame
{
Q_OBJECT
public:
explicit FingerprintPreview(QWidget *parent, const QList<Fingerprint> &fingerprints = {});
explicit FingerprintPreview(QWidget *parent, const Fingerprint &fingerprint = {});
~FingerprintPreview() override = default;
private:
QLayout *emptyLayout();
QLayout *sha256Layout(const Fingerprint &fingerprint = {});
};

View File

@ -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()

View File

@ -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);

View File

@ -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);