diff --git a/src/crypto/decryptverifytask.cpp b/src/crypto/decryptverifytask.cpp --- a/src/crypto/decryptverifytask.cpp +++ b/src/crypto/decryptverifytask.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include @@ -294,7 +295,18 @@ if (key.isNull()) { return text += i18n("With unavailable certificate:") + QStringLiteral("
ID: 0x%1").arg(QString::fromLatin1(sig.fingerprint()).toUpper()); } - return text += i18n("With certificate:") + QStringLiteral("
") + renderKey(key); + text += i18n("With certificate:") + QStringLiteral("
") + renderKey(key); + + if (Kleo::gpgComplianceP("de-vs")) + text += + (QStringLiteral("
") + + (IS_DE_VS(sig) + ? i18nc("VS-conforming is a German standard for restricted documents for which special restrictions about algorithms apply. The string states that a signature is compliant with that.", + "The signature is VS-compliant.") + : i18nc("VS-conforming is a German standard for restricted documents for which special restrictions about algorithms apply. The string states that a signature is not compliant with that.", + "The signature is not VS-compliant."))); + + return text; } static QString strikeOut(const QString &str, bool strike) @@ -531,22 +543,31 @@ static QString formatDecryptionResultDetails(const DecryptionResult &res, const std::vector &recipients, const QString &errorString, bool isSigned) { + QString details; + if ((res.error().code() == GPG_ERR_EIO || res.error().code() == GPG_ERR_NO_DATA) && !errorString.isEmpty()) { return i18n("Input error: %1", errorString); } + if (Kleo::gpgComplianceP("de-vs")) + details += ((IS_DE_VS(res) + ? i18nc("VS-conforming is a German standard for restricted documents for which special restrictions about algorithms apply. The string states that the decryption is compliant with that.", + "The decryption is VS-compliant.") + : i18nc("VS-conforming is a German standard for restricted documents for which special restrictions about algorithms apply. The string states that the decryption is compliant with that.", + "The decryption is not VS-compliant.")) + + QStringLiteral("
")); + if (res.isNull() || !res.error() || res.error().isCanceled()) { if (!isSigned) { - return i18n("Note: You cannot be sure who encrypted this message as it is not signed."); + return details + i18n("Note: You cannot be sure who encrypted this message as it is not signed."); } - return QString(); + return details; } if (recipients.empty() && res.numRecipients() > 0) { - return QLatin1String("") + i18np("One unknown recipient.", "%1 unknown recipients.", res.numRecipients()) + QLatin1String(""); + return details + QLatin1String("") + i18np("One unknown recipient.", "%1 unknown recipients.", res.numRecipients()) + QLatin1String(""); } - QString details; if (!recipients.empty()) { details += i18np("Recipient:", "Recipients:", res.numRecipients()); if (res.numRecipients() == 1) { diff --git a/src/newcertificatewizard/newcertificatewizard.cpp b/src/newcertificatewizard/newcertificatewizard.cpp --- a/src/newcertificatewizard/newcertificatewizard.cpp +++ b/src/newcertificatewizard/newcertificatewizard.cpp @@ -108,10 +108,12 @@ // for GnuPG 2.1. The whole subkey / usage generation needs // new api and a reworked dialog. (ah 10.3.16) // EDDSA should be supported, too. -static const QStringList curveNames { +static const QStringList brainpoolCurveNames { { QStringLiteral("brainpoolP256r1") }, { QStringLiteral("brainpoolP384r1") }, { QStringLiteral("brainpoolP512r1") }, +}; +static const QStringList nistCurveNames { { QStringLiteral("NIST P-256") }, { QStringLiteral("NIST P-384") }, { QStringLiteral("NIST P-521") }, @@ -1766,15 +1768,22 @@ void AdvancedSettingsDialog::fillKeySizeComboBoxen() { + bool de_vs = Kleo::gpgComplianceP("de-vs"); const KConfigGroup config(KSharedConfig::openConfig(), "CertificateCreationWizard"); - const QList rsaKeySizes = config.readEntry(RSA_KEYSIZES_ENTRY, QList() << 1536 << -2048 << 3072 << 4096); + const QList rsaKeySizes = config.readEntry(RSA_KEYSIZES_ENTRY, + de_vs + ? QList() << -2048 << 3072 << 4096 + : QList() << 1536 << -2048 << 3072 << 4096); const QList dsaKeySizes = config.readEntry(DSA_KEYSIZES_ENTRY, QList() << -2048); const QList elgKeySizes = config.readEntry(ELG_KEYSIZES_ENTRY, QList() << 1536 << -2048 << 3072 << 4096); const QStringList rsaKeySizeLabels = config.readEntry(RSA_KEYSIZE_LABELS_ENTRY, QStringList()); const QStringList dsaKeySizeLabels = config.readEntry(DSA_KEYSIZE_LABELS_ENTRY, QStringList()); const QStringList elgKeySizeLabels = config.readEntry(ELG_KEYSIZE_LABELS_ENTRY, QStringList()); + const QStringList curveNames = (de_vs + ? brainpoolCurveNames + : brainpoolCurveNames + nistCurveNames); fill_combobox(*ui.rsaKeyStrengthCB, rsaKeySizes, rsaKeySizeLabels); fill_combobox(*ui.rsaKeyStrengthSubCB, rsaKeySizes, rsaKeySizeLabels); @@ -1817,6 +1826,8 @@ void AdvancedSettingsDialog::updateWidgetVisibility() { + bool de_vs = Kleo::gpgComplianceP("de-vs"); + // Personal Details Page if (protocol == OpenPGP) { // ### hide until multi-uid is implemented if (ui.tabWidget->indexOf(ui.personalTab) != -1) { @@ -1849,8 +1860,8 @@ } else { ui.rsaRB->setEnabled(true); ui.rsaSubCB->setEnabled(protocol == OpenPGP); - ui.dsaRB->setEnabled(protocol == OpenPGP); - ui.elgCB->setEnabled(protocol == OpenPGP); + ui.dsaRB->setEnabled(protocol == OpenPGP && ! de_vs); + ui.elgCB->setEnabled(protocol == OpenPGP && ! de_vs); ui.ecdsaRB->setEnabled(protocol == OpenPGP); ui.ecdhCB->setEnabled(protocol == OpenPGP); } diff --git a/src/utils/gnupg-helper.h b/src/utils/gnupg-helper.h --- a/src/utils/gnupg-helper.h +++ b/src/utils/gnupg-helper.h @@ -35,6 +35,21 @@ #include +/* Support compilation with GPGME older than 1.9. */ +#include +#if GPGMEPP_VERSION >= 0x10900 +# define GPGME_HAS_KEY_IS_DEVS +#endif + +/* Does the given object comply with DE_VS? This macro can be used to + ensure that we can still build against older versions of GPGME + without cluttering the code with preprocessor conditionals. */ +#ifdef GPGME_HAS_KEY_IS_DEVS +# define IS_DE_VS(x) (x).isDeVs() +#else +# define IS_DE_VS(x) 0 +#endif + class QString; class QStringList; @@ -59,6 +74,7 @@ bool engineIsVersion(int major, int minor, int patch, GpgME::Engine = GpgME::GpgConfEngine); bool haveKeyserverConfigured(); +bool gpgComplianceP(const char *mode); } #endif // __KLEOPATRA_GNUPGHELPER_H__ diff --git a/src/utils/gnupg-helper.cpp b/src/utils/gnupg-helper.cpp --- a/src/utils/gnupg-helper.cpp +++ b/src/utils/gnupg-helper.cpp @@ -275,3 +275,12 @@ const QGpgME::CryptoConfigEntry *const entry = config->entry(QStringLiteral("gpg"), QStringLiteral("Keyserver"), QStringLiteral("keyserver")); return entry && !entry->stringValue().isEmpty(); } + +bool Kleo::gpgComplianceP(const char *mode) +{ + auto conf = QGpgME::cryptoConfig(); + return (conf->entry(QStringLiteral("gpg"), + QStringLiteral("Configuration"), + QStringLiteral("compliance"))->stringValue() + == QString(mode)); +}