From 345bb4b62b8efd0b4274277a5c3bc48fe47b223e Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 19 Jul 2020 11:56:17 +0300 Subject: [PATCH] gui: Regenerate certificate if it's invalid or the key is too small --- src/gui/CMakeLists.txt | 2 +- src/gui/src/SslCertificate.cpp | 63 +++++++++++++++++++++++++++++++++- src/gui/src/SslCertificate.h | 1 + 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f29fd910..02856b95 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -22,7 +22,7 @@ add_executable (barrier WIN32 include_directories (./src) -target_link_libraries (barrier Qt5::Core Qt5::Widgets Qt5::Network) +target_link_libraries (barrier Qt5::Core Qt5::Widgets Qt5::Network ${OPENSSL_LIBS}) target_compile_definitions (barrier PRIVATE -DBARRIER_VERSION_STAGE="${BARRIER_VERSION_STAGE}") target_compile_definitions (barrier PRIVATE -DBARRIER_REVISION="${BARRIER_REVISION}") diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index dc52c6f3..08863ae6 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -23,6 +23,12 @@ #include #include +#include +#include +#include +#include +#include + static const char kCertificateLifetime[] = "365"; static const char kCertificateSubjectInfo[] = "/CN=Barrier"; static const char kCertificateFilename[] = "Barrier.pem"; @@ -94,7 +100,7 @@ void SslCertificate::generateCertificate() auto filename = QString::fromStdString(getCertificatePath()); QFile file(filename); - if (!file.exists()) { + if (!file.exists() || !isCertificateValid(filename)) { QStringList arguments; // self signed certificate @@ -183,3 +189,58 @@ std::string SslCertificate::getCertificateDirectory() { return m_ProfileDir + QDir::separator().toLatin1() + kSslDir; } + +bool SslCertificate::isCertificateValid(const QString& path) +{ + OpenSSL_add_all_algorithms(); + ERR_load_BIO_strings(); + ERR_load_crypto_strings(); + + BIO* bio = BIO_new(BIO_s_file()); + + auto ret = BIO_read_filename(bio, path.toStdString().c_str()); + if (!ret) { + emit info(tr("Could not read from default certificate file.")); + BIO_free_all(bio); + return false; + } + + X509* cert = PEM_read_bio_X509(bio, NULL, 0, NULL); + if (!cert) { + emit info(tr("Error loading default certificate file to memory.")); + BIO_free_all(bio); + return false; + } + + EVP_PKEY* pubkey = X509_get_pubkey(cert); + if (!pubkey) { + emit info(tr("Default certificate key file does not contain valid public key")); + X509_free(cert); + BIO_free_all(bio); + return false; + } + + auto type = EVP_PKEY_type(EVP_PKEY_id(pubkey)); + if (type != EVP_PKEY_RSA && type != EVP_PKEY_DSA) { + emit info(tr("Public key in default certificate key file is not RSA or DSA")); + EVP_PKEY_free(pubkey); + X509_free(cert); + BIO_free_all(bio); + return false; + } + + auto bits = EVP_PKEY_bits(pubkey); + if (bits < 2048) { + // We could have small keys in old barrier installations + emit info(tr("Public key in default certificate key file is too small.")); + EVP_PKEY_free(pubkey); + X509_free(cert); + BIO_free_all(bio); + return false; + } + + EVP_PKEY_free(pubkey); + X509_free(cert); + BIO_free_all(bio); + return true; +} diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index 5ff5368d..b29a6b16 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -42,6 +42,7 @@ private: std::string getCertificatePath(); std::string getCertificateDirectory(); + bool isCertificateValid(const QString& path); private: std::string m_ProfileDir; };