From ffe8f415d3e083005850c19d258246a34b93bdd7 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 6 Jan 2025 15:17:45 +0200 Subject: [PATCH] Remove Qt 5 support IB-8335 Signed-off-by: Raul Metsma --- .github/workflows/build.yml | 15 +-- CMakeLists.txt | 5 +- client/Application.cpp | 4 - client/CMakeLists.txt | 17 +--- client/Crypto.cpp | 9 +- client/Diagnostics.cpp | 6 -- client/IKValidator.cpp | 22 ++--- client/MainWindow.cpp | 5 - client/QCardLock.cpp | 73 --------------- client/QCardLock.h | 59 ------------ client/QCardLock_p.h | 33 ------- client/QPCSC.cpp | 6 -- client/QSigner.cpp | 130 ++++++++++---------------- client/QSigner.h | 3 +- client/QSmartCard.cpp | 25 +---- client/QSmartCard.h | 5 +- client/Settings.h | 11 +-- client/SslCertificate.cpp | 12 --- client/SslCertificate.h | 4 - client/dialogs/CertificateHistory.cpp | 8 -- client/dialogs/CertificateHistory.h | 6 +- client/dialogs/SettingsDialog.cpp | 6 +- client/main.cpp | 5 - client/widgets/LineEdit.cpp | 2 +- common | 2 +- debian/control | 14 +-- 26 files changed, 92 insertions(+), 395 deletions(-) delete mode 100644 client/QCardLock.cpp delete mode 100644 client/QCardLock.h delete mode 100644 client/QCardLock_p.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 665a1ad6a..dd8d2a816 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,7 +56,7 @@ jobs: container: ubuntu:${{ matrix.container }} strategy: matrix: - container: ['20.04', '22.04', '24.04', '24.10'] + container: ['22.04', '24.04', '24.10'] env: DEBIAN_FRONTEND: noninteractive DEBFULLNAME: github-actions @@ -71,10 +71,6 @@ jobs: path: libdigidocpp-pkg repo: open-eid/libdigidocpp - name: Install dependencies - if: matrix.container == '20.04' - run: apt update -qq && apt install --no-install-recommends -y git lsb-release build-essential devscripts debhelper pkg-config lintian ./libdigidocpp-pkg/*.deb cmake libldap2-dev gettext libpcsclite-dev libssl-dev libqt5svg5-dev qttools5-dev-tools qttools5-dev libflatbuffers-dev zlib1g-dev - - name: Install dependencies - if: matrix.container != '20.04' run: apt update -qq && apt install --no-install-recommends -y git lsb-release build-essential devscripts debhelper pkg-config lintian ${UBUNTU_DEPS} - name: Checkout uses: actions/checkout@v4 @@ -137,10 +133,12 @@ jobs: runs-on: ${{ matrix.image }} strategy: matrix: - vcver: [143] + vcver: [143, 142] include: - vcver: 143 image: windows-2022 + - vcver: 142 + image: windows-2019 env: VER_SUFFIX: .VS${{ matrix.vcver }} steps: @@ -164,7 +162,7 @@ jobs: uses: lukka/run-vcpkg@v7 with: vcpkgArguments: openssl zlib flatbuffers - vcpkgGitCommitId: 18b028fe785e707265fa0e35590b7537ae1d12ea + vcpkgGitCommitId: e4644bd15436d406bba71928d086c809e5c9ca45 vcpkgTriplet: x64-windows - name: Install Qt uses: jurplel/install-qt-action@v4 @@ -181,9 +179,6 @@ jobs: wix extension -g add WixToolset.UI.wixext/5.0.2 - name: Build run: | - if ($env:VCToolsRedistDir -eq $null) { - $env:VCToolsRedistDir = -join ($env:VCINSTALLDIR, "Redist\MSVC\", $env:VCToolsVersion, "\") - } cmake "-GNinja" -B build -S . -DCMAKE_BUILD_TYPE=RelWithDebInfo ` -DCMAKE_TOOLCHAIN_FILE=${{ env.RUNVCPKG_VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake ` "-DLibDigiDocpp_ROOT=libs/PFiles64/libdigidocpp" diff --git a/CMakeLists.txt b/CMakeLists.txt index cb0d25bcb..686e223b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.22) if(NOT EXISTS ${CMAKE_SOURCE_DIR}/cmake/modules/VersionInfo.cmake) message(FATAL_ERROR "cmake submodule directory empty, did you 'git clone --recursive'?") endif() @@ -13,8 +13,7 @@ include( VersionInfo ) find_package(LibDigiDocpp 4.1.0 REQUIRED) find_package( LDAP REQUIRED ) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} 5.12.0 REQUIRED COMPONENTS Core Widgets Network PrintSupport Svg LinguistTools) +find_package(Qt6 6.2.0 REQUIRED COMPONENTS Core Widgets Network PrintSupport SvgWidgets LinguistTools) find_package(FlatBuffers CONFIG REQUIRED NAMES FlatBuffers Flatbuffers) find_package(ZLIB REQUIRED) diff --git a/client/Application.cpp b/client/Application.cpp index 5c23b4e58..46cd58310 100644 --- a/client/Application.cpp +++ b/client/Application.cpp @@ -822,11 +822,7 @@ void Application::openHelp() void Application::parseArgs( const QString &msg ) { QStringList params; -#if QT_VERSION > QT_VERSION_CHECK(5, 14, 0) for(const QString ¶m: msg.split(QStringLiteral("\", \""), Qt::SkipEmptyParts)) -#else - for(const QString ¶m: msg.split(QStringLiteral("\", \""), QString::SkipEmptyParts)) -#endif { QUrl url( param, QUrl::StrictMode ); params.append(param != QLatin1String("-crypto") && !url.toLocalFile().isEmpty() ? url.toLocalFile() : param); diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index b2251bcb4..18895af13 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,11 +1,11 @@ +get_target_property(qtCore_install_prefix Qt6::qmake IMPORTED_LOCATION) +get_filename_component(qtCore_install_prefix ${qtCore_install_prefix} DIRECTORY) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/TSL.qrc) set(TSL_QRC ${CMAKE_CURRENT_SOURCE_DIR}/TSL.qrc) else() add_executable(TSLDownload TSLDownload.cpp) - target_link_libraries(TSLDownload Qt${QT_VERSION_MAJOR}::Network) + target_link_libraries(TSLDownload Qt6::Network) set_target_properties(TSLDownload PROPERTIES AUTOMOC OFF) - get_target_property(qtCore_install_prefix Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION) - get_filename_component(qtCore_install_prefix ${qtCore_install_prefix} DIRECTORY) add_custom_command( OUTPUT TSL.qrc DEPENDS TSLDownload @@ -69,8 +69,6 @@ add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE MainWindow.ui PrintSheet.cpp PrintSheet.h - QCardLock.cpp - QCardLock.h QCryptoBackend.cpp QCryptoBackend.h QPCSC.cpp @@ -96,8 +94,8 @@ add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE target_link_libraries(${PROJECT_NAME} qdigidoccommon - Qt${QT_VERSION_MAJOR}::PrintSupport - Qt${QT_VERSION_MAJOR}::Svg + Qt6::PrintSupport + Qt6::SvgWidgets ${LIBDIGIDOCPP_LIBRARY} ${LDAP_LIBRARIES} $ @@ -109,11 +107,6 @@ if(NOT BUILD_DATE) string(TIMESTAMP BUILD_DATE "%d.%m.%Y") endif() -if(${QT_VERSION_MAJOR} STREQUAL "6") - find_package(Qt6 COMPONENTS SvgWidgets REQUIRED) - target_link_libraries(${PROJECT_NAME} Qt6::SvgWidgets) -endif() - set_target_properties(${PROJECT_NAME} PROPERTIES AUTOUIC ON AUTORCC ON diff --git a/client/Crypto.cpp b/client/Crypto.cpp index ac6b2ad73..e41983f1e 100644 --- a/client/Crypto.cpp +++ b/client/Crypto.cpp @@ -24,9 +24,7 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L #include -#endif #include #include #include @@ -168,9 +166,6 @@ QByteArray Crypto::concatKDF(QCryptographicHash::Algorithm hashAlg, const QByteA QByteArray Crypto::curve_oid(EVP_PKEY *key) { QByteArray buf(50, 0); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(key))); -#else std::array group{}; size_t size = group.size(); if(EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_GROUP_NAME, group.data(), group.size(), &size) != 1) @@ -178,9 +173,7 @@ QByteArray Crypto::curve_oid(EVP_PKEY *key) buf.clear(); return buf; } - int nid = OBJ_sn2nid(group.data()); -#endif - ASN1_OBJECT *obj = OBJ_nid2obj(nid); + ASN1_OBJECT *obj = OBJ_nid2obj(OBJ_sn2nid(group.data())); if(int size = OBJ_obj2txt(buf.data(), buf.size(), obj, 1); size != NID_undef) buf.resize(size); else diff --git a/client/Diagnostics.cpp b/client/Diagnostics.cpp index 72dd8608d..ea842f155 100644 --- a/client/Diagnostics.cpp +++ b/client/Diagnostics.cpp @@ -28,12 +28,6 @@ #include #include -#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) -namespace Qt { -using ::hex; -} -#endif - void Diagnostics::generalInfo(QTextStream &s) { s << "" << tr("Arguments:") << " " << Application::arguments().join(' ') << "
" diff --git a/client/IKValidator.cpp b/client/IKValidator.cpp index 0873c02e6..f7e1e70ee 100644 --- a/client/IKValidator.cpp +++ b/client/IKValidator.cpp @@ -22,20 +22,12 @@ #include #include -inline int toInt(QStringView str) { -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - return QLocale::system().toInt(str); // QLocale, workaround for Qt 5 -#else - return str.toInt(); -#endif -} - QDate IKValidator::birthDate(QStringView ik) { if(ik.size() != 11) return {}; quint16 year = 0; - switch(toInt(ik.left(1))) + switch(ik.left(1).toInt()) { case 1: case 2: year = 1800; break; case 3: case 4: year = 1900; break; @@ -45,9 +37,9 @@ QDate IKValidator::birthDate(QStringView ik) } QDate date( - toInt(ik.mid(1, 2)) + year, - toInt(ik.mid(3, 2)), - toInt(ik.mid(5, 2))); + ik.mid(1, 2).toInt() + year, + ik.mid(3, 2).toInt(), + ik.mid(5, 2).toInt()); return date.isValid() ? date : QDate(); } @@ -80,8 +72,8 @@ bool IKValidator::isValid(QStringView ik) int sum1 = 0, sum2 = 0; for(int i = 0, pos1 = 1, pos2 = 3; i < 10; ++i) { - sum1 += toInt(ik.mid(i, 1)) * pos1; - sum2 += toInt(ik.mid(i, 1)) * pos2; + sum1 += ik.mid(i, 1).toInt() * pos1; + sum2 += ik.mid(i, 1).toInt() * pos2; pos1 = pos1 == 9 ? 1 : pos1 + 1; pos2 = pos2 == 9 ? 1 : pos2 + 1; } @@ -91,7 +83,7 @@ bool IKValidator::isValid(QStringView ik) (result = sum2 % 11) >= 10) result = 0; - return toInt(ik.right(1)) == result; + return ik.right(1).toInt() == result; } diff --git a/client/MainWindow.cpp b/client/MainWindow.cpp index 2fbb8d71b..488d8ecdb 100644 --- a/client/MainWindow.cpp +++ b/client/MainWindow.cpp @@ -90,12 +90,7 @@ MainWindow::MainWindow( QWidget *parent ) ui->pageButtonGroup->setId(ui->myEid, Pages::MyEid); connect(ui->pageButtonGroup, QOverload::of(&QButtonGroup::buttonToggled), this, &MainWindow::clearPopups); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) connect(ui->pageButtonGroup, &QButtonGroup::idToggled, this, &MainWindow::pageSelected); -#else - connect(ui->pageButtonGroup, QOverload::of(&QButtonGroup::buttonToggled), this, - [=](QAbstractButton *button, bool checked){ pageSelected(ui->pageButtonGroup->id(button), checked); }); -#endif ui->help->installEventFilter(new ButtonHoverFilter(QStringLiteral(":/images/icon_Abi.svg"), QStringLiteral(":/images/icon_Abi_hover.svg"), this)); ui->settings->installEventFilter(new ButtonHoverFilter(QStringLiteral(":/images/icon_Seaded.svg"), QStringLiteral(":/images/icon_Seaded_hover.svg"), this)); connect(ui->help, &QToolButton::clicked, qApp, &Application::openHelp); diff --git a/client/QCardLock.cpp b/client/QCardLock.cpp deleted file mode 100644 index 17775ae58..000000000 --- a/client/QCardLock.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * QDigiDoc4 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "QCardLock.h" -#include "QCardLock_p.h" - -QCardLock::QCardLock() -: d(new QCardLockPrivate) -{ -} - -QCardLock::~QCardLock() -{ - delete d; -} - -void QCardLock::exclusiveLock() -{ - readLock(); - d->exclusiveLock.lock(); -} - -bool QCardLock::exclusiveTryLock() -{ - readLock(); - bool rc = d->exclusiveLock.tryLock(); - if(!rc) - readUnlock(); - return rc; -} - -void QCardLock::exclusiveUnlock() -{ - d->exclusiveLock.unlock(); - readUnlock(); -} - -QCardLock& QCardLock::instance() -{ - static QCardLock lock; - return lock; -} - -void QCardLock::readLock() -{ - d->readLock.lock(); -} - -bool QCardLock::readTryLock() -{ - return d->readLock.tryLock(); -} - -void QCardLock::readUnlock() -{ - d->readLock.unlock(); -} diff --git a/client/QCardLock.h b/client/QCardLock.h deleted file mode 100644 index 8c4e2ad60..000000000 --- a/client/QCardLock.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * QDigiDoc4 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#pragma once - -#include - -class QCardLockPrivate; - -class QCardLock -{ -public: - ~QCardLock(); - static QCardLock& instance(); - - void exclusiveLock(); - bool exclusiveTryLock(); - void exclusiveUnlock(); - void readLock(); - bool readTryLock(); - void readUnlock(); - -private: - QCardLock(); - Q_DISABLE_COPY(QCardLock); - QCardLockPrivate *d; -}; - -class QCardLocker -{ -public: - inline QCardLocker() - { - QCardLock::instance().exclusiveLock(); - } - inline ~QCardLocker() - { - QCardLock::instance().exclusiveUnlock(); - } - -private: - Q_DISABLE_COPY(QCardLocker) -}; diff --git a/client/QCardLock_p.h b/client/QCardLock_p.h deleted file mode 100644 index e5bef6343..000000000 --- a/client/QCardLock_p.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * QDigiDoc4 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#pragma once - -#include - -class QCardLockPrivate -{ -public: -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - QRecursiveMutex readLock; -#else - QMutex readLock{QMutex::Recursive}; -#endif - QMutex exclusiveLock; -}; diff --git a/client/QPCSC.cpp b/client/QPCSC.cpp index 97830c639..cc05a729d 100644 --- a/client/QPCSC.cpp +++ b/client/QPCSC.cpp @@ -27,12 +27,6 @@ #include #include -#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) -namespace Qt { - using ::hex; -} -#endif - Q_LOGGING_CATEGORY(APDU,"QPCSC.APDU") Q_LOGGING_CATEGORY(SCard,"QPCSC.SCard") diff --git a/client/QSigner.cpp b/client/QSigner.cpp index 1b36cac46..83e721c8b 100644 --- a/client/QSigner.cpp +++ b/client/QSigner.cpp @@ -20,7 +20,6 @@ #include "QSigner.h" #include "Application.h" -#include "QCardLock.h" #include "QSmartCard.h" #include "TokenData.h" #ifdef Q_OS_WIN @@ -35,6 +34,7 @@ #include #include +#include #include #include @@ -53,6 +53,7 @@ class QSigner::Private final QSmartCard *smartcard {}; TokenData auth, sign; QList cache; + QReadWriteLock lock; static ECDSA_SIG* ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); @@ -165,7 +166,7 @@ bool QSigner::cardsOrder(const TokenData &s1, const TokenData &s2) default: return 0; } }; - QRegularExpression reg(QStringLiteral("(\\w{1,2})(\\d{7})")); + static const QRegularExpression reg(QStringLiteral("(\\w{1,2})(\\d{7})")); QRegularExpressionMatch r1 = reg.match(s1.card()); QRegularExpressionMatch r2 = reg.match(s2.card()); if(r1.hasMatch() || r2.hasMatch()) @@ -197,7 +198,7 @@ X509Cert QSigner::cert() const QByteArray QSigner::decrypt(std::function &&func) { - if(!QCardLock::instance().exclusiveTryLock()) + if(!d->lock.tryLockForWrite(10 * 1000)) { Q_EMIT error( tr("Signing/decrypting is already in progress another window.") ); return {}; @@ -206,38 +207,23 @@ QByteArray QSigner::decrypt(std::function &&func) if( d->auth.cert().isNull() ) { Q_EMIT error( tr("Authentication certificate is not selected.") ); - QCardLock::instance().exclusiveUnlock(); + d->lock.unlock(); return {}; } - QCryptoBackend::PinStatus status = QCryptoBackend::UnknownError; - do + switch(auto status = QCryptoBackend::PinStatus(login(d->auth))) { - switch(status = d->backend->login(d->auth)) - { - case QCryptoBackend::PinOK: break; - case QCryptoBackend::PinCanceled: - QCardLock::instance().exclusiveUnlock(); - return {}; - case QCryptoBackend::PinIncorrect: - (new WarningDialog(QCryptoBackend::errorString(status), Application::mainWindow()))->exec(); - continue; - case QCryptoBackend::PinLocked: - QCardLock::instance().exclusiveUnlock(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN1 is blocked. - Q_EMIT error(QCryptoBackend::errorString(status)); - return {}; - default: - QCardLock::instance().exclusiveUnlock(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN1 is blocked. - Q_EMIT error(tr("Failed to login token") + " " + QCryptoBackend::errorString(status)); - return {}; - } - } while(status != QCryptoBackend::PinOK); + case QCryptoBackend::PinOK: break; + case QCryptoBackend::PinCanceled: return {}; + case QCryptoBackend::PinLocked: + Q_EMIT error(QCryptoBackend::errorString(status)); + return {}; + default: + Q_EMIT error(tr("Failed to login token") + ' ' + QCryptoBackend::errorString(status)); + return {}; + } QByteArray result = waitFor(func, d->backend); - QCardLock::instance().exclusiveUnlock(); - d->backend->logout(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN1 is blocked. + logout(); if(d->backend->lastError() == QCryptoBackend::PinCanceled) return {}; @@ -251,26 +237,10 @@ QSslKey QSigner::key() const QSslKey key = d->auth.cert().publicKey(); if(!key.handle()) return {}; - if(!QCardLock::instance().exclusiveTryLock()) + if(!d->lock.tryLockForWrite(10 * 1000)) + return {}; + if(login(d->auth) != QCryptoBackend::PinOK) return {}; - - QCryptoBackend::PinStatus status = QCryptoBackend::UnknownError; - do - { - switch(status = d->backend->login(d->auth)) - { - case QCryptoBackend::PinOK: break; - case QCryptoBackend::PinIncorrect: - (new WarningDialog(QCryptoBackend::errorString(status), Application::mainWindow()))->exec(); - continue; - case QCryptoBackend::PinLocked: - default: - QCardLock::instance().exclusiveUnlock(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN1 is blocked. - return {}; - } - } while(status != QCryptoBackend::PinOK); - if(key.algorithm() == QSsl::Ec) { auto *ec = (EC_KEY*)key.handle(); @@ -286,10 +256,25 @@ QSslKey QSigner::key() const return key; } -void QSigner::logout() +quint8 QSigner::login(const TokenData &cert) const +{ + switch(auto status = d->backend->login(cert)) + { + case QCryptoBackend::PinOK: return status; + case QCryptoBackend::PinIncorrect: + (new WarningDialog(QCryptoBackend::errorString(status), Application::mainWindow()))->exec(); + return login(cert); + default: + d->lock.unlock(); + d->smartcard->reloadCounters(); // QSmartCard should also know that PIN is blocked. + return status; + } +} + +void QSigner::logout() const { d->backend->logout(); - QCardLock::instance().exclusiveUnlock(); + d->lock.unlock(); d->smartcard->reloadCounters(); // QSmartCard should also know that PIN1 info is updated } @@ -326,7 +311,7 @@ void QSigner::run() while(!isInterruptionRequested()) { - if(QCardLock::instance().readTryLock()) + if(d->lock.tryLockForRead()) { auto *pkcs11 = qobject_cast(d->backend); if(pkcs11 && !pkcs11->reload()) @@ -382,7 +367,7 @@ void QSigner::run() Q_EMIT signDataChanged(d->sign = update = st); if(aold != at || sold != st) d->smartcard->reloadCard(update); - QCardLock::instance().readUnlock(); + d->lock.unlock(); } if(!isInterruptionRequested()) @@ -420,43 +405,28 @@ std::vector QSigner::sign(const std::string &method, const std::v throw e; \ } - if(!QCardLock::instance().exclusiveTryLock()) + if(!d->lock.tryLockForWrite(10 * 1000)) throwException(tr("Signing/decrypting is already in progress another window."), Exception::General) if( d->sign.cert().isNull() ) { - QCardLock::instance().exclusiveUnlock(); + d->lock.unlock(); throwException(tr("Signing certificate is not selected."), Exception::General) } - QCryptoBackend::PinStatus status = QCryptoBackend::UnknownError; - do + switch(auto status = QCryptoBackend::PinStatus(login(d->sign))) { - switch(status = d->backend->login(d->sign)) - { - case QCryptoBackend::PinOK: break; - case QCryptoBackend::PinCanceled: - QCardLock::instance().exclusiveUnlock(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN2 info is updated - throwException((tr("Failed to login token") + " " + QCryptoBackend::errorString(status)), Exception::PINCanceled) - case QCryptoBackend::PinIncorrect: - (new WarningDialog(QCryptoBackend::errorString(status), Application::mainWindow()))->exec(); - continue; - case QCryptoBackend::PinLocked: - QCardLock::instance().exclusiveUnlock(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN2 info is updated - throwException((tr("Failed to login token") + " " + QCryptoBackend::errorString(status)), Exception::PINLocked) - default: - QCardLock::instance().exclusiveUnlock(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN2 info is updated - throwException((tr("Failed to login token") + " " + QCryptoBackend::errorString(status)), Exception::PINFailed) - } - } while(status != QCryptoBackend::PinOK); + case QCryptoBackend::PinOK: break; + case QCryptoBackend::PinCanceled: + throwException((tr("Failed to login token") + ' ' + QCryptoBackend::errorString(status)), Exception::PINCanceled); + case QCryptoBackend::PinLocked: + throwException((tr("Failed to login token") + ' ' + QCryptoBackend::errorString(status)), Exception::PINLocked); + default: + throwException((tr("Failed to login token") + ' ' + QCryptoBackend::errorString(status)), Exception::PINFailed); + } QByteArray sig = waitFor(&QCryptoBackend::sign, d->backend, methodToNID(method), QByteArray::fromRawData((const char*)digest.data(), int(digest.size()))); - QCardLock::instance().exclusiveUnlock(); - d->backend->logout(); - d->smartcard->reloadCounters(); // QSmartCard should also know that PIN2 info is updated + logout(); if(d->backend->lastError() == QCryptoBackend::PinCanceled) throwException(tr("Failed to login token"), Exception::PINCanceled) diff --git a/client/QSigner.h b/client/QSigner.h index ea7b42bdc..e15d2e012 100644 --- a/client/QSigner.h +++ b/client/QSigner.h @@ -43,7 +43,7 @@ class QSigner final: public QThread, public digidoc::Signer digidoc::X509Cert cert() const final; QByteArray decrypt(std::function &&func); QSslKey key() const; - void logout(); + void logout() const; void selectCard(const TokenData &token); std::vector sign( const std::string &method, const std::vector &digest) const final; @@ -59,6 +59,7 @@ class QSigner final: public QThread, public digidoc::Signer private: static bool cardsOrder(const TokenData &s1, const TokenData &s2); + quint8 login(const TokenData &cert) const; static QCryptographicHash::Algorithm methodToNID(const std::string &method); void run() final; diff --git a/client/QSmartCard.cpp b/client/QSmartCard.cpp index 83c91f3dd..e87128bf6 100644 --- a/client/QSmartCard.cpp +++ b/client/QSmartCard.cpp @@ -20,7 +20,6 @@ #include "QSmartCard_p.h" #include "IKValidator.h" -#include "QCardLock.h" #include "Settings.h" #include "Utils.h" #include "dialogs/PinPopup.h" @@ -35,10 +34,10 @@ Q_LOGGING_CATEGORY(CLog, "qdigidoc4.QSmartCard") QSmartCardData::QSmartCardData(): d(new QSmartCardDataPrivate) {} QSmartCardData::QSmartCardData(const QSmartCardData &other) = default; -QSmartCardData::QSmartCardData(QSmartCardData &&other) Q_DECL_NOEXCEPT = default; +QSmartCardData::QSmartCardData(QSmartCardData &&other) noexcept = default; QSmartCardData::~QSmartCardData() = default; QSmartCardData& QSmartCardData::operator =(const QSmartCardData &other) = default; -QSmartCardData& QSmartCardData::operator =(QSmartCardData &&other) Q_DECL_NOEXCEPT = default; +QSmartCardData& QSmartCardData::operator =(QSmartCardData &&other) noexcept = default; bool QSmartCardData::operator ==(const QSmartCardData &other) const { return d == other.d || ( @@ -46,7 +45,6 @@ bool QSmartCardData::operator ==(const QSmartCardData &other) const d->authCert == other.d->authCert && d->signCert == other.d->signCert); } -bool QSmartCardData::operator !=(const QSmartCardData &other) const { return !operator==(other); } QString QSmartCardData::card() const { return d->card; } @@ -195,20 +193,13 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const } } - bool readFailed = false; auto readCert = [&](const QByteArray &path) { QPCSCReader::Result data = reader->transfer(path); if(!data) - { - readFailed = true; return QSslCertificate(); - } QHash fci = parseFCI(data.data); if(!fci.contains(0x80)) - { - readFailed = true; return QSslCertificate(); - } QByteArray cert; QByteArray cmd = READBINARY; for(int size = quint8(fci[0x80][0]) << 8 | quint8(fci[0x80][1]); cert.size() < size; ) @@ -217,10 +208,7 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const cmd[3] = char(cert.size()); data = reader->transfer(cmd); if(!data) - { - readFailed = true; return QSslCertificate(); - } cert += data.data; } return QSslCertificate(cert, QSsl::Der); @@ -229,11 +217,10 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const d->authCert = readCert(APDU("00A40904 06 3F00 ADF1 3401 00")); if(d->signCert.isNull()) d->signCert = readCert(APDU("00A40904 06 3F00 ADF2 341F 00")); - if(!d->data.contains(QSmartCardData::BirthDate) && !d->authCert.isNull()) - d->data[QSmartCardData::BirthDate] = IKValidator::birthDate(d->authCert.personalCode()); - - if(readFailed) + if(d->authCert.isNull() || d->signCert.isNull()) return false; + if(!d->data.contains(QSmartCardData::BirthDate)) + d->data[QSmartCardData::BirthDate] = IKValidator::birthDate(d->authCert.personalCode()); return updateCounters(reader, d); } @@ -349,7 +336,6 @@ QSmartCard::ErrorType QSmartCard::change(QSmartCardData::PinType type, QWidget* case QSmartCardData::PukType: flags = PinPopup::PukType; break; default: return UnknownError; } - QCardLocker locker; QSharedPointer reader(d->connect(d->t.reader())); if(!reader) return UnknownError; @@ -489,7 +475,6 @@ QSmartCard::ErrorType QSmartCard::unblock(QSmartCardData::PinType type, QWidget* case QSmartCardData::Pin2Type: flags = PinPopup::Pin2Type; break; default: return UnknownError; } - QCardLocker locker; QSharedPointer reader(d->connect(d->t.reader())); if(!reader) return UnknownError; diff --git a/client/QSmartCard.h b/client/QSmartCard.h index 645c59086..37c9302c6 100644 --- a/client/QSmartCard.h +++ b/client/QSmartCard.h @@ -51,12 +51,11 @@ class QSmartCardData QSmartCardData(); QSmartCardData( const QSmartCardData &other ); - QSmartCardData(QSmartCardData &&other) Q_DECL_NOEXCEPT; + QSmartCardData(QSmartCardData &&other) noexcept; ~QSmartCardData(); QSmartCardData& operator=( const QSmartCardData &other ); - QSmartCardData& operator=(QSmartCardData &&other) Q_DECL_NOEXCEPT; + QSmartCardData& operator=(QSmartCardData &&other) noexcept; bool operator ==(const QSmartCardData &other) const; - bool operator !=(const QSmartCardData &other) const; QString card() const; QString reader() const; diff --git a/client/Settings.h b/client/Settings.h index af777bc70..220794b56 100644 --- a/client/Settings.h +++ b/client/Settings.h @@ -57,7 +57,7 @@ struct Settings QSettings().remove(KEY); } bool isLocked() const { - return settings(QSettings::SystemScope).value(KEY + QLatin1String("_LOCK"), false).toBool(); + return QSettings(QSettings::SystemScope).value(KEY + QLatin1String("_LOCK"), false).toBool(); } bool isSet() const { return QSettings().contains(KEY); @@ -86,14 +86,7 @@ struct Settings f = functor; } QSettings settings() const { - return settings(isLocked() ? QSettings::SystemScope : QSettings::UserScope); - } - static QSettings settings(QSettings::Scope scope) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - return QSettings(scope); -#else - return QSettings(scope, QCoreApplication::organizationName(), QCoreApplication::applicationName()); -#endif + return QSettings(isLocked() ? QSettings::SystemScope : QSettings::UserScope); } const QString KEY; const D DEFAULT {}; diff --git a/client/SslCertificate.cpp b/client/SslCertificate.cpp index fff7a42a0..4a363aecc 100644 --- a/client/SslCertificate.cpp +++ b/client/SslCertificate.cpp @@ -55,11 +55,7 @@ static QByteArray i2dDer(Func func, Arg arg) return der; } -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) size_t qHash(const SslCertificate &cert) { return qHash(cert.digest()); } -#else -uint qHash(const SslCertificate &cert) { return qHash(cert.digest()); } -#endif SslCertificate::SslCertificate() = default; @@ -95,18 +91,10 @@ QMultiHash SslCertificate::authori switch(OBJ_obj2nid(ad->method)) { case NID_ad_OCSP: -#if QT_VERSION > QT_VERSION_CHECK(5, 14, 0) result.insert(ad_OCSP, toQByteArray(ad->location->d.uniformResourceIdentifier)); -#else - result.insertMulti(ad_OCSP, toQByteArray(ad->location->d.uniformResourceIdentifier)); -#endif break; case NID_ad_ca_issuers: -#if QT_VERSION > QT_VERSION_CHECK(5, 14, 0) result.insert(ad_CAIssuers, toQByteArray(ad->location->d.uniformResourceIdentifier)); -#else - result.insertMulti(ad_CAIssuers, toQByteArray(ad->location->d.uniformResourceIdentifier)); -#endif break; default: break; } diff --git a/client/SslCertificate.h b/client/SslCertificate.h index 5cfe7f8ac..cd6d08941 100644 --- a/client/SslCertificate.h +++ b/client/SslCertificate.h @@ -109,8 +109,4 @@ class SslCertificate: public QSslCertificate Qt::HANDLE extension( int nid ) const; }; -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) size_t qHash(const SslCertificate &cert); -#else -uint qHash(const SslCertificate &cert); -#endif diff --git a/client/dialogs/CertificateHistory.cpp b/client/dialogs/CertificateHistory.cpp index b7c84adba..fed050b0e 100644 --- a/client/dialogs/CertificateHistory.cpp +++ b/client/dialogs/CertificateHistory.cpp @@ -31,14 +31,6 @@ #include #include -bool HistoryCertData::operator==(const HistoryCertData& other) const -{ - return CN == other.CN && - type == other.type && - issuer == other.issuer && - expireDate == other.expireDate; -} - QString HistoryCertData::toType(const SslCertificate &cert) { auto certType = cert.type(); diff --git a/client/dialogs/CertificateHistory.h b/client/dialogs/CertificateHistory.h index adda94907..f1d6ff668 100644 --- a/client/dialogs/CertificateHistory.h +++ b/client/dialogs/CertificateHistory.h @@ -36,15 +36,11 @@ class HistoryCertData static QString toType(const SslCertificate &cert); - bool operator==(const HistoryCertData& other) const; + bool operator==(const HistoryCertData& other) const noexcept = default; QString typeName() const; }; -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -class HistoryList: public QVector -#else class HistoryList: public QList -#endif { public: HistoryList(); diff --git a/client/dialogs/SettingsDialog.cpp b/client/dialogs/SettingsDialog.cpp index 54a41819a..cd7416693 100644 --- a/client/dialogs/SettingsDialog.cpp +++ b/client/dialogs/SettingsDialog.cpp @@ -406,11 +406,7 @@ SettingsDialog::SettingsDialog(int page, QWidget *parent) ui->pageGroup->setId(ui->btnMenuProxy, NetworkSettings); ui->pageGroup->setId(ui->btnMenuDiagnostics, DiagnosticsSettings); ui->pageGroup->setId(ui->btnMenuInfo, LicenseSettings); -#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) - connect(ui->pageGroup, qOverload(&QButtonGroup::buttonClicked), this, &SettingsDialog::showPage); -#else - connect(ui->pageGroup, qOverload(&QButtonGroup::idClicked), this, &SettingsDialog::showPage); -#endif + connect(ui->pageGroup, &QButtonGroup::idClicked, this, &SettingsDialog::showPage); updateVersion(); updateDiagnostics(); diff --git a/client/main.cpp b/client/main.cpp index 9652f63aa..a991bd0c2 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -26,11 +26,6 @@ int main( int argc, char *argv[] ) { -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); -#endif - for(int i = 1; i < argc; ++i) { QString parameter(argv[i]); diff --git a/client/widgets/LineEdit.cpp b/client/widgets/LineEdit.cpp index ca2304ef2..6e4beddf5 100644 --- a/client/widgets/LineEdit.cpp +++ b/client/widgets/LineEdit.cpp @@ -28,7 +28,7 @@ LineEdit::LineEdit(QWidget *parent) void LineEdit::paintEvent(QPaintEvent *event) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) +#if QT_VERSION < QT_VERSION_CHECK(6, 4, 1) // Workaround QTBUG-92199 if(text().isEmpty() && (!placeholderText().isEmpty() || !placeholder.isEmpty())) { diff --git a/common b/common index c04bf626d..abdbe1ed8 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c04bf626dae604343350c1c338700af0b89ba83b +Subproject commit abdbe1ed8ecf5aae6b5842565c57e93743f8ed8a diff --git a/debian/control b/debian/control index b11f7aeca..df7cf7a56 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: RIA Build-Depends: pkg-config, - debhelper-compat (= 12), + debhelper-compat (= 13), cmake, libdigidocpp-dev (>=3.0), libldap2-dev, @@ -13,21 +13,21 @@ Build-Depends: libflatbuffers-dev, flatbuffers-compiler-dev, zlib1g-dev, - qt6-tools-dev | qttools5-dev, - qt6-l10n-tools | qttools5-dev-tools, - libqt6svg6-dev | libqt5svg5-dev -Standards-Version: 4.5.1 + qt6-tools-dev, + qt6-l10n-tools, + libqt6svg6-dev, +Standards-Version: 4.6.1 Homepage: https://github.com/open-eid/DigiDoc4-Client Package: qdigidoc4 Architecture: any Depends: opensc-pkcs11, - qt6-qpa-plugins | libqt5gui5, + qt6-qpa-plugins, ${shlibs:Depends}, ${misc:Depends} Recommends: - python3-nautilus:amd64 | python3-nautilus:arm64 | python-nautilus + python3-nautilus:amd64 | python3-nautilus:arm64 Replaces: qdigidoc (<< 3.14) Description: Estonian digital signature application