refactor: do not write sha1 to localdb and no longer send sha1 as part of comparison
This commit is contained 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";
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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"));
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 = {});
|
||||
};
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user