File indexing completed on 2025-03-09 04:54:29
0001 /* 0002 SPDX-FileCopyrightText: 2018-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "messageviewer_export.h" 0010 #include <KMime/Message> 0011 #include <MessageViewer/DKIMCheckPolicy> 0012 #include <MessageViewer/DKIMHeaderParser> 0013 #include <MessageViewer/DKIMInfo> 0014 #include <MessageViewer/DKIMKeyRecord> 0015 #include <QObject> 0016 0017 namespace MessageViewer 0018 { 0019 /** 0020 * @brief The DKIMCheckSignatureJob class 0021 * @author Laurent Montel <montel@kde.org> 0022 */ 0023 class MESSAGEVIEWER_EXPORT DKIMCheckSignatureJob : public QObject 0024 { 0025 Q_OBJECT 0026 public: 0027 enum class DKIMStatus : int { 0028 Unknown = 0, 0029 Valid = 1, 0030 Invalid = 2, 0031 EmailNotSigned = 3, 0032 NeedToBeSigned = 4, 0033 }; 0034 Q_ENUM(DKIMStatus) 0035 0036 enum class DKIMError : int { 0037 Any = 0, 0038 CorruptedBodyHash = 1, 0039 DomainNotExist = 2, 0040 MissingFrom = 3, 0041 MissingSignature = 4, 0042 InvalidQueryMethod = 5, 0043 InvalidHeaderCanonicalization = 6, 0044 InvalidBodyCanonicalization = 7, 0045 InvalidBodyHashAlgorithm = 8, 0046 InvalidSignAlgorithm = 9, 0047 PublicKeyWasRevoked = 10, 0048 SignatureTooLarge = 11, 0049 InsupportedHashAlgorithm = 12, 0050 PublicKeyTooSmall = 13, 0051 ImpossibleToVerifySignature = 14, 0052 DomainI = 15, 0053 TestKeyMode = 16, 0054 ImpossibleToDownloadKey = 17, 0055 HashAlgorithmUnsafeSha1 = 18, 0056 IDomainError = 19, 0057 PublicKeyConversionError = 20, 0058 }; 0059 Q_ENUM(DKIMError) 0060 enum class DKIMWarning : int { 0061 Any = 0, 0062 SignatureExpired = 1, 0063 SignatureCreatedInFuture = 2, 0064 SignatureTooSmall = 3, 0065 HashAlgorithmUnsafe = 4, 0066 PublicRsaKeyTooSmall = 5, 0067 }; 0068 Q_ENUM(DKIMWarning) 0069 0070 enum class AuthenticationMethod : int { 0071 Unknown = 0, 0072 Dkim = 1, 0073 Spf = 2, 0074 Dmarc = 3, 0075 Dkimatps = 4, 0076 Auth = 5, 0077 }; 0078 Q_ENUM(AuthenticationMethod) 0079 0080 struct MESSAGEVIEWER_EXPORT DKIMCheckSignatureAuthenticationResult { 0081 QString errorStr; 0082 QString infoResult; 0083 AuthenticationMethod method = AuthenticationMethod::Unknown; 0084 DKIMCheckSignatureJob::DKIMStatus status = DKIMCheckSignatureJob::DKIMStatus::Unknown; 0085 QString sdid; // Signing Domain Identifier 0086 QString auid; // DKIM MAY optionally provide a single responsible Agent or User Identifier (AUID). 0087 [[nodiscard]] bool operator==(const DKIMCheckSignatureAuthenticationResult &other) const; 0088 [[nodiscard]] bool isValid() const; 0089 }; 0090 0091 struct MESSAGEVIEWER_EXPORT CheckSignatureResult { 0092 [[nodiscard]] bool isValid() const; 0093 0094 [[nodiscard]] bool operator==(const CheckSignatureResult &other) const; 0095 0096 [[nodiscard]] bool operator!=(const CheckSignatureResult &other) const; 0097 0098 DKIMCheckSignatureJob::DKIMError error = DKIMCheckSignatureJob::DKIMError::Any; 0099 DKIMCheckSignatureJob::DKIMWarning warning = DKIMCheckSignatureJob::DKIMWarning::Any; 0100 DKIMCheckSignatureJob::DKIMStatus status = DKIMCheckSignatureJob::DKIMStatus::Unknown; 0101 QString sdid; // Signing Domain Identifier 0102 QString auid; // DKIM MAY optionally provide a single responsible Agent or User Identifier (AUID). 0103 QString fromEmail; 0104 0105 QList<DKIMCheckSignatureAuthenticationResult> listSignatureAuthenticationResult; 0106 }; 0107 0108 explicit DKIMCheckSignatureJob(QObject *parent = nullptr); 0109 ~DKIMCheckSignatureJob() override; 0110 void start(); 0111 0112 [[nodiscard]] QString dkimValue() const; 0113 0114 [[nodiscard]] DKIMCheckSignatureJob::DKIMStatus status() const; 0115 void setStatus(MessageViewer::DKIMCheckSignatureJob::DKIMStatus status); 0116 0117 [[nodiscard]] MessageViewer::DKIMCheckSignatureJob::DKIMStatus checkSignature(const MessageViewer::DKIMInfo &info); 0118 0119 [[nodiscard]] DKIMCheckSignatureJob::DKIMError error() const; 0120 0121 [[nodiscard]] KMime::Message::Ptr message() const; 0122 void setMessage(const KMime::Message::Ptr &message); 0123 0124 [[nodiscard]] DKIMCheckSignatureJob::DKIMWarning warning() const; 0125 void setWarning(MessageViewer::DKIMCheckSignatureJob::DKIMWarning warning); 0126 0127 [[nodiscard]] QString headerCanonizationResult() const; 0128 0129 [[nodiscard]] QString bodyCanonizationResult() const; 0130 0131 [[nodiscard]] DKIMCheckPolicy policy() const; 0132 void setPolicy(const DKIMCheckPolicy &policy); 0133 0134 void setHeaderParser(const DKIMHeaderParser &headerParser); 0135 0136 void setCheckSignatureAuthenticationResult(const QList<DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult> &lst); 0137 0138 Q_SIGNALS: 0139 void result(const MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult &checkResult); 0140 void storeKey(const QString &key, const QString &domain, const QString &selector); 0141 0142 private: 0143 MESSAGEVIEWER_NO_EXPORT void downloadKey(const DKIMInfo &info); 0144 MESSAGEVIEWER_NO_EXPORT void slotDownloadKeyDone(const QList<QByteArray> &lst, const QString &domain, const QString &selector); 0145 MESSAGEVIEWER_NO_EXPORT void parseDKIMKeyRecord(const QString &str, const QString &domain, const QString &selector, bool storeKeyValue = true); 0146 [[nodiscard]] MESSAGEVIEWER_NO_EXPORT QString headerCanonizationSimple() const; 0147 [[nodiscard]] MESSAGEVIEWER_NO_EXPORT QString headerCanonizationRelaxed(bool removeQuoteOnContentType) const; 0148 [[nodiscard]] MESSAGEVIEWER_NO_EXPORT QString bodyCanonizationRelaxed() const; 0149 [[nodiscard]] MESSAGEVIEWER_NO_EXPORT QString bodyCanonizationSimple() const; 0150 [[nodiscard]] MESSAGEVIEWER_NO_EXPORT MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult createCheckResult() const; 0151 MESSAGEVIEWER_NO_EXPORT void verifySignature(); 0152 MESSAGEVIEWER_NO_EXPORT void verifyRSASignature(); 0153 MESSAGEVIEWER_NO_EXPORT void verifyEd25519Signature(); 0154 MESSAGEVIEWER_NO_EXPORT void computeHeaderCanonization(bool removeQuoteOnContentType); 0155 QList<DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult> mCheckSignatureAuthenticationResult; 0156 DKIMCheckPolicy mPolicy; 0157 DKIMHeaderParser mHeaderParser; 0158 KMime::Message::Ptr mMessage; 0159 QString mFromEmail; 0160 DKIMInfo mDkimInfo; 0161 DKIMKeyRecord mDkimKeyRecord; 0162 QString mDkimValue; 0163 QString mHeaderCanonizationResult; 0164 QString mBodyCanonizationResult; 0165 DKIMCheckSignatureJob::DKIMError mError = DKIMCheckSignatureJob::DKIMError::Any; 0166 DKIMCheckSignatureJob::DKIMWarning mWarning = DKIMCheckSignatureJob::DKIMWarning::Any; 0167 DKIMCheckSignatureJob::DKIMStatus mStatus = DKIMCheckSignatureJob::DKIMStatus::Unknown; 0168 }; 0169 } 0170 MESSAGEVIEWER_EXPORT QDebug operator<<(QDebug d, const MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult &t); 0171 MESSAGEVIEWER_EXPORT QDebug operator<<(QDebug d, const MessageViewer::DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult &t); 0172 Q_DECLARE_METATYPE(MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult) 0173 Q_DECLARE_TYPEINFO(MessageViewer::DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult, Q_RELOCATABLE_TYPE);