diff --git a/src/kcfg/settings.kcfg b/src/kcfg/settings.kcfg
index 7d4263fec..74c8c7f1f 100644
--- a/src/kcfg/settings.kcfg
+++ b/src/kcfg/settings.kcfg
@@ -1,198 +1,198 @@
This text will be used as placeholder text for the common name (CN) field of S/MIME certificates.If true, then the common name (CN) field of S/MIME certificates will be prefilled with information gathered from the system,
e.g., from the email settings of the desktop or, on Windows, from the Active Directory.trueThis text will be used as placeholder text for the email address field of OpenPGP and S/MIME certificates.If true, then the email address field of OpenPGP and S/MIME certificates will be prefilled with information gathered from the system,
e.g., from the email settings of the desktop or, on Windows, from the Active Directory.trueThis text will be used as placeholder text for the name field of OpenPGP certificates.If true, then the name field of OpenPGP certificates will be prefilled with information gathered from the system,
e.g., from the email settings of the desktop or, on Windows, from the Active Directory.trueSpecifies the default validity period of new OpenPGP keys in days.
- This setting specifies how many days a new OpenPGP key is valid by default, or, in other words, after how many days the key will expire. Set this to 0 for unlimited validity. If this setting is not set or if it is set to a negative value, then new OpenPGP keys will be valid for two years (possibly clamped to the allowed minimum or maximum validity period) by default.
+ This setting specifies how many days a new OpenPGP key is valid by default, or, in other words, after how many days the key will expire. Set this to 0 for unlimited validity. If this setting is not set or if it is set to a negative value, then new OpenPGP keys will be valid for three years (possibly clamped to the allowed minimum or maximum validity period) by default.-1Specifies the minimum validity period of new OpenPGP keys in days.This setting specifies how many days a new OpenPGP key is valid at least, or, in other words, after how many days the new key will expire at the earliest.0Specifies the maximum validity period of new OpenPGP keys in days.This setting specifies how many days a new OpenPGP key is valid at most, or, in other words, after how many days the new key will expire at the latest. If this setting is not set or if it is set to a negative value, then unlimited validity is allowed.-1If true, hides the advanced settings button in the new certificate wizard.falseSpecifies the default validity of certifications in days.This setting specifies how many days a certification is valid by default, or, in other words, after how many days a new certification will expire. Set this to 0 for unlimited validity of certifications.0sha256sumIf true, then the results are shown after successfully signing the clipboard.trueIf true, then the results are shown after successfully encrypting the clipboard.trueEnables support for S/MIME (CMS).If false, then Kleopatra's main UI will not offer any functionality related to S/MIME (CMS).trueAllows the creation of S/MIME certificate signing requests.If false, then Kleopatra will not offer the creation of S/MIME certificate signing requests.trueAllows signing of text or files with S/MIME certificates.If false, then Kleopatra will not offer functionality for creating signatures with S/MIME certificates.truetruetruetruetruetruetrueSpecifies the display order of the DN attributes of X.509 certificates.Enable usage of groups of keys.Enable usage of groups of keys to create lists of recipients.trueIf enabled, then Kleopatra will automatically try to retrieve the keys
that were used to certify the user ids of newly imported OpenPGP keys. This is
useful in combination with trusted introducers.falseIf enabled, then Kleopatra will show notifications in some place when using
certificates that are about to expire soon.trueThis is a list of URL schemes that shall be blocked by the application.
This can be used to prevent the application from opening external applications for certain URLs.Searches for the certificates belonging the smartcard keys on the configured keyserver.Searches on keyservers regardless of the protocol for the smartcards key, regardless
of the keyserver protocol. Default behavior is to only do this for LDAP keyservers.falseAutomatically load S/MIME certificates from PKCS#15 (CardOS) smartcardsIf true, then Kleopatra will call gpgsm --learn if a PKCS#15 Smartcard is inserted with unknown certificates. This can take a while and blocks the smartcard while the command is running.truefalse
diff --git a/src/utils/keys.cpp b/src/utils/keys.cpp
index 5f44f1af1..a4ba020a7 100644
--- a/src/utils/keys.cpp
+++ b/src/utils/keys.cpp
@@ -1,179 +1,179 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/keys.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "keys.h"
#include
#include
#include
#include
#include
// needed for GPGME_VERSION_NUMBER
#include
#include
#include
namespace
{
bool isLastValidUserID(const GpgME::UserID &userId)
{
if (Kleo::isRevokedOrExpired(userId)) {
return false;
}
const auto userIds = userId.parent().userIDs();
const int numberOfValidUserIds = std::count_if(std::begin(userIds), std::end(userIds),
[](const auto &u) {
return !Kleo::isRevokedOrExpired(u);
});
return numberOfValidUserIds == 1;
}
bool hasValidUserID(const GpgME::Key &key)
{
return Kleo::any_of(key.userIDs(), [](const auto &u) {
return !Kleo::isRevokedOrExpired(u);
});
}
}
bool Kleo::isSelfSignature(const GpgME::UserID::Signature &signature)
{
return !qstrcmp(signature.parent().parent().keyID(), signature.signerKeyID());
}
bool Kleo::isRevokedOrExpired(const GpgME::UserID &userId)
{
if (userId.isRevoked() || userId.parent().isExpired()) {
return true;
}
const auto sigs = userId.signatures();
std::vector selfSigs;
std::copy_if(std::begin(sigs), std::end(sigs), std::back_inserter(selfSigs), &Kleo::isSelfSignature);
std::sort(std::begin(selfSigs), std::end(selfSigs));
// check the most recent signature
const auto sig = !selfSigs.empty() ? selfSigs.back() : GpgME::UserID::Signature{};
return !sig.isNull() && (sig.isRevokation() || sig.isExpired());
}
bool Kleo::canCreateCertifications(const GpgME::Key &key)
{
return key.canCertify() && canBeUsedForSecretKeyOperations(key);
}
bool Kleo::canBeCertified(const GpgME::Key &key)
{
return key.protocol() == GpgME::OpenPGP //
&& !key.isBad() //
&& hasValidUserID(key);
}
bool Kleo::canBeUsedForSecretKeyOperations(const GpgME::Key &key)
{
#if GPGME_VERSION_NUMBER >= 0x011102 // 1.17.2
// we need to check the primary subkey because Key::hasSecret() is also true if just the secret key stub of an offline key is available
return key.subkey(0).isSecret();
#else
// older versions of GpgME did not always set the secret flag for card keys
return key.subkey(0).isSecret() || key.subkey(0).isCardKey();
#endif
}
bool Kleo::canRevokeUserID(const GpgME::UserID &userId)
{
return (!userId.isNull() //
&& userId.parent().protocol() == GpgME::OpenPGP
&& !isLastValidUserID(userId));
}
bool Kleo::isSecretKeyStoredInKeyRing(const GpgME::Key &key)
{
return key.subkey(0).isSecret() && !key.subkey(0).isCardKey();
}
bool Kleo::userHasCertificationKey()
{
const auto secretKeys = KeyCache::instance()->secretKeys();
return Kleo::any_of(secretKeys, [](const auto &k) {
return (k.protocol() == GpgME::OpenPGP) && canCreateCertifications(k);
});
}
Kleo::CertificationRevocationFeasibility Kleo::userCanRevokeCertification(const GpgME::UserID::Signature &certification)
{
const auto certificationKey = KeyCache::instance()->findByKeyIDOrFingerprint(certification.signerKeyID());
const bool isSelfSignature = qstrcmp(certification.parent().parent().keyID(), certification.signerKeyID()) == 0;
if (!certificationKey.hasSecret()) {
return CertificationNotMadeWithOwnKey;
} else if (isSelfSignature) {
return CertificationIsSelfSignature;
} else if (certification.isRevokation()) {
return CertificationIsRevocation;
} else if (certification.isExpired()) {
return CertificationIsExpired;
} else if (certification.isInvalid()) {
return CertificationIsInvalid;
} else if (!canCreateCertifications(certificationKey)) {
return CertificationKeyNotAvailable;
}
return CertificationCanBeRevoked;
}
bool Kleo::userCanRevokeCertifications(const GpgME::UserID &userId)
{
if (userId.numSignatures() == 0) {
qCWarning(KLEOPATRA_LOG) << __func__ << "- Error: Signatures of user ID" << QString::fromUtf8(userId.id()) << "not available";
}
return Kleo::any_of(userId.signatures(), [](const auto &certification) {
return userCanRevokeCertification(certification) == CertificationCanBeRevoked;
});
}
bool Kleo::userIDBelongsToKey(const GpgME::UserID &userID, const GpgME::Key &key)
{
return !qstricmp(userID.parent().primaryFingerprint(), key.primaryFingerprint());
}
static time_t creationDate(const GpgME::UserID &uid)
{
// returns the date of the first self-signature
for (unsigned int i = 0, numSignatures = uid.numSignatures(); i < numSignatures; ++i) {
const auto sig = uid.signature(i);
if (Kleo::isSelfSignature(sig)) {
return sig.creationTime();
}
}
return 0;
}
bool Kleo::userIDsAreEqual(const GpgME::UserID &lhs, const GpgME::UserID &rhs)
{
return (qstrcmp(lhs.parent().primaryFingerprint(), rhs.parent().primaryFingerprint()) == 0
&& qstrcmp(lhs.id(), rhs.id()) == 0
&& creationDate(lhs) == creationDate(rhs));
}
QDate Kleo::defaultExpirationDate(Kleo::ExpirationOnUnlimitedValidity onUnlimitedValidity)
{
QDate expirationDate;
const auto settings = Kleo::Settings{};
const auto defaultExpirationInDays = settings.validityPeriodInDays();
if (defaultExpirationInDays > 0) {
expirationDate = QDate::currentDate().addDays(defaultExpirationInDays);
} else if (defaultExpirationInDays < 0 || onUnlimitedValidity == ExpirationOnUnlimitedValidity::InternalDefaultExpiration) {
- expirationDate = QDate::currentDate().addYears(2);
+ expirationDate = QDate::currentDate().addYears(3);
}
return expirationDate;
}