refactor: secureutils add pemFileCertFingerprint
This commit is contained in:
parent
fb32f141cc
commit
5a71d63923
8 changed files with 163 additions and 24 deletions
|
|
@ -11,6 +11,7 @@ add_library(base STATIC
|
||||||
EventQueue.h
|
EventQueue.h
|
||||||
EventTypes.cpp
|
EventTypes.cpp
|
||||||
EventTypes.h
|
EventTypes.h
|
||||||
|
finally.h
|
||||||
FunctionEventJob.cpp
|
FunctionEventJob.cpp
|
||||||
FunctionEventJob.h
|
FunctionEventJob.h
|
||||||
FunctionJob.cpp
|
FunctionJob.cpp
|
||||||
|
|
|
||||||
53
src/lib/base/finally.h
Normal file
53
src/lib/base/finally.h
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||||
|
* SPDX-FileCopyrightText: (C) 2021 Barrier Contributors
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace deskflow {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The `FinalAction` class implements a common pattern for calling an action at the end of a function.
|
||||||
|
*/
|
||||||
|
template <class Callable> class FinalAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FinalAction() noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FinalAction(Callable callable) noexcept : m_callable{callable}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~FinalAction() noexcept
|
||||||
|
{
|
||||||
|
if (!m_invoked) {
|
||||||
|
m_callable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FinalAction(FinalAction &&other) noexcept : m_callable{std::move(other.m_callable)}
|
||||||
|
{
|
||||||
|
std::swap(m_invoked, other.m_invoked);
|
||||||
|
}
|
||||||
|
|
||||||
|
FinalAction(const FinalAction &) = delete;
|
||||||
|
FinalAction &operator=(const FinalAction &) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_invoked = false;
|
||||||
|
Callable m_callable;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Callable> inline FinalAction<Callable> finally(Callable &&callable) noexcept
|
||||||
|
{
|
||||||
|
return FinalAction<Callable>(std::forward<Callable>(callable));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace deskflow
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "TlsFingerprint.h"
|
#include "TlsFingerprint.h"
|
||||||
|
|
||||||
#include "common/constants.h"
|
#include "common/constants.h"
|
||||||
|
#include "net/SecureUtils.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
@ -184,31 +185,14 @@ bool TlsCertificate::generateCertificate(const QString &path, int keyLength)
|
||||||
bool TlsCertificate::generateFingerprint(const QString &certificateFilename)
|
bool TlsCertificate::generateFingerprint(const QString &certificateFilename)
|
||||||
{
|
{
|
||||||
qDebug("generating tls fingerprint");
|
qDebug("generating tls fingerprint");
|
||||||
|
try {
|
||||||
QStringList arguments;
|
auto fingerprint =
|
||||||
arguments.append("x509");
|
deskflow::pemFileCertFingerprint(certificateFilename.toStdString(), deskflow::FingerprintType::SHA1);
|
||||||
arguments.append("-fingerprint");
|
TlsFingerprint::local().trust(QString::fromStdString(deskflow::formatSSLFingerprint(fingerprint)), false);
|
||||||
arguments.append(kCertificateHashAlgorithm);
|
|
||||||
arguments.append("-noout");
|
|
||||||
arguments.append("-in");
|
|
||||||
arguments.append(certificateFilename);
|
|
||||||
|
|
||||||
if (!runTool(arguments)) {
|
|
||||||
qCritical("failed to generate tls fingerprint");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the fingerprint from the tool output
|
|
||||||
auto i = m_toolStdout.indexOf("=");
|
|
||||||
if (i != -1) {
|
|
||||||
i++;
|
|
||||||
QString fingerprint = m_toolStdout.mid(i, m_toolStdout.size() - i);
|
|
||||||
|
|
||||||
TlsFingerprint::local().trust(fingerprint, false);
|
|
||||||
qDebug("tls fingerprint generated");
|
qDebug("tls fingerprint generated");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} catch (const std::exception &e) {
|
||||||
qCritical("failed to find tls fingerprint in tls tool output");
|
qCritical() << "failed to find tls fingerprint: " << e.what();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
|
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||||
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
|
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
|
||||||
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
|
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
add_library(io STATIC
|
add_library(io STATIC
|
||||||
|
filesystem.cpp
|
||||||
|
filesystem.h
|
||||||
IStream.h
|
IStream.h
|
||||||
StreamBuffer.cpp
|
StreamBuffer.cpp
|
||||||
StreamBuffer.h
|
StreamBuffer.h
|
||||||
|
|
|
||||||
52
src/lib/io/filesystem.cpp
Normal file
52
src/lib/io/filesystem.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||||
|
* SPDX-FileCopyrightText: (C) 2021 Barrier Contributors
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace deskflow {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <class Stream> void openUtf8PathImpl(Stream &stream, const fs::path &path, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
stream.open(path.native().c_str(), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void openUtf8Path(std::ifstream &stream, const fs::path &path, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
openUtf8PathImpl(stream, path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openUtf8Path(std::ofstream &stream, const fs::path &path, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
openUtf8PathImpl(stream, path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openUtf8Path(std::fstream &stream, const fs::path &path, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
openUtf8PathImpl(stream, path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::FILE *fopenUtf8Path(const fs::path &path, const std::string &mode)
|
||||||
|
{
|
||||||
|
#if SYSAPI_WIN32
|
||||||
|
std::wstring wpath = path.native();
|
||||||
|
std::wstring wmode(mode.begin(), mode.end());
|
||||||
|
|
||||||
|
return _wfopen(wpath.c_str(), wmode.c_str());
|
||||||
|
#else
|
||||||
|
return std::fopen(path.native().c_str(), mode.c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace deskflow
|
||||||
27
src/lib/io/filesystem.h
Normal file
27
src/lib/io/filesystem.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||||
|
* SPDX-FileCopyrightText: (C) 2021 Barrier Contributors
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <ios>
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
namespace deskflow {
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
void openUtf8Path(std::ifstream &stream, const fs::path &path, std::ios_base::openmode mode = std::ios_base::in);
|
||||||
|
void openUtf8Path(std::ofstream &stream, const fs::path &path, std::ios_base::openmode mode = std::ios_base::out);
|
||||||
|
void openUtf8Path(
|
||||||
|
std::fstream &stream, const fs::path &path, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out
|
||||||
|
);
|
||||||
|
|
||||||
|
std::FILE *fopenUtf8Path(const fs::path &path, const std::string &mode);
|
||||||
|
|
||||||
|
} // namespace deskflow
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "SecureUtils.h"
|
#include "SecureUtils.h"
|
||||||
#include "base/String.h"
|
#include "base/String.h"
|
||||||
|
#include "base/finally.h"
|
||||||
|
#include "io/filesystem.h"
|
||||||
|
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
|
@ -66,4 +68,20 @@ std::vector<uint8_t> SSLCertFingerprint(X509 *cert, FingerprintType type)
|
||||||
return digestVec;
|
return digestVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::uint8_t> pemFileCertFingerprint(const std::string &path, FingerprintType type)
|
||||||
|
{
|
||||||
|
auto fp = fopenUtf8Path(path, "r");
|
||||||
|
if (!fp) {
|
||||||
|
throw std::runtime_error("could not open certificate path");
|
||||||
|
}
|
||||||
|
auto fileClose = finally([fp]() { std::fclose(fp); });
|
||||||
|
|
||||||
|
X509 *cert = PEM_read_X509(fp, nullptr, nullptr, nullptr);
|
||||||
|
if (!cert) {
|
||||||
|
throw std::runtime_error("certificate could not be parsed");
|
||||||
|
}
|
||||||
|
auto certFree = finally([cert]() { X509_free(cert); });
|
||||||
|
|
||||||
|
return SSLCertFingerprint(cert, type);
|
||||||
|
}
|
||||||
} // namespace deskflow
|
} // namespace deskflow
|
||||||
|
|
|
||||||
|
|
@ -25,4 +25,6 @@ namespace deskflow {
|
||||||
std::string formatSSLFingerprint(const std::vector<uint8_t> &fingerprint, bool enableSeparators = true);
|
std::string formatSSLFingerprint(const std::vector<uint8_t> &fingerprint, bool enableSeparators = true);
|
||||||
|
|
||||||
std::vector<std::uint8_t> SSLCertFingerprint(X509 *cert, FingerprintType type);
|
std::vector<std::uint8_t> SSLCertFingerprint(X509 *cert, FingerprintType type);
|
||||||
|
|
||||||
|
std::vector<std::uint8_t> pemFileCertFingerprint(const std::string &path, FingerprintType type);
|
||||||
} // namespace deskflow
|
} // namespace deskflow
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue