From: Michael Marley Date: Sat, 31 Mar 2018 18:06:16 +0000 (-0400) Subject: Add support for Elliptic Curve keys for CertFP X-Git-Tag: travis-deploy-test~126 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=0dbec2cfc937857d66a9645249f876f1e6b3f05e;hp=92f4dca367c3a6f0536a1e0f3fbb44bb6ed4da62 Add support for Elliptic Curve keys for CertFP This functionality is controlled by a feature flag so that clients supporting EC keys won't try to set an EC key on a core that doesn't. As with the previous EC patch, this requires Qt 5.5 to work but uses the QT_VERSION macro to remain compileable with Qt4. This patch also fixes the QSsl::KeyAlgorithm indices to be correct for both Qt4 and Qt5. In Qt4, RSA was 0 and DSA was 1, but in Qt5 0 became Opaque, 1 because RSA, and two became DSA. EC is 3 and wasn't added until 5.5. The new macro handles all three versions correctly. (See https://doc.qt.io/qt-5/qssl.html#KeyAlgorithm-enum and https://doc.qt.io/archives/qt-4.8/qssl.html#KeyAlgorithm-enum.) Thanks to @justJanne for pointing out this discrepancy. Closes GH-347. --- diff --git a/src/client/clientidentity.cpp b/src/client/clientidentity.cpp index 26c0a730..3507a10b 100644 --- a/src/client/clientidentity.cpp +++ b/src/client/clientidentity.cpp @@ -111,6 +111,10 @@ void CertIdentity::markClean() void ClientCertManager::setSslKey(const QByteArray &encoded) { QSslKey key(encoded, QSsl::Rsa); +#if QT_VERSION >= 0x050500 + if (key.isNull() && Client::isCoreFeatureEnabled(Quassel::Feature::EcdsaCertfpKeys)) + key = QSslKey(encoded, QSsl::Ec); +#endif if (key.isNull()) key = QSslKey(encoded, QSsl::Dsa); _certIdentity->setSslKey(key); diff --git a/src/common/quassel.h b/src/common/quassel.h index 87d525f8..88b22546 100644 --- a/src/common/quassel.h +++ b/src/common/quassel.h @@ -131,6 +131,9 @@ public: SenderPrefixes, ///< Show prefixes for senders in backlog RemoteDisconnect, ///< Allow this peer to be remotely disconnected ExtendedFeatures, ///< Extended features +#if QT_VERSION >= 0x050500 + EcdsaCertfpKeys, ///< ECDSA keys for CertFP in identities +#endif }; Q_ENUMS(Feature) diff --git a/src/core/coreidentity.cpp b/src/core/coreidentity.cpp index 1255411c..b7cd6d09 100644 --- a/src/core/coreidentity.cpp +++ b/src/core/coreidentity.cpp @@ -77,6 +77,10 @@ void CoreIdentity::synchronize(SignalProxy *proxy) void CoreIdentity::setSslKey(const QByteArray &encoded) { QSslKey key(encoded, QSsl::Rsa); +#if QT_VERSION >= 0x050500 + if (key.isNull()) + key = QSslKey(encoded, QSsl::Ec); +#endif if (key.isNull()) key = QSslKey(encoded, QSsl::Dsa); setSslKey(key); diff --git a/src/qtui/settingspages/identityeditwidget.cpp b/src/qtui/settingspages/identityeditwidget.cpp index a08ab09d..d31020a7 100644 --- a/src/qtui/settingspages/identityeditwidget.cpp +++ b/src/qtui/settingspages/identityeditwidget.cpp @@ -392,7 +392,16 @@ QSslKey IdentityEditWidget::keyByFilename(const QString &filename) keyFile.close(); for (int i = 0; i < 2; i++) { +#if QT_VERSION >= 0x050500 + // On Qt5.5+, support QSsl::KeyAlgorithm::Rsa (1), QSsl::KeyAlgorithm::Dsa (2), and QSsl::KeyAlgorithm::Ec (3) + for (int j = 1; j < 4; j++) { +#elif QT_VERSION >= 0x050000 + // On Qt5.0-Qt5.4, support QSsl::KeyAlgorithm::Rsa (1) and QSsl::KeyAlgorithm::Dsa (2) (Ec wasn't added until 5.5) + for (int j = 1; j < 3; j++) { +#else + // On Qt4, support QSsl::KeyAlgorithm::Rsa (0) and QSsl::KeyAlgorithm::Dsa (1) (Qt4 uses different indices for the values) for (int j = 0; j < 2; j++) { +#endif key = QSslKey(keyRaw, (QSsl::KeyAlgorithm)j, (QSsl::EncodingFormat)i); if (!key.isNull()) goto returnKey; @@ -400,6 +409,12 @@ QSslKey IdentityEditWidget::keyByFilename(const QString &filename) } QMessageBox::information(this, tr("Failed to read key"), tr("Failed to read the key file. It is either incompatible or invalid. Note that the key file must not have a passphrase.")); returnKey: +#if QT_VERSION >= 0x050500 + if(!key.isNull() && key.algorithm() == QSsl::KeyAlgorithm::Ec && !Client::isCoreFeatureEnabled(Quassel::Feature::EcdsaCertfpKeys)) { + QMessageBox::information(this, tr("Core does not support ECDSA keys"), tr("You loaded an ECDSA key, but the core does not support ECDSA keys. Please contact the core administrator.")); + key.clear(); + } +#endif return key; } @@ -415,11 +430,16 @@ void IdentityEditWidget::showKeyState(const QSslKey &key) case QSsl::Rsa: ui.keyTypeLabel->setText(tr("RSA")); break; +#if QT_VERSION >= 0x050500 + case QSsl::Ec: + ui.keyTypeLabel->setText(tr("ECDSA")); + break; +#endif case QSsl::Dsa: ui.keyTypeLabel->setText(tr("DSA")); break; default: - ui.keyTypeLabel->setText(tr("No Key loaded")); + ui.keyTypeLabel->setText(tr("Invalid key or no key loaded")); } ui.clearOrLoadKeyButton->setText(tr("Clear")); }