7#include "dkimchecksignaturejob.h"
8#include "dkimdownloadkeyjob.h"
10#include "dkimkeyrecord.h"
11#include "dkimmanagerkey.h"
13#include "messageviewer_dkimcheckerdebug.h"
15#include <KEmailAddress>
16#include <QCryptographicHash>
19#include <QRegularExpression>
21#include <openssl/bn.h>
22#include <openssl/core_names.h>
23#include <openssl/decoder.h>
24#include <openssl/err.h>
25#include <openssl/evp.h>
26#include <openssl/rsa.h>
30using namespace MessageViewer;
31DKIMCheckSignatureJob::DKIMCheckSignatureJob(
QObject *parent)
36DKIMCheckSignatureJob::~DKIMCheckSignatureJob() =
default;
38MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult DKIMCheckSignatureJob::createCheckResult()
const
40 MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult result;
41 result.error = mError;
42 result.warning = mWarning;
43 result.status = mStatus;
44 result.sdid = mDkimInfo.domain();
45 result.auid = mDkimInfo.agentOrUserIdentifier();
46 result.fromEmail = mFromEmail;
47 result.listSignatureAuthenticationResult = mCheckSignatureAuthenticationResult;
51QString DKIMCheckSignatureJob::bodyCanonizationResult()
const
53 return mBodyCanonizationResult;
56QString DKIMCheckSignatureJob::headerCanonizationResult()
const
58 return mHeaderCanonizationResult;
61void DKIMCheckSignatureJob::start()
64 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Item has not a message";
65 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
66 Q_EMIT result(createCheckResult());
70 if (
auto hrd = mMessage->headerByType(
"DKIM-Signature")) {
71 mDkimValue = hrd->asUnicodeString();
74 if (
auto hrd = mMessage->from(
false)) {
78 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::EmailNotSigned;
79 Q_EMIT result(createCheckResult());
83 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"mFromEmail " << mFromEmail;
84 if (!mDkimInfo.parseDKIM(mDkimValue)) {
85 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Impossible to parse header" << mDkimValue;
86 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
87 Q_EMIT result(createCheckResult());
92 const MessageViewer::DKIMCheckSignatureJob::DKIMStatus status = checkSignature(mDkimInfo);
93 if (status != MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Valid) {
95 Q_EMIT result(createCheckResult());
100 switch (mDkimInfo.bodyCanonization()) {
101 case MessageViewer::DKIMInfo::CanonicalizationType::Unknown:
102 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidBodyCanonicalization;
103 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
104 Q_EMIT result(createCheckResult());
107 case MessageViewer::DKIMInfo::CanonicalizationType::Simple:
108 mBodyCanonizationResult = bodyCanonizationSimple();
110 case MessageViewer::DKIMInfo::CanonicalizationType::Relaxed:
111 mBodyCanonizationResult = bodyCanonizationRelaxed();
116 if (mDkimInfo.bodyLengthCount() != -1) {
117 if (mDkimInfo.bodyLengthCount() > mBodyCanonizationResult.
length()) {
119 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
" mDkimInfo.bodyLengthCount() " << mDkimInfo.bodyLengthCount() <<
" mBodyCanonizationResult.length() "
120 << mBodyCanonizationResult.
length();
121 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::SignatureTooLarge;
122 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
123 Q_EMIT result(createCheckResult());
126 }
else if (mDkimInfo.bodyLengthCount() < mBodyCanonizationResult.
length()) {
127 mWarning = MessageViewer::DKIMCheckSignatureJob::DKIMWarning::SignatureTooSmall;
130 mBodyCanonizationResult = mBodyCanonizationResult.
left(mDkimInfo.bodyLengthCount());
133 mBodyCanonizationResult = mBodyCanonizationResult.
right(mBodyCanonizationResult.
length() - 2);
137 mBodyCanonizationResult.
replace(QStringLiteral(
" This is a multi-part message in MIME format"),
138 QStringLiteral(
"This is a multi-part message in MIME format"));
142 mBodyCanonizationResult.
replace(QStringLiteral(
" This is a cryptographically signed message in MIME format."),
143 QStringLiteral(
"This is a cryptographically signed message in MIME format."));
147 mBodyCanonizationResult.
remove(reg);
149#ifdef DEBUG_SIGNATURE_DKIM
150 QFile caFile(QStringLiteral(
"/tmp/bodycanon-kmail.txt"));
153 outStream << mBodyCanonizationResult;
158 switch (mDkimInfo.hashingAlgorithm()) {
159 case DKIMInfo::HashingAlgorithmType::Sha1:
162 case DKIMInfo::HashingAlgorithmType::Sha256:
165 case DKIMInfo::HashingAlgorithmType::Any:
166 case DKIMInfo::HashingAlgorithmType::Unknown:
167 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InsupportedHashAlgorithm;
168 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
169 Q_EMIT result(createCheckResult());
175 qDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"resultHash " << resultHash <<
"mDkimInfo.bodyHash()" << mDkimInfo.bodyHash();
176 if (resultHash != mDkimInfo.bodyHash().
toLatin1()) {
177 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
" Corrupted body hash";
178 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::CorruptedBodyHash;
179 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
180 Q_EMIT result(createCheckResult());
185 if (mDkimInfo.headerCanonization() == MessageViewer::DKIMInfo::CanonicalizationType::Unknown) {
186 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidHeaderCanonicalization;
187 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
188 Q_EMIT result(createCheckResult());
193 if (!mHeaderParser.wasAlreadyParsed()) {
194 mHeaderParser.setHead(mMessage->head());
195 mHeaderParser.parse();
198 computeHeaderCanonization(
true);
199 if (mPolicy.saveKey() == MessageViewer::MessageViewerSettings::EnumSaveKey::Save) {
200 const QString keyValue = MessageViewer::DKIMManagerKey::self()->keyValue(mDkimInfo.selector(), mDkimInfo.domain());
203 downloadKey(mDkimInfo);
205 parseDKIMKeyRecord(keyValue, mDkimInfo.domain(), mDkimInfo.selector(),
false);
206 MessageViewer::DKIMManagerKey::self()->updateLastUsed(mDkimInfo.domain(), mDkimInfo.selector());
209 downloadKey(mDkimInfo);
213void DKIMCheckSignatureJob::computeHeaderCanonization(
bool removeQuoteOnContentType)
216 switch (mDkimInfo.headerCanonization()) {
217 case MessageViewer::DKIMInfo::CanonicalizationType::Unknown:
219 case MessageViewer::DKIMInfo::CanonicalizationType::Simple:
220 mHeaderCanonizationResult = headerCanonizationSimple();
222 case MessageViewer::DKIMInfo::CanonicalizationType::Relaxed:
223 mHeaderCanonizationResult = headerCanonizationRelaxed(removeQuoteOnContentType);
246 QString dkimValue = mDkimValue;
248 switch (mDkimInfo.headerCanonization()) {
249 case MessageViewer::DKIMInfo::CanonicalizationType::Unknown:
251 case MessageViewer::DKIMInfo::CanonicalizationType::Simple:
252 mHeaderCanonizationResult +=
QLatin1StringView(
"\r\n") + MessageViewer::DKIMUtil::headerCanonizationSimple(QStringLiteral(
"dkim-signature"), dkimValue);
254 case MessageViewer::DKIMInfo::CanonicalizationType::Relaxed:
256 + MessageViewer::DKIMUtil::headerCanonizationRelaxed(QStringLiteral(
"dkim-signature"), dkimValue, removeQuoteOnContentType);
259#ifdef DEBUG_SIGNATURE_DKIM
264 outHeaderStream << mHeaderCanonizationResult;
269void DKIMCheckSignatureJob::setHeaderParser(
const DKIMHeaderParser &headerParser)
271 mHeaderParser = headerParser;
276 mCheckSignatureAuthenticationResult = lst;
279QString DKIMCheckSignatureJob::bodyCanonizationSimple()
const
296 return MessageViewer::DKIMUtil::bodyCanonizationSimple(
QString::fromLatin1(mMessage->encodedBody()));
299QString DKIMCheckSignatureJob::bodyCanonizationRelaxed()
const
324QString DKIMCheckSignatureJob::headerCanonizationSimple()
const
330 const auto listSignedHeader{mDkimInfo.listSignedHeader()};
331 for (
const QString &header : listSignedHeader) {
332 const QString str = parser.headerType(header.toLower());
337 headers += MessageViewer::DKIMUtil::headerCanonizationSimple(header, str);
343QString DKIMCheckSignatureJob::headerCanonizationRelaxed(
bool removeQuoteOnContentType)
const
370 const auto listSignedHeader = mDkimInfo.listSignedHeader();
371 for (
const QString &header : listSignedHeader) {
372 const QString str = parser.headerType(header.toLower());
377 headers += MessageViewer::DKIMUtil::headerCanonizationRelaxed(header, str, removeQuoteOnContentType);
383void DKIMCheckSignatureJob::downloadKey(
const DKIMInfo &info)
386 job->setDomainName(info.domain());
387 job->setSelectorName(info.selector());
388 connect(job, &DKIMDownloadKeyJob::error,
this, [
this](
const QString &errorString) {
389 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Impossible to start downloadkey: error returned: " << errorString;
390 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::ImpossibleToDownloadKey;
391 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
392 Q_EMIT result(createCheckResult());
395 connect(job, &DKIMDownloadKeyJob::success,
this, &DKIMCheckSignatureJob::slotDownloadKeyDone);
398 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Impossible to start downloadkey";
399 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::ImpossibleToDownloadKey;
400 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
401 Q_EMIT result(createCheckResult());
409 if (lst.
count() != 1) {
420void DKIMCheckSignatureJob::parseDKIMKeyRecord(
const QString &str,
const QString &domain,
const QString &selector,
bool storeKeyValue)
422 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG)
423 <<
"void DKIMCheckSignatureJob::parseDKIMKeyRecord(const QString &str, const QString &domain, const QString &selector, bool storeKeyValue) key:" << str;
424 if (!mDkimKeyRecord.parseKey(str)) {
425 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Impossible to parse key record " << str;
426 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
427 Q_EMIT result(createCheckResult());
431 const QString keyType{mDkimKeyRecord.keyType()};
433 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"mDkimKeyRecord key type is unknown " << keyType <<
" str " << str;
434 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
435 Q_EMIT result(createCheckResult());
448 if (mDkimInfo.iDomain() != mDkimInfo.domain()) {
449 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
450 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::DomainI;
451 Q_EMIT result(createCheckResult());
460 if (!mPolicy.verifySignatureWhenOnlyTest()) {
461 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Testing mode!";
462 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::TestKeyMode;
463 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
464 Q_EMIT result(createCheckResult());
469 if (mDkimKeyRecord.publicKey().
isEmpty()) {
471 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"mDkimKeyRecord public key is empty. It was revoked ";
472 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::PublicKeyWasRevoked;
473 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
474 Q_EMIT result(createCheckResult());
480 Q_EMIT storeKey(str, domain, selector);
486void DKIMCheckSignatureJob::verifySignature()
488 const QString keyType{mDkimKeyRecord.keyType()};
490 verifyRSASignature();
492 verifyEd25519Signature();
494 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
" It's a bug " << keyType;
498void DKIMCheckSignatureJob::verifyEd25519Signature()
501 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"it's a Ed25519 signed email";
502 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::PublicKeyConversionError;
503 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
504 Q_EMIT result(createCheckResult());
508using EVPPKeyPtr = std::unique_ptr<EVP_PKEY,
decltype(&EVP_PKEY_free)>;
510EVPPKeyPtr loadRSAPublicKey(
const QByteArray &der)
512 EVP_PKEY *pubKey =
nullptr;
513 std::unique_ptr<OSSL_DECODER_CTX,
decltype(&OSSL_DECODER_CTX_free)> decoderCtx(
514 OSSL_DECODER_CTX_new_for_pkey(&pubKey,
"DER",
nullptr,
"RSA", EVP_PKEY_PUBLIC_KEY,
nullptr,
nullptr),
515 OSSL_DECODER_CTX_free);
517 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Failed to create OSSL_DECODER_CTX";
518 return {
nullptr, EVP_PKEY_free};
522 std::unique_ptr<BIO,
decltype(&BIO_free)> pubKeyBio(BIO_new_mem_buf(rawDer.constData(), rawDer.size()), BIO_free);
523 if (!OSSL_DECODER_from_bio(decoderCtx.get(), pubKeyBio.get())) {
525 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Failed to decode public key:" << ERR_error_string(ERR_get_error(),
nullptr);
526 return {
nullptr, EVP_PKEY_free};
529 return {pubKey, EVP_PKEY_free};
532const EVP_MD *evpAlgo(DKIMInfo::HashingAlgorithmType algo)
535 case DKIMInfo::HashingAlgorithmType::Sha1:
537 case DKIMInfo::HashingAlgorithmType::Sha256:
539 case DKIMInfo::HashingAlgorithmType::Any:
540 case DKIMInfo::HashingAlgorithmType::Unknown:
546std::optional<bool> doVerifySignature(EVP_PKEY *key,
const EVP_MD *md,
const QByteArray &signature,
const QByteArray &message)
548 std::unique_ptr<EVP_MD_CTX,
decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
549 if (!EVP_MD_CTX_init(ctx.get())) {
550 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Failed to initialize signature verification:" << ERR_error_string(ERR_get_error(),
nullptr);
554 EVP_PKEY_CTX *pctx =
nullptr;
555 if (!EVP_DigestVerifyInit(ctx.get(), &pctx, md,
nullptr, key)) {
556 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Failed to initialize signature verification:" << ERR_error_string(ERR_get_error(),
nullptr);
560 EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING);
561 const auto result = EVP_DigestVerify(ctx.get(),
562 reinterpret_cast<const unsigned char *
>(signature.
constData()),
564 reinterpret_cast<const unsigned char *
>(message.constData()),
568 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Signature verification failed:" << ERR_error_string(ERR_get_error(),
nullptr);
572 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Signature successfully verified";
576uint64_t getKeyE(EVP_PKEY *key)
578 BIGNUM *bne =
nullptr;
579 EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_E, &bne);
580 const uint64_t size = BN_get_word(bne);
585void DKIMCheckSignatureJob::verifyRSASignature()
590 const auto publicKey = loadRSAPublicKey(mDkimKeyRecord.publicKey().
toLatin1());
592 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Failed to load public key";
593 return verificationFailed(DKIMError::PublicKeyConversionError);
595 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Success loading public key";
598 if (
const auto keyE = getKeyE(publicKey.get()); keyE * 4 < 1024) {
599 const int publicRsaTooSmallPolicyValue = mPolicy.publicRsaTooSmallPolicy();
600 if (publicRsaTooSmallPolicyValue == MessageViewer::MessageViewerSettings::EnumPublicRsaTooSmall::Nothing) {
602 }
else if (publicRsaTooSmallPolicyValue == MessageViewer::MessageViewerSettings::EnumPublicRsaTooSmall::Warning) {
603 mWarning = MessageViewer::DKIMCheckSignatureJob::DKIMWarning::PublicRsaKeyTooSmall;
604 }
else if (publicRsaTooSmallPolicyValue == MessageViewer::MessageViewerSettings::EnumPublicRsaTooSmall::Error) {
605 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::PublicKeyTooSmall;
606 mStatus = MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
607 Q_EMIT result(createCheckResult());
611 }
else if (keyE * 4 < 2048) {
616 const auto md = evpAlgo(mDkimInfo.hashingAlgorithm());
618 return verificationFailed(DKIMError::InvalidBodyHashAlgorithm);
622 if (
const auto result = doVerifySignature(publicKey.get(), md, signature, mHeaderCanonizationResult.toLatin1()); !result.has_value()) {
624 return verificationFailed(DKIMError::ImpossibleToVerifySignature);
625 }
else if (!result.value()) {
627 computeHeaderCanonization(
false);
628 if (
const auto result = doVerifySignature(publicKey.get(), md, signature, mHeaderCanonizationResult.toLatin1()); !result.has_value()) {
630 return verificationFailed(DKIMError::ImpossibleToVerifySignature);
631 }
else if (!result.value()) {
632 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Signature verification failed";
633 return verificationFailed(DKIMError::ImpossibleToVerifySignature);
637 mStatus = DKIMStatus::Valid;
638 Q_EMIT result(createCheckResult());
642void DKIMCheckSignatureJob::verificationFailed(DKIMError error)
645 mStatus = DKIMStatus::Invalid;
646 Q_EMIT result(createCheckResult());
660DKIMCheckSignatureJob::DKIMWarning DKIMCheckSignatureJob::warning()
const
665void DKIMCheckSignatureJob::setWarning(DKIMCheckSignatureJob::DKIMWarning warning)
680MessageViewer::DKIMCheckSignatureJob::DKIMStatus DKIMCheckSignatureJob::checkSignature(
const DKIMInfo &info)
683 if (info.expireTime() != -1 && info.expireTime() < currentDate) {
684 mWarning = DKIMCheckSignatureJob::DKIMWarning::SignatureExpired;
686 if (info.signatureTimeStamp() != -1 && info.signatureTimeStamp() > currentDate) {
687 mWarning = DKIMCheckSignatureJob::DKIMWarning::SignatureCreatedInFuture;
689 if (info.signature().
isEmpty()) {
690 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Signature doesn't exist";
691 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::MissingSignature;
692 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
695 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"From is not include in headers list";
696 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::MissingFrom;
697 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
700 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Domain is not defined.";
701 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::DomainNotExist;
702 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
705 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"Query is incorrect: " << info.query();
706 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidQueryMethod;
707 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
710 if ((info.hashingAlgorithm() == MessageViewer::DKIMInfo::HashingAlgorithmType::Any)
711 || (info.hashingAlgorithm() == MessageViewer::DKIMInfo::HashingAlgorithmType::Unknown)) {
712 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"body header algorithm is empty";
713 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidBodyHashAlgorithm;
714 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
716 if (info.signingAlgorithm().
isEmpty()) {
717 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"signature algorithm is empty";
718 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidSignAlgorithm;
719 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
722 if (info.hashingAlgorithm() == DKIMInfo::HashingAlgorithmType::Sha1) {
723 if (mPolicy.rsaSha1Policy() == MessageViewer::MessageViewerSettings::EnumPolicyRsaSha1::Nothing) {
725 }
else if (mPolicy.rsaSha1Policy() == MessageViewer::MessageViewerSettings::EnumPolicyRsaSha1::Warning) {
726 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"hash algorithm is not secure sha1 : Error";
727 mWarning = MessageViewer::DKIMCheckSignatureJob::DKIMWarning::HashAlgorithmUnsafe;
728 }
else if (mPolicy.rsaSha1Policy() == MessageViewer::MessageViewerSettings::EnumPolicyRsaSha1::Error) {
729 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"hash algorithm is not secure sha1: Error";
730 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::HashAlgorithmUnsafeSha1;
731 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
736 if (!info.agentOrUserIdentifier().
endsWith(info.iDomain())) {
737 qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) <<
"AUID is not in a subdomain of SDID";
738 mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::IDomainError;
739 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid;
743 return MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Valid;
746DKIMCheckSignatureJob::DKIMError DKIMCheckSignatureJob::error()
const
751DKIMCheckSignatureJob::DKIMStatus DKIMCheckSignatureJob::status()
const
756void DKIMCheckSignatureJob::setStatus(DKIMCheckSignatureJob::DKIMStatus
status)
761QString DKIMCheckSignatureJob::dkimValue()
const
766bool DKIMCheckSignatureJob::CheckSignatureResult::isValid()
const
768 return status != DKIMCheckSignatureJob::DKIMStatus::Unknown;
771bool DKIMCheckSignatureJob::CheckSignatureResult::operator==(
const DKIMCheckSignatureJob::CheckSignatureResult &other)
const
773 return error == other.error && warning == other.warning &&
status == other.status && fromEmail == other.fromEmail && auid == other.auid
774 && sdid == other.sdid && listSignatureAuthenticationResult == other.listSignatureAuthenticationResult;
777bool DKIMCheckSignatureJob::CheckSignatureResult::operator!=(
const DKIMCheckSignatureJob::CheckSignatureResult &other)
const
779 return !CheckSignatureResult::operator==(other);
784 d <<
" error " << t.error;
785 d <<
" warning " << t.warning;
786 d <<
" status " << t.status;
787 d <<
" signedBy " << t.sdid;
788 d <<
" fromEmail " << t.fromEmail;
789 d <<
" auid " << t.auid;
790 d <<
" authenticationResult " << t.listSignatureAuthenticationResult;
796 d <<
" method " << t.method;
797 d <<
" errorStr " << t.errorStr;
798 d <<
" status " << t.status;
799 d <<
" sdid " << t.sdid;
800 d <<
" auid " << t.auid;
801 d <<
" inforesult " << t.infoResult;
805bool DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult::operator==(
const DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult &other)
const
807 return errorStr == other.errorStr && method == other.method &&
status == other.status && sdid == other.sdid && auid == other.auid
808 && infoResult == other.infoResult;
811bool DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult::isValid()
const
814 return (method != AuthenticationMethod::Unknown);
817#include "moc_dkimchecksignaturejob.cpp"
The DKIMCheckPolicy class.
The DKIMDownloadKeyJob class.
Q_SCRIPTABLE CaptureState status()
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QDebug operator<<(QDebug dbg, const PerceptualColor::MultiSpinBoxSection &value)
const char * constData() const const
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
qsizetype size() const const
qint64 currentSecsSinceEpoch()
const_reference at(qsizetype i) const const
qsizetype count() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QString fromLatin1(QByteArrayView str)
QString fromLocal8Bit(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QString right(qsizetype n) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toLatin1() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const