diff --git a/autotests/expirycheckertest.cpp b/autotests/expirycheckertest.cpp
index 3c1b78f1d..59d93aa46 100644
--- a/autotests/expirycheckertest.cpp
+++ b/autotests/expirycheckertest.cpp
@@ -1,522 +1,535 @@
/*
This file is part of libkleopatra's test suite.
SPDX-FileCopyrightText: 2022 Sandro Knauß The OpenPGP key for alice@autocrypt.example (KeyID 0xF231550C4F47E38E) expired less than a day "
"ago. Your OpenPGP encryption key alice@autocrypt.example (KeyID 0xF231550C4F47E38E) expired one day "
- "ago. The OpenPGP key for alice@autocrypt.example (KeyID 0xF231550C4F47E38E) expired yesterday. Your OpenPGP signing key alice@autocrypt.example (KeyID 0xF231550C4F47E38E) expired 2 days ago. Your OpenPGP encryption key alice@autocrypt.example (KeyID 0xF231550C4F47E38E) expired 2 days "
+ "ago. The S/MIME certificate for CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US (serial "
"number 00D345203A186385C9) expired less than a day ago. Your S/MIME encryption certificate CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US "
- "(serial number 00D345203A186385C9) expired one day ago.
expired yesterday.
"); QTest::newRow("smime - own signing; 2 days ago") // << testKey("test@example.com", GpgME::CMS) // << ExpiryChecker::CheckFlags{ExpiryChecker::OwnSigningKey} // - << QDate{2013, 3, 28} // the third day after the expiration date of the key + << QDateTime{{2013, 3, 27}, {}, Qt::UTC} // the second day after the expiration date of the key << days{2} // << ExpiryChecker::OwnKeyExpired << QStringLiteral( "Your S/MIME signing certificate
CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " "(serial number 00D345203A186385C9)
expired 2 days ago.
"); } void expired() { QFETCH(GpgME::Key, key); QFETCH(ExpiryChecker::CheckFlags, checkFlags); - QFETCH(QDate, fakedate); + QFETCH(QDateTime, fakedate); QFETCH(Kleo::chrono::days, expectedDuration); QFETCH(ExpiryChecker::ExpiryInformation, expiryInfo); QFETCH(QString, msg); { ExpiryChecker checker(ExpiryCheckerSettings{days{1}, days{1}, days{1}, days{1}}); checker.setTimeProviderForTest(std::make_sharedThe OpenPGP key for
alice@autocrypt.example (KeyID 0xF231550C4F47E38E)
expires in less than 6 days.
") + "The OpenPGP key for
alice@autocrypt.example (KeyID 0xF231550C4F47E38E)
expires in 5 days.
") << QStringLiteral( - "Your OpenPGP encryption key
alice@autocrypt.example (KeyID 0xF231550C4F47E38E)
expires in less than 6 " + "
Your OpenPGP encryption key
alice@autocrypt.example (KeyID 0xF231550C4F47E38E)
expires in 5 " "days.
") << QStringLiteral( - "Your OpenPGP signing key
alice@autocrypt.example (KeyID 0xF231550C4F47E38E)
expires in less than 6 " + "
Your OpenPGP signing key
alice@autocrypt.example (KeyID 0xF231550C4F47E38E)
expires in 5 " "days.
"); QTest::newRow("smime") << testKey("test@example.com", GpgME::CMS) // - << QDate{2013, 3, 20} // + << QDateTime{{2013, 3, 20}, {}, Qt::UTC} // << days{5} << QStringLiteral( "The S/MIME certificate for
CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US (serial " - "number 00D345203A186385C9)
expires in less than 6 days.
") + "number 00D345203A186385C9)expires in 5 days.
") << QStringLiteral( "Your S/MIME encryption certificate
CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " - "(serial number 00D345203A186385C9)
expires in less than 6 days.
") + "(serial number 00D345203A186385C9)expires in 5 days.
") << QStringLiteral( "Your S/MIME signing certificate
CN=unittest cert,EMAIL=test@example.com,O=KDAB,C=US " - "(serial number 00D345203A186385C9)
expires in less than 6 days.
"); + "(serial number 00D345203A186385C9)expires in 5 days.
"); } void nearexpiry() { QFETCH(GpgME::Key, key); - QFETCH(QDate, fakedate); + QFETCH(QDateTime, fakedate); QFETCH(Kleo::chrono::days, expectedDuration); QFETCH(QString, msg); QFETCH(QString, msgOwnKey); QFETCH(QString, msgOwnSigningKey); { ExpiryChecker checker(ExpiryCheckerSettings{days{1}, days{10}, days{1}, days{1}}); checker.setTimeProviderForTest(std::make_sharedThe S/MIME certificate for
CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE " - "(serial number 51260A931CE27F9CC3A55F79E072AE82)
expires in less than 6 days.
"); + "(serial number 51260A931CE27F9CC3A55F79E072AE82)expires in 5 days.
"); QTest::newRow("certificate near expiry; issuer not checked") // << testKey("3193786A48BDF2D4D20B8FC6501F4DE8BE231B05", GpgME::CMS) // << ExpiryChecker::CheckFlags{ExpiryChecker::NoCheckFlags} // - << QDate{2019, 6, 19} // 5 days before expiration date of the certificate + << QDateTime{{2019, 6, 19}, {}, Qt::UTC} // 5 days before expiration date of the certificate << ExpiryChecker::ExpiresSoon // << days{5} // << 0 // issuer chain not checked << Key{} // ignored << ExpiryChecker::ExpirationStatus{} // ignored << days{} // ignored << 1 // expect 1 signal emission because certificate is near expiry << QByteArray{"501F4DE8BE231B05"} // signal emission references the certificate << QStringLiteral( "The S/MIME certificate for
CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE " - "(serial number 51260A931CE27F9CC3A55F79E072AE82)
expires in less than 6 days.
"); + "(serial number 51260A931CE27F9CC3A55F79E072AE82)expires in 5 days.
"); QTest::newRow("certificate okay; issuer near expiry") // << testKey("9E99817D12280C9677674430492EDA1DCE2E4C63", GpgME::CMS) // << ExpiryChecker::CheckFlags{ExpiryChecker::CheckChain} // - << QDate{2019, 6, 19} // 5 days before expiration date of the issuer certificate + << QDateTime{{2019, 6, 19}, {}, Qt::UTC} // 5 days before expiration date of the issuer certificate << ExpiryChecker::NotNearExpiry // << days{346} // << 1 // one expiring certificate in issuer chain << testKey("3193786A48BDF2D4D20B8FC6501F4DE8BE231B05", GpgME::CMS) // << ExpiryChecker::ExpiresSoon // << days{5} // << 1 // expect 1 signal emission because of a 2-certificate chain with 1 cert near expiry << QByteArray{"501F4DE8BE231B05"} // first signal emission references the isser certificate << QStringLiteral( "The intermediate CA certificate
CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust " "AB,C=SE
for S/MIME certificate
CN=UTN - DATACorp SGC,L=Salt Lake " "City,SP=UT,OU=http://www.usertrust.com,O=The USERTRUST Network,C=US (serial number 46EAF096054CC5E3FA65EA6E9F42C664)
expires in " - "less than 6 days.
"); + "5 days."); QTest::newRow("certificate okay; issuer not checked") // << testKey("9E99817D12280C9677674430492EDA1DCE2E4C63", GpgME::CMS) // << ExpiryChecker::CheckFlags{ExpiryChecker::NoCheckFlags} // - << QDate{2019, 6, 19} // 5 days before expiration date of the issuer certificate + << QDateTime{{2019, 6, 19}, {}, Qt::UTC} // 5 days before expiration date of the issuer certificate << ExpiryChecker::NotNearExpiry // << days{346} // << 0 // issuer chain not checked << Key{} // ignored << ExpiryChecker::ExpirationStatus{} // ignored << days{} // ignored << 0 // expect 0 signal emission because certificate is not near expiry << QByteArray{} // << QString{}; QTest::newRow("certificate near expiry; issuer expired") // << testKey("9E99817D12280C9677674430492EDA1DCE2E4C63", GpgME::CMS) // << ExpiryChecker::CheckFlags{ExpiryChecker::CheckChain} // - << QDate{2020, 5, 25} // 5 days before expiration date of the certificate + << QDateTime{{2020, 5, 25}, {}, Qt::UTC} // 5 days before expiration date of the certificate << ExpiryChecker::ExpiresSoon // << days{5} // << 1 // one expired certificate in issuer chain << testKey("3193786A48BDF2D4D20B8FC6501F4DE8BE231B05", GpgME::CMS) // << ExpiryChecker::Expired // - << days{335} // + << days{336} // << 2 // expect 2 signal emissions because both certificates in the 2-certificate chain are either expired or near expiry << QByteArray{"492EDA1DCE2E4C63"} // first signal emission references the certificate << QStringLiteral( "The S/MIME certificate for
CN=UTN - DATACorp SGC,L=Salt Lake City,SP=UT,OU=http://www.usertrust.com,O=The " - "USERTRUST Network,C=US (serial number 46EAF096054CC5E3FA65EA6E9F42C664)
expires in less than 6 days.
"); + "USERTRUST Network,C=US (serial number 46EAF096054CC5E3FA65EA6E9F42C664)expires in 5 days.
"); QTest::newRow("certificate near expiry; issuer not checked") << testKey("9E99817D12280C9677674430492EDA1DCE2E4C63", GpgME::CMS) // << ExpiryChecker::CheckFlags{ExpiryChecker::NoCheckFlags} // - << QDate{2020, 5, 25} // 5 days before expiration date of the certificate + << QDateTime{{2020, 5, 25}, {}, Qt::UTC} // 5 days before expiration date of the certificate << ExpiryChecker::ExpiresSoon // << days{5} // << 0 // issuer chain not checked << Key{} // ignored << ExpiryChecker::ExpirationStatus{} // ignored << days{} // ignored << 1 // expect 1 signal emission because certificate is near expiry << QByteArray{"492EDA1DCE2E4C63"} // first signal emission references the certificate << QStringLiteral( "The S/MIME certificate for
CN=UTN - DATACorp SGC,L=Salt Lake City,SP=UT,OU=http://www.usertrust.com,O=The " - "USERTRUST Network,C=US (serial number 46EAF096054CC5E3FA65EA6E9F42C664)
expires in less than 6 days.
"); + "USERTRUST Network,C=US (serial number 46EAF096054CC5E3FA65EA6E9F42C664)expires in 5 days.
"); } void certificateChain() { QFETCH(GpgME::Key, key); QFETCH(ExpiryChecker::CheckFlags, checkFlags); - QFETCH(QDate, fakedate); + QFETCH(QDateTime, fakedate); QFETCH(ExpiryChecker::ExpirationStatus, expectedStatus); QFETCH(Kleo::chrono::days, expectedDuration); QFETCH(int, expectedChainResults); QFETCH(GpgME::Key, expectedChainCertificate); QFETCH(ExpiryChecker::ExpirationStatus, expectedChainStatus); QFETCH(Kleo::chrono::days, expectedChainDuration); QFETCH(int, emissions); QFETCH(QByteArray, keyID); QFETCH(QString, msg); { ExpiryChecker checker(ExpiryCheckerSettings{days{1}, days{10}, days{10}, days{10}}); checker.setTimeProviderForTest(std::make_sharedYour OpenPGP signing key
%1
expired less than a day ago.
"); } else if (isOwnKey) { msg = ki18n("Your OpenPGP encryption key
%1
expired less than a day ago.
"); } else { msg = ki18n("The OpenPGP key for
%1
expired less than a day ago.
"); } return msg.subs(keyInfo).toString(); } KLocalizedString msg; if (isSigningKey) { - msg = ki18np( - "Your OpenPGP signing key
%2
" - "expired one day ago.
", - "Your OpenPGP signing key
%2
" - "expired %1 days ago.
"); + msg = ki18np("Your OpenPGP signing key
%2
expired yesterday.
", + "Your OpenPGP signing key
%2
expired %1 days ago.
"); } else if (isOwnKey) { - msg = ki18np( - "Your OpenPGP encryption key
%2
" - "expired one day ago.
", - "Your OpenPGP encryption key
%2
" - "expired %1 days ago.
"); + msg = ki18np("Your OpenPGP encryption key
%2
expired yesterday.
", + "Your OpenPGP encryption key
%2
expired %1 days ago.
"); } else { - msg = ki18np( - "The OpenPGP key for
%2
" - "expired one day ago.
", - "The OpenPGP key for
%2
" - "expired %1 days ago.
"); + msg = ki18np("The OpenPGP key for
%2
expired yesterday.
", + "The OpenPGP key for
%2
expired %1 days ago.
"); } return msg.subs(expiration.duration.count()).subs(keyInfo).toString(); } - qCDebug(LIBKLEO_LOG) << "Key" << key << "expires in less than" << expiration.duration.count() + 1 << "days"; + qCDebug(LIBKLEO_LOG) << "Key" << key << "expires in" << expiration.duration.count() << "days"; + if (expiration.duration.count() == 0) { + KLocalizedString msg; + if (isSigningKey) { + msg = ki18n("Your OpenPGP signing key
%1
expires today.
"); + } else if (isOwnKey) { + msg = ki18n("Your OpenPGP encryption key
%1
expires today.
"); + } else { + msg = ki18n("The OpenPGP key for
%1
expires today.
"); + } + return msg.subs(keyInfo).toString(); + } KLocalizedString msg; if (isSigningKey) { - msg = ki18np( - "Your OpenPGP signing key
%2
" - "expires in less than a day.
", - "Your OpenPGP signing key
%2
" - "expires in less than %1 days.
"); + msg = ki18np("Your OpenPGP signing key
%2
expires tomorrow.
", + "Your OpenPGP signing key
%2
expires in %1 days.
"); } else if (isOwnKey) { - msg = ki18np( - "Your OpenPGP encryption key
%2
" - "expires in less than a day.
", - "Your OpenPGP encryption key
%2
" - "expires in less than %1 days.
"); + msg = ki18np("Your OpenPGP encryption key
%2
expires tomorrow.
", + "Your OpenPGP encryption key
%2
expires in %1 days.
"); } else { - msg = ki18np( - "The OpenPGP key for
%2
" - "expires in less than a day.
", - "The OpenPGP key for
%2
" - "expires in less than %1 days.
"); + msg = ki18np("The OpenPGP key for
%2
expires tomorrow.
", + "The OpenPGP key for
%2
expires in %1 days.
"); } - return msg.subs(expiration.duration.count() + 1).subs(keyInfo).toString(); + return msg.subs(expiration.duration.count()).subs(keyInfo).toString(); } QString formatSMIMEMessage(const GpgME::Key &orig_key, ExpiryChecker::Expiration expiration, ExpiryChecker::CheckFlags flags, bool ca) { const GpgME::Key key = expiration.certificate; const bool isOwnKey = flags & ExpiryChecker::OwnKey; const bool isSigningKey = flags & ExpiryChecker::SigningKey; const auto userCert = orig_key.isNull() ? key : orig_key; const auto userCertInfo = ki18nc("User ID of certificate (serial number serial no. of certificate)", "%1 (serial number %2)") .subs(Kleo::DN(userCert.userID(0).id()).prettyDN()) .subs(QString::fromLatin1(userCert.issuerSerial())); if (expiration.status == ExpiryChecker::Expired) { qCDebug(LIBKLEO_LOG) << "Certificate" << key << "expired" << expiration.duration.count() << "days ago"; if (ca) { if (key.isRoot()) { if (expiration.duration.count() == 0) { KLocalizedString msg; if (isSigningKey) { msg = ki18n( "The root certificate
%2
" "for your S/MIME signing certificate
%1
" "expired less than a day ago.
"); } else if (isOwnKey) { msg = ki18n( "The root certificate
%2
" "for your S/MIME encryption certificate
%1
" "expired less than a day ago.
"); } else { msg = ki18n( "The root certificate
%2
" "for S/MIME certificate
%1
" "expired less than a day ago.
"); } return msg.subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); } KLocalizedString msg; if (isSigningKey) { msg = ki18np( "The root certificate
%3
" "for your S/MIME signing certificate
%2
" - "expired one day ago.
", + "expired yesterday.
", "The root certificate
%3
" "for your S/MIME signing certificate
%2
" "expired %1 days ago.
"); } else if (isOwnKey) { msg = ki18np( "The root certificate
%3
" "for your S/MIME encryption certificate
%2
" - "expired one day ago.
", + "expired yesterday.
", "The root certificate
%3
" "for your S/MIME encryption certificate
%2
" "expired %1 days ago.
"); } else { msg = ki18np( "The root certificate
%3
" "for S/MIME certificate
%2
" - "expired one day ago.
", + "expired yesterday.
", "The root certificate
%3
" "for S/MIME certificate
%2
" "expired %1 days ago.
"); } return msg.subs(expiration.duration.count()).subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); } else { if (expiration.duration.count() == 0) { KLocalizedString msg; if (isSigningKey) { msg = ki18n( "The intermediate CA certificate
%2
" "for your S/MIME signing certificate
%1
" "expired less than a day ago.
"); } else if (isOwnKey) { msg = ki18n( "The intermediate CA certificate
%2
" "for your S/MIME encryption certificate
%1
" "expired less than a day ago.
"); } else { msg = ki18n( "The intermediate CA certificate
%2
" "for S/MIME certificate
%1
" "expired less than a day ago.
"); } return msg.subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); } KLocalizedString msg; if (isSigningKey) { msg = ki18np( "The intermediate CA certificate
%3
" "for your S/MIME signing certificate
%2
" - "expired one day ago.
", + "expired yesterday.
", "The intermediate CA certificate
%3
" "for your S/MIME signing certificate
%2
" "expired %1 days ago.
"); } else if (isOwnKey) { msg = ki18np( "The intermediate CA certificate
%3
" "for your S/MIME encryption certificate
%2
" - "expired one day ago.
", + "expired yesterday.
", "The intermediate CA certificate
%3
" "for your S/MIME encryption certificate
%2
" "expired %1 days ago.
"); } else { msg = ki18np( "The intermediate CA certificate
%3
" "for S/MIME certificate
%2
" - "expired one day ago.
", + "expired yesterday.
", "The intermediate CA certificate
%3
" "for S/MIME certificate
%2
" "expired %1 days ago.
"); } return msg.subs(expiration.duration.count()).subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); } } else { if (expiration.duration.count() == 0) { KLocalizedString msg; if (isSigningKey) { msg = ki18n("Your S/MIME signing certificate
%1
expired less than a day ago.
"); } else if (isOwnKey) { msg = ki18n("Your S/MIME encryption certificate
%1
expired less than a day ago.
"); } else { msg = ki18n("The S/MIME certificate for
%1
expired less than a day ago.
"); } return msg.subs(userCertInfo).toString(); } KLocalizedString msg; if (isSigningKey) { - msg = ki18np( - "Your S/MIME signing certificate
%2
" - "expired one day ago.
", - "Your S/MIME signing certificate
%2
" - "expired %1 days ago.
"); + msg = ki18np("Your S/MIME signing certificate
%2
expired yesterday.
", + "Your S/MIME signing certificate
%2
expired %1 days ago.
"); } else if (isOwnKey) { - msg = ki18np( - "Your S/MIME encryption certificate
%2
" - "expired one day ago.
", - "Your S/MIME encryption certificate
%2
" - "expired %1 days ago.
"); + msg = ki18np("Your S/MIME encryption certificate
%2
expired yesterday.
", + "Your S/MIME encryption certificate
%2
expired %1 days ago.
"); } else { - msg = ki18np( - "The S/MIME certificate for
%2
" - "expired one day ago.
", - "The S/MIME certificate for
%2
" - "expired %1 days ago.
"); + msg = ki18np("The S/MIME certificate for
%2
expired yesterday.
", + "The S/MIME certificate for
%2
expired %1 days ago.
"); } return msg.subs(expiration.duration.count()).subs(userCertInfo).toString(); } } - qCDebug(LIBKLEO_LOG) << "Certificate" << key << "expires in less than" << expiration.duration.count() + 1 << "days"; - KLocalizedString msg; + qCDebug(LIBKLEO_LOG) << "Certificate" << key << "expires in" << expiration.duration.count() << "days"; if (ca) { if (key.isRoot()) { + if (expiration.duration.count() == 0) { + KLocalizedString msg; + if (isSigningKey) { + msg = ki18n( + "The root certificate
%3
" + "for your S/MIME signing certificate
%2
" + "expires today.
"); + } else if (isOwnKey) { + msg = ki18n( + "The root certificate
%3
" + "for your S/MIME encryption certificate
%2
" + "expires today.
"); + } else { + msg = ki18n( + "The root certificate
%3
" + "for S/MIME certificate
%2
" + "expires today.
"); + } + return msg.subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); + } + KLocalizedString msg; if (isSigningKey) { msg = ki18np( "The root certificate
%3
" "for your S/MIME signing certificate
%2
" - "expires in less than a day.
", + "expires tomorrow.
", "The root certificate
%3
" "for your S/MIME signing certificate
%2
" - "expires in less than %1 days.
"); + "expires in %1 days.
"); } else if (isOwnKey) { msg = ki18np( "The root certificate
%3
" "for your S/MIME encryption certificate
%2
" - "expires in less than a day.
", + "expires tomorrow.
", "The root certificate
%3
" "for your S/MIME encryption certificate
%2
" - "expires in less than %1 days.
"); + "expires in %1 days.
"); } else { msg = ki18np( "The root certificate
%3
" "for S/MIME certificate
%2
" - "expires in less than a day.
", + "expires tomorrow.
", "The root certificate
%3
" "for S/MIME certificate
%2
" - "expires in less than %1 days.
"); + "expires in %1 days.
"); } - } else { + return msg.subs(expiration.duration.count()).subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); + } + if (expiration.duration.count() == 0) { + KLocalizedString msg; if (isSigningKey) { - msg = ki18np( - "The intermediate CA certificate
%3
" - "for your S/MIME signing certificate
%2
" - "expires in less than a day.
", + msg = ki18n( "The intermediate CA certificate
%3
" "for your S/MIME signing certificate
%2
" - "expires in less than %1 days.
"); + "expires today.
"); } else if (isOwnKey) { - msg = ki18np( + msg = ki18n( "The intermediate CA certificate
%3
" "for your S/MIME encryption certificate
%2
" - "expires in less than a day.
", - "The intermediate CA certificate
%3
" - "for your S/MIME encryption certificate
%2
" - "expires in less than %1 days.
"); + "expires today.
"); } else { - msg = ki18np( + msg = ki18n( "The intermediate CA certificate
%3
" "for S/MIME certificate
%2
" - "expires in less than a day.
", - "The intermediate CA certificate
%3
" - "for S/MIME certificate
%2
" - "expires in less than %1 days.
"); + "expires today.
"); } } - return msg.subs(expiration.duration.count() + 1).subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); + KLocalizedString msg; + if (isSigningKey) { + msg = ki18np( + "The intermediate CA certificate
%3
" + "for your S/MIME signing certificate
%2
" + "expires tomorrow.
", + "The intermediate CA certificate
%3
" + "for your S/MIME signing certificate
%2
" + "expires in %1 days.
"); + } else if (isOwnKey) { + msg = ki18np( + "The intermediate CA certificate
%3
" + "for your S/MIME encryption certificate
%2
" + "expires tomorrow.
", + "The intermediate CA certificate
%3
" + "for your S/MIME encryption certificate
%2
" + "expires in %1 days.
"); + } else { + msg = ki18np( + "The intermediate CA certificate
%3
" + "for S/MIME certificate
%2
" + "expires tomorrow.
", + "The intermediate CA certificate
%3
" + "for S/MIME certificate
%2
" + "expires in %1 days.
"); + } + return msg.subs(expiration.duration.count()).subs(userCertInfo).subs(Kleo::DN(key.userID(0).id()).prettyDN()).toString(); } + if (expiration.duration.count() == 0) { + KLocalizedString msg; + if (isSigningKey) { + msg = ki18n("Your S/MIME signing certificate
%2
expires today.
"); + } else if (isOwnKey) { + msg = ki18n("Your S/MIME encryption certificate
%2
expires today.
"); + } else { + msg = ki18n("The S/MIME certificate for
%2
expires today.
"); + } + return msg.subs(userCertInfo).toString(); + } + KLocalizedString msg; if (isSigningKey) { msg = ki18np( "Your S/MIME signing certificate
%2
" - "expires in less than a day.
", + "expires tomorrow.
", "Your S/MIME signing certificate
%2
" - "expires in less than %1 days.
"); + "expires in %1 days.
"); } else if (isOwnKey) { msg = ki18np( "Your S/MIME encryption certificate
%2
" - "expires in less than a day.
", + "expires tomorrow.
", "Your S/MIME encryption certificate
%2
" - "expires in less than %1 days.
"); + "expires in %1 days.
"); } else { msg = ki18np( "The S/MIME certificate for
%2
" - "expires in less than a day.
", + "expires tomorrow.
", "The S/MIME certificate for
%2
" - "expires in less than %1 days.
"); + "expires in %1 days.
"); } - return msg.subs(expiration.duration.count() + 1).subs(userCertInfo).toString(); + return msg.subs(expiration.duration.count()).subs(userCertInfo).toString(); } ExpiryChecker::Expiration ExpiryCheckerPrivate::calculateExpiration(const GpgME::Key &key) const { const GpgME::Subkey subkey = key.subkey(0); if (subkey.neverExpires()) { return {key, ExpiryChecker::NotNearExpiry, Kleo::chrono::days::zero()}; } - const time_t t = timeProvider ? timeProvider->getTime() : std::time(nullptr); - // casting the double-valued difference (returned by std::difftime) of two non-negative time_t to a time_t is no problem; - // negative values for expiration time and current time can be safely ignored - const time_t secsTillExpiry = static_cast