summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/mime/mimetreeparser
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2018-05-05 10:39:32 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-05-06 17:21:01 +0200
commit01594e68275a09c67b5ee258e2af86598118a6a0 (patch)
tree4f859815f6455906bb656f9cc27ba5d6e4111599 /framework/src/domain/mime/mimetreeparser
parent481cb9f600caf3f45596bf78b5ba2bd07007969c (diff)
downloadkube-01594e68275a09c67b5ee258e2af86598118a6a0.tar.gz
kube-01594e68275a09c67b5ee258e2af86598118a6a0.zip
Port to gpgme only.
QGpgme and Gpgmepp are not readily available, the cmake files buggy, the buildsystem horrendous and generally just difficult to build on windows. Given that all they are is a wrapper around gpgme, we're better of without all the indirections. What we loose is: * QGpgme moved the work to separate threads (but we then blocked anyways), something that we can just do in our own code should we want to. * QGpgme has a function to prettify dn's that was used to show the signer. Also something we could bring back should we need to (don't know where it is useful atm.) Ported messagepart to gpgme Almost there Moved the crypto bits to a separate file All gpg code is in one place. All tests passing Use error codes Cleanup
Diffstat (limited to 'framework/src/domain/mime/mimetreeparser')
-rw-r--r--framework/src/domain/mime/mimetreeparser/CMakeLists.txt7
-rw-r--r--framework/src/domain/mime/mimetreeparser/autotests/CMakeLists.txt6
-rw-r--r--framework/src/domain/mime/mimetreeparser/messagepart.cpp283
-rw-r--r--framework/src/domain/mime/mimetreeparser/messagepart.h21
-rw-r--r--framework/src/domain/mime/mimetreeparser/partmetadata.h1
-rw-r--r--framework/src/domain/mime/mimetreeparser/tests/CMakeLists.txt5
6 files changed, 90 insertions, 233 deletions
diff --git a/framework/src/domain/mime/mimetreeparser/CMakeLists.txt b/framework/src/domain/mime/mimetreeparser/CMakeLists.txt
index b35bd958..c3f317ee 100644
--- a/framework/src/domain/mime/mimetreeparser/CMakeLists.txt
+++ b/framework/src/domain/mime/mimetreeparser/CMakeLists.txt
@@ -2,9 +2,8 @@ set(CMAKE_CXX_VISIBILITY_PRESET default)
2 2
3find_package(Qt5 COMPONENTS REQUIRED Core Gui) 3find_package(Qt5 COMPONENTS REQUIRED Core Gui)
4find_package(KF5Mime 4.87.0 CONFIG REQUIRED) 4find_package(KF5Mime 4.87.0 CONFIG REQUIRED)
5find_package(QGpgme CONFIG REQUIRED)
6find_package(Gpgmepp CONFIG REQUIRED)
7find_package(KF5Codecs CONFIG REQUIRED) 5find_package(KF5Codecs CONFIG REQUIRED)
6find_package(Gpgme REQUIRED)
8 7
9# target_include_directories does not handle empty include paths 8# target_include_directories does not handle empty include paths
10include_directories(${GPGME_INCLUDES}) 9include_directories(${GPGME_INCLUDES})
@@ -49,8 +48,8 @@ target_link_libraries(kube_otp
49 48
50target_link_libraries(kube_otp 49target_link_libraries(kube_otp
51 PRIVATE 50 PRIVATE
52 QGpgme 51 gpgme
53 Gpgmepp 52 mailcrypto
54 KF5::Codecs 53 KF5::Codecs
55 Qt5::Gui 54 Qt5::Gui
56) 55)
diff --git a/framework/src/domain/mime/mimetreeparser/autotests/CMakeLists.txt b/framework/src/domain/mime/mimetreeparser/autotests/CMakeLists.txt
index f0b1f5f5..e67884e0 100644
--- a/framework/src/domain/mime/mimetreeparser/autotests/CMakeLists.txt
+++ b/framework/src/domain/mime/mimetreeparser/autotests/CMakeLists.txt
@@ -15,7 +15,7 @@ macro(add_mimetreeparser_unittest _source)
15 ecm_add_test(${_source} util.cpp setupenv.cpp 15 ecm_add_test(${_source} util.cpp setupenv.cpp
16 TEST_NAME ${_name} 16 TEST_NAME ${_name}
17 NAME_PREFIX "mimetreeparser-" 17 NAME_PREFIX "mimetreeparser-"
18 LINK_LIBRARIES kube_otp Qt5::Test KF5::Mime Gpgmepp 18 LINK_LIBRARIES kube_otp Qt5::Test KF5::Mime gpgme
19 ) 19 )
20endmacro () 20endmacro ()
21 21
@@ -24,7 +24,7 @@ macro(add_mimetreeparser_class_unittest _source _additionalSource)
24 ecm_add_test(${_source} ${_additionalSource} 24 ecm_add_test(${_source} ${_additionalSource}
25 TEST_NAME ${_name} 25 TEST_NAME ${_name}
26 NAME_PREFIX "mimetreeparser-" 26 NAME_PREFIX "mimetreeparser-"
27 LINK_LIBRARIES kube_otp Qt5::Test KF5::Mime Gpgmepp 27 LINK_LIBRARIES kube_otp Qt5::Test KF5::Mime gpgme
28 ) 28 )
29endmacro () 29endmacro ()
30 30
@@ -37,7 +37,7 @@ macro(add_mimetreeparser_crypto_unittest _source)
37 kube_otp 37 kube_otp
38 Qt5::Test 38 Qt5::Test
39 KF5::Mime 39 KF5::Mime
40 Gpgmepp 40 gpgme
41 ) 41 )
42 add_gpg_crypto_test(${_name} mimetreeparser-${_name}) 42 add_gpg_crypto_test(${_name} mimetreeparser-${_name})
43endmacro () 43endmacro ()
diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.cpp b/framework/src/domain/mime/mimetreeparser/messagepart.cpp
index 2fd4f496..4bed80da 100644
--- a/framework/src/domain/mime/mimetreeparser/messagepart.cpp
+++ b/framework/src/domain/mime/mimetreeparser/messagepart.cpp
@@ -27,102 +27,12 @@
27 27
28#include <KMime/Content> 28#include <KMime/Content>
29 29
30#include <QGpgME/DN> 30#include <crypto.h>
31#include <QGpgME/DataProvider>
32
33#include <gpgme++/context.h>
34#include <gpgme++/data.h>
35#include <gpgme++/verificationresult.h>
36#include <gpgme++/key.h>
37#include <gpgme++/keylistresult.h>
38#include <gpgme++/decryptionresult.h>
39#include <gpgme++/importresult.h>
40#include <gpgme.h>
41
42 31
43#include <QTextCodec> 32#include <QTextCodec>
44#include <sstream>
45 33
46using namespace MimeTreeParser; 34using namespace MimeTreeParser;
47 35using namespace Crypto;
48static GpgME::Data fromBA(const QByteArray &ba)
49{
50 return {ba.data(), static_cast<size_t>(ba.size()), false};
51}
52
53
54static GpgME::Protocol toGpgMe(CryptoProtocol p)
55{
56 switch (p) {
57 case UnknownProtocol:
58 return GpgME::UnknownProtocol;
59 case CMS:
60 return GpgME::CMS;
61 case OpenPGP:
62 return GpgME::OpenPGP;
63 }
64 return GpgME::UnknownProtocol;
65}
66
67static QSharedPointer<GpgME::Context> gpgContext(CryptoProtocol protocol)
68{
69 GpgME::initializeLibrary();
70 auto error = GpgME::checkEngine(toGpgMe(protocol));
71 if (error) {
72 qWarning() << "Engine check failed: " << error.asString();
73 }
74 auto ctx = QSharedPointer<GpgME::Context>(GpgME::Context::createForProtocol(toGpgMe(protocol)));
75 Q_ASSERT(ctx);
76 return ctx;
77}
78
79static GpgME::VerificationResult verifyDetachedSignature(CryptoProtocol protocol, const QByteArray &signature, const QByteArray &text)
80{
81 return gpgContext(protocol)->verifyDetachedSignature(fromBA(signature), fromBA(text));
82}
83
84static GpgME::VerificationResult verifyOpaqueSignature(CryptoProtocol protocol, const QByteArray &signature, QByteArray &outdata)
85{
86 QGpgME::QByteArrayDataProvider out;
87 GpgME::Data wrapper(&out);
88 const auto result = gpgContext(protocol)->verifyOpaqueSignature(fromBA(signature), wrapper);
89 outdata = out.data();
90 return result;
91}
92
93
94static std::pair<GpgME::DecryptionResult,GpgME::VerificationResult> decryptAndVerify(CryptoProtocol protocol, const QByteArray &ciphertext, QByteArray &outdata)
95{
96 QGpgME::QByteArrayDataProvider out;
97 GpgME::Data wrapper(&out);
98 const std::pair<GpgME::DecryptionResult,GpgME::VerificationResult> res = gpgContext(protocol)->decryptAndVerify(fromBA(ciphertext), wrapper);
99 outdata = out.data();
100 return res;
101}
102
103static void importKeys(CryptoProtocol protocol, const QByteArray &certData)
104{
105 gpgContext(protocol)->importKeys(fromBA(certData));
106}
107
108static GpgME::KeyListResult listKeys(CryptoProtocol protocol, const char *pattern, bool secretOnly, std::vector<GpgME::Key> &keys) {
109 auto ctx = gpgContext(protocol);
110 if (const GpgME::Error err = ctx->startKeyListing(pattern, secretOnly)) {
111 return GpgME::KeyListResult( 0, err );
112 }
113
114 GpgME::Error err;
115 do {
116 keys.push_back( ctx->nextKey(err));
117 } while ( !err );
118
119 keys.pop_back();
120
121 const GpgME::KeyListResult result = ctx->endKeyListing();
122 ctx->cancelPendingOperation();
123 return result;
124}
125
126 36
127//------MessagePart----------------------- 37//------MessagePart-----------------------
128MessagePart::MessagePart(ObjectTreeParser *otp, const QString &text, KMime::Content *node) 38MessagePart::MessagePart(ObjectTreeParser *otp, const QString &text, KMime::Content *node)
@@ -771,10 +681,7 @@ SignedMessagePart::SignedMessagePart(ObjectTreeParser *otp,
771{ 681{
772 mMetaData.isSigned = true; 682 mMetaData.isSigned = true;
773 mMetaData.isGoodSignature = false; 683 mMetaData.isGoodSignature = false;
774 //FIXME
775 // mMetaData.keyTrust = GpgME::Signature::Unknown;
776 mMetaData.status = tr("Wrong Crypto Plug-In."); 684 mMetaData.status = tr("Wrong Crypto Plug-In.");
777 mMetaData.status_code = GPGME_SIG_STAT_NONE;
778} 685}
779 686
780SignedMessagePart::~SignedMessagePart() 687SignedMessagePart::~SignedMessagePart()
@@ -792,99 +699,65 @@ bool SignedMessagePart::isSigned() const
792 return mMetaData.isSigned; 699 return mMetaData.isSigned;
793} 700}
794 701
795static int signatureToStatus(const GpgME::Signature &sig)
796{
797 switch (sig.status().code()) {
798 case GPG_ERR_NO_ERROR:
799 return GPGME_SIG_STAT_GOOD;
800 case GPG_ERR_BAD_SIGNATURE:
801 return GPGME_SIG_STAT_BAD;
802 case GPG_ERR_NO_PUBKEY:
803 return GPGME_SIG_STAT_NOKEY;
804 case GPG_ERR_NO_DATA:
805 return GPGME_SIG_STAT_NOSIG;
806 case GPG_ERR_SIG_EXPIRED:
807 return GPGME_SIG_STAT_GOOD_EXP;
808 case GPG_ERR_KEY_EXPIRED:
809 return GPGME_SIG_STAT_GOOD_EXPKEY;
810 default:
811 return GPGME_SIG_STAT_ERROR;
812 }
813}
814 702
815QString prettifyDN(const char *uid) 703static QString prettifyDN(const char *uid)
816{ 704{
817 return QGpgME::DN(uid).prettyDN(); 705 // We used to use QGpgME::DN::prettyDN here. But I'm not sure what we actually need it for.
706 return QString::fromUtf8(uid);
818} 707}
819 708
820void SignedMessagePart::sigStatusToMetaData(const GpgME::Signature &signature) 709void SignedMessagePart::sigStatusToMetaData(const Signature &signature)
821{ 710{
822 GpgME::Key key; 711 mMetaData.isGoodSignature = signature.status & GPG_ERR_NO_ERROR;
823 mMetaData.status_code = signatureToStatus(signature);
824 mMetaData.isGoodSignature = mMetaData.status_code & GPGME_SIG_STAT_GOOD;
825 // save extended signature status flags 712 // save extended signature status flags
826 auto summary = signature.summary(); 713 auto summary = signature.summary;
827 mMetaData.keyMissing = summary & GpgME::Signature::KeyMissing; 714 mMetaData.keyMissing = summary & GPGME_SIGSUM_KEY_MISSING;
828 mMetaData.keyExpired = summary & GpgME::Signature::KeyExpired; 715 mMetaData.keyExpired = summary & GPGME_SIGSUM_KEY_EXPIRED;
829 mMetaData.keyRevoked = summary & GpgME::Signature::KeyRevoked; 716 mMetaData.keyRevoked = summary & GPGME_SIGSUM_KEY_REVOKED;
830 mMetaData.sigExpired = summary & GpgME::Signature::SigExpired; 717 mMetaData.sigExpired = summary & GPGME_SIGSUM_SIG_EXPIRED;
831 mMetaData.crlMissing = summary & GpgME::Signature::CrlMissing; 718 mMetaData.crlMissing = summary & GPGME_SIGSUM_CRL_MISSING;
832 mMetaData.crlTooOld = summary & GpgME::Signature::CrlTooOld; 719 mMetaData.crlTooOld = summary & GPGME_SIGSUM_CRL_TOO_OLD;
833 720
834 if (mMetaData.isGoodSignature && !key.keyID()) { 721 Key key;
722 if (mMetaData.isGoodSignature) {
835 // Search for the key by its fingerprint so that we can check for trust etc. 723 // Search for the key by its fingerprint so that we can check for trust etc.
836 std::vector<GpgME::Key> found_keys; 724 const auto keys = findKeys({signature.fingerprint});
837 auto res = listKeys(mProtocol, signature.fingerprint(), false, found_keys); 725 if (keys.size() > 1) {
838 if (res.error()) {
839 qCDebug(MIMETREEPARSER_LOG) << "Error while searching key for Fingerprint: " << signature.fingerprint();
840 }
841 if (found_keys.size() > 1) {
842 // Should not happen 726 // Should not happen
843 qCDebug(MIMETREEPARSER_LOG) << "Oops: Found more then one Key for Fingerprint: " << signature.fingerprint(); 727 qCDebug(MIMETREEPARSER_LOG) << "Oops: Found more then one Key for Fingerprint: " << signature.fingerprint;
844 } 728 }
845 if (found_keys.empty()) { 729 if (keys.empty()) {
846 // Should not happen at this point 730 // Should not happen at this point
847 qCWarning(MIMETREEPARSER_LOG) << "Oops: Found no Key for Fingerprint: " << signature.fingerprint(); 731 qCWarning(MIMETREEPARSER_LOG) << "Oops: Found no Key for Fingerprint: " << signature.fingerprint;
848 } else { 732 } else {
849 key = found_keys[0]; 733 key = keys[0];
850 } 734 }
851 } 735 }
852 736
853 if (key.keyID()) { 737 mMetaData.keyId = key.keyId;
854 mMetaData.keyId = key.keyID();
855 }
856 if (mMetaData.keyId.isEmpty()) { 738 if (mMetaData.keyId.isEmpty()) {
857 mMetaData.keyId = signature.fingerprint(); 739 mMetaData.keyId = signature.fingerprint;
858 } 740 }
859 auto keyTrust = signature.validity(); 741 mMetaData.keyIsTrusted = signature.validity == GPGME_VALIDITY_FULL || signature.validity == GPGME_VALIDITY_ULTIMATE;
860 mMetaData.keyIsTrusted = keyTrust & GpgME::Signature::Full || keyTrust & GpgME::Signature::Ultimate; 742 if (!key.userIds.empty()) {
861 if (key.numUserIDs() > 0 && key.userID(0).id()) { 743 mMetaData.signer = prettifyDN(key.userIds[0].id);
862 mMetaData.signer = prettifyDN(key.userID(0).id()); 744 }
863 } 745 for (const auto &userId : key.userIds) {
864 for (uint iMail = 0; iMail < key.numUserIDs(); ++iMail) { 746 QString email = QString::fromUtf8(userId.email);
865 // The following if /should/ always result in TRUE but we 747 // ### work around gpgme 0.3.QString text() const Q_DECL_OVERRIDE;x / cryptplug bug where the
866 // won't trust implicitely the plugin that gave us these data. 748 // ### email addresses are specified as angle-addr, not addr-spec:
867 if (key.userID(iMail).email()) { 749 if (email.startsWith(QLatin1Char('<')) && email.endsWith(QLatin1Char('>'))) {
868 QString email = QString::fromUtf8(key.userID(iMail).email()); 750 email = email.mid(1, email.length() - 2);
869 // ### work around gpgme 0.3.QString text() const Q_DECL_OVERRIDE;x / cryptplug bug where the 751 }
870 // ### email addresses are specified as angle-addr, not addr-spec: 752 if (!email.isEmpty()) {
871 if (email.startsWith(QLatin1Char('<')) && email.endsWith(QLatin1Char('>'))) { 753 mMetaData.signerMailAddresses.append(email);
872 email = email.mid(1, email.length() - 2);
873 }
874 if (!email.isEmpty()) {
875 mMetaData.signerMailAddresses.append(email);
876 }
877 } 754 }
878 } 755 }
879 756
880 if (signature.creationTime()) { 757 mMetaData.creationTime = signature.creationTime;
881 mMetaData.creationTime.setTime_t(signature.creationTime());
882 } else {
883 mMetaData.creationTime = QDateTime();
884 }
885 if (mMetaData.signer.isEmpty()) { 758 if (mMetaData.signer.isEmpty()) {
886 if (key.numUserIDs() > 0 && key.userID(0).name()) { 759 if (!key.userIds.empty()) {
887 mMetaData.signer = prettifyDN(key.userID(0).name()); 760 mMetaData.signer = prettifyDN(key.userIds[0].name);
888 } 761 }
889 if (!mMetaData.signerMailAddresses.empty()) { 762 if (!mMetaData.signerMailAddresses.empty()) {
890 if (mMetaData.signer.isEmpty()) { 763 if (mMetaData.signer.isEmpty()) {
@@ -924,18 +797,13 @@ void SignedMessagePart::startVerificationDetached(const QByteArray &text, KMime:
924 } 797 }
925 798
926 mMetaData.isSigned = false; 799 mMetaData.isSigned = false;
927 //FIXME
928 // mMetaData.keyTrust = GpgME::Signature::Unknown;
929 mMetaData.status = tr("Wrong Crypto Plug-In."); 800 mMetaData.status = tr("Wrong Crypto Plug-In.");
930 mMetaData.status_code = GPGME_SIG_STAT_NONE;
931 801
932 if (!signature.isEmpty()) { 802 if (!signature.isEmpty()) {
933 auto result = verifyDetachedSignature(mProtocol, signature, text); 803 setVerificationResult(verifyDetachedSignature(mProtocol, signature, text), false, text);
934 setVerificationResult(result, false, text);
935 } else { 804 } else {
936 QByteArray outdata; 805 QByteArray outdata;
937 auto result = verifyOpaqueSignature(mProtocol, text, outdata); 806 setVerificationResult(verifyOpaqueSignature(mProtocol, text, outdata), false, outdata);
938 setVerificationResult(result, false, outdata);
939 } 807 }
940 808
941 if (!mMetaData.isSigned) { 809 if (!mMetaData.isSigned) {
@@ -943,11 +811,11 @@ void SignedMessagePart::startVerificationDetached(const QByteArray &text, KMime:
943 } 811 }
944} 812}
945 813
946void SignedMessagePart::setVerificationResult(const GpgME::VerificationResult &result, bool parseText, const QByteArray &plainText) 814void SignedMessagePart::setVerificationResult(const VerificationResult &result, bool parseText, const QByteArray &plainText)
947{ 815{
948 auto signatures = result.signatures(); 816 auto signatures = result.signatures;
949 // FIXME 817 // FIXME
950 // mMetaData.auditLogError = result.error(); 818 // mMetaData.auditLogError = result.error;
951 if (!signatures.empty()) { 819 if (!signatures.empty()) {
952 mMetaData.isSigned = true; 820 mMetaData.isSigned = true;
953 sigStatusToMetaData(signatures.front()); 821 sigStatusToMetaData(signatures.front());
@@ -994,10 +862,7 @@ EncryptedMessagePart::EncryptedMessagePart(ObjectTreeParser *otp,
994 mMetaData.isGoodSignature = false; 862 mMetaData.isGoodSignature = false;
995 mMetaData.isEncrypted = false; 863 mMetaData.isEncrypted = false;
996 mMetaData.isDecryptable = false; 864 mMetaData.isDecryptable = false;
997 //FIXME
998 // mMetaData.keyTrust = GpgME::Signature::Unknown;
999 mMetaData.status = tr("Wrong Crypto Plug-In."); 865 mMetaData.status = tr("Wrong Crypto Plug-In.");
1000 mMetaData.status_code = GPGME_SIG_STAT_NONE;
1001} 866}
1002 867
1003EncryptedMessagePart::~EncryptedMessagePart() 868EncryptedMessagePart::~EncryptedMessagePart()
@@ -1055,59 +920,61 @@ bool EncryptedMessagePart::okDecryptMIME(KMime::Content &data)
1055 920
1056 const QByteArray ciphertext = data.decodedContent(); 921 const QByteArray ciphertext = data.decodedContent();
1057 QByteArray plainText; 922 QByteArray plainText;
1058 const auto res = decryptAndVerify(mProtocol, ciphertext, plainText); 923 DecryptionResult decryptResult;
1059 const GpgME::DecryptionResult &decryptResult = res.first; 924 VerificationResult verifyResult;
1060 const GpgME::VerificationResult &verifyResult = res.second; 925 std::tie(decryptResult, verifyResult) = decryptAndVerify(mProtocol, ciphertext, plainText);
1061 mMetaData.isSigned = verifyResult.signatures().size() > 0; 926 mMetaData.isSigned = verifyResult.signatures.size() > 0;
1062 927
1063 if (verifyResult.signatures().size() > 0) { 928 if (verifyResult.signatures.size() > 0) {
1064 //We simply attach a signed message part to indicate that this content is also signed 929 //We simply attach a signed message part to indicate that this content is also signed
1065 auto subPart = SignedMessagePart::Ptr(new SignedMessagePart(mOtp, QString::fromUtf8(plainText), mProtocol, mFromAddress, nullptr, nullptr)); 930 auto subPart = SignedMessagePart::Ptr(new SignedMessagePart(mOtp, QString::fromUtf8(plainText), mProtocol, mFromAddress, nullptr, nullptr));
1066 subPart->setVerificationResult(verifyResult, true, plainText); 931 subPart->setVerificationResult(verifyResult, true, plainText);
1067 appendSubPart(subPart); 932 appendSubPart(subPart);
1068 } 933 }
1069 934
1070 if (decryptResult.error() && mMetaData.isSigned) { 935 if (decryptResult.error && mMetaData.isSigned) {
1071 //Only a signed part 936 //Only a signed part
1072 mMetaData.isEncrypted = false; 937 mMetaData.isEncrypted = false;
1073 mDecryptedData = plainText; 938 mDecryptedData = plainText;
1074 return true; 939 return true;
1075 } 940 }
1076 941
1077 if (mMetaData.isEncrypted && decryptResult.numRecipients() > 0) { 942 if (mMetaData.isEncrypted && decryptResult.recipients.size()) {
1078 mMetaData.keyId = decryptResult.recipient(0).keyID(); 943 mMetaData.keyId = decryptResult.recipients.at(0).keyId;
1079 } 944 }
1080 945
1081 if (!decryptResult.error()) { 946 if (!decryptResult.error) {
1082 mDecryptedData = plainText; 947 mDecryptedData = plainText;
1083 setText(QString::fromUtf8(mDecryptedData.constData())); 948 setText(QString::fromUtf8(mDecryptedData.constData()));
1084 } else { 949 } else {
1085 mMetaData.isEncrypted = decryptResult.error().code() != GPG_ERR_NO_DATA; 950 const auto errorCode = decryptResult.error.errorCode();
1086 mMetaData.errorText = QString::fromLocal8Bit(decryptResult.error().asString()); 951 mMetaData.isEncrypted = errorCode != GPG_ERR_NO_DATA;
1087 952 qWarning() << "Failed to decrypt : " << decryptResult.error;
1088 std::stringstream ss; 953
1089 ss << decryptResult << '\n' << verifyResult; 954 const bool noSecretKeyAvilable = [&] {
1090 qWarning() << "Decryption failed: " << ss.str().c_str(); 955 foreach (const auto &recipient, decryptResult.recipients) {
1091 956 if (!(recipient.status.errorCode() == GPG_ERR_NO_SECKEY)) {
1092 bool passphraseError = decryptResult.error().isCanceled() || decryptResult.error().code() == GPG_ERR_NO_SECKEY; 957 return false;
1093 958 }
1094 auto noSecKey = true; 959 }
1095 foreach (const GpgME::DecryptionResult::Recipient &recipient, decryptResult.recipients()) { 960 return true;
1096 noSecKey &= (recipient.status().code() == GPG_ERR_NO_SECKEY); 961 }();
1097 } 962 bool passphraseError = errorCode == GPG_ERR_CANCELED || errorCode == GPG_ERR_NO_SECKEY;
1098 if (!passphraseError && !noSecKey) { // GpgME do not detect passphrase error correctly 963 //We only get a decryption failed error when we enter the wrong passphrase....
964 if (!passphraseError && !noSecretKeyAvilable) {
1099 passphraseError = true; 965 passphraseError = true;
1100 } 966 }
1101 967
1102 if(noSecKey) { 968 if(noSecretKeyAvilable) {
1103 mError = NoKeyError; 969 mError = NoKeyError;
1104 mMetaData.errorText = tr("Could not decrypt the data. ") + tr("No key found for recepients."); 970 mMetaData.errorText = tr("Could not decrypt the data. ") + tr("No key found for recepients.");
1105 } else if (passphraseError) { 971 } else if (passphraseError) {
1106 mError = PassphraseError; 972 mError = PassphraseError;
973 // mMetaData.errorText = QString::fromLocal8Bit(decryptResult.error().asString());
1107 } else { 974 } else {
1108 mError = UnknownError; 975 mError = UnknownError;
1109 mMetaData.errorText = tr("Could not decrypt the data. ") 976 mMetaData.errorText = tr("Could not decrypt the data. ");
1110 + tr("Error: %1").arg(mMetaData.errorText); 977 // + tr("Error: %1").arg(QString::fromLocal8Bit(decryptResult.error().asString()));
1111 } 978 }
1112 return false; 979 return false;
1113 } 980 }
diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.h b/framework/src/domain/mime/mimetreeparser/messagepart.h
index 3c07ca88..c576699e 100644
--- a/framework/src/domain/mime/mimetreeparser/messagepart.h
+++ b/framework/src/domain/mime/mimetreeparser/messagepart.h
@@ -23,6 +23,7 @@
23#include "util.h" 23#include "util.h"
24#include "enums.h" 24#include "enums.h"
25#include "partmetadata.h" 25#include "partmetadata.h"
26#include <crypto.h>
26 27
27#include <KMime/Message> 28#include <KMime/Message>
28 29
@@ -32,13 +33,6 @@
32class QTextCodec; 33class QTextCodec;
33class PartPrivate; 34class PartPrivate;
34 35
35namespace GpgME
36{
37class ImportResult;
38class VerificationResult;
39class Signature;
40}
41
42namespace KMime 36namespace KMime
43{ 37{
44class Content; 38class Content;
@@ -55,11 +49,10 @@ class MultiPartAlternativeBodyPartFormatter;
55class SignedMessagePart; 49class SignedMessagePart;
56class EncryptedMessagePart; 50class EncryptedMessagePart;
57 51
58enum CryptoProtocol { 52using Crypto::CryptoProtocol;
59 UnknownProtocol, 53using Crypto::CryptoProtocol::CMS;
60 OpenPGP, 54using Crypto::CryptoProtocol::OpenPGP;
61 CMS 55using Crypto::CryptoProtocol::UnknownProtocol;
62};
63 56
64class MessagePart : public QObject 57class MessagePart : public QObject
65{ 58{
@@ -366,8 +359,8 @@ public:
366 QString htmlContent() const Q_DECL_OVERRIDE; 359 QString htmlContent() const Q_DECL_OVERRIDE;
367 360
368private: 361private:
369 void sigStatusToMetaData(const GpgME::Signature &signature); 362 void sigStatusToMetaData(const Crypto::Signature &signature);
370 void setVerificationResult(const GpgME::VerificationResult &result, bool parseText, const QByteArray &plainText); 363 void setVerificationResult(const Crypto::VerificationResult &result, bool parseText, const QByteArray &plainText);
371 364
372protected: 365protected:
373 CryptoProtocol mProtocol; 366 CryptoProtocol mProtocol;
diff --git a/framework/src/domain/mime/mimetreeparser/partmetadata.h b/framework/src/domain/mime/mimetreeparser/partmetadata.h
index 44a9cf7e..583eb454 100644
--- a/framework/src/domain/mime/mimetreeparser/partmetadata.h
+++ b/framework/src/domain/mime/mimetreeparser/partmetadata.h
@@ -37,7 +37,6 @@ public:
37 QByteArray keyId; 37 QByteArray keyId;
38 bool keyIsTrusted = false; 38 bool keyIsTrusted = false;
39 QString status; // to be used for unknown plug-ins 39 QString status; // to be used for unknown plug-ins
40 int status_code; // to be used for i18n of OpenPGP and S/MIME CryptPlugs
41 QString errorText; 40 QString errorText;
42 QDateTime creationTime; 41 QDateTime creationTime;
43 QString decryptionError; 42 QString decryptionError;
diff --git a/framework/src/domain/mime/mimetreeparser/tests/CMakeLists.txt b/framework/src/domain/mime/mimetreeparser/tests/CMakeLists.txt
index 9937ab06..fcb1988a 100644
--- a/framework/src/domain/mime/mimetreeparser/tests/CMakeLists.txt
+++ b/framework/src/domain/mime/mimetreeparser/tests/CMakeLists.txt
@@ -15,12 +15,11 @@ target_link_libraries(mimetreeparsertest
15 Qt5::Core 15 Qt5::Core
16 Qt5::Test 16 Qt5::Test
17 KF5::Mime 17 KF5::Mime
18 Gpgmepp 18 gpgme
19 QGpgme
20) 19)
21 20
22ecm_add_test(gpgerrortest.cpp 21ecm_add_test(gpgerrortest.cpp
23 TEST_NAME "gpgerrortest" 22 TEST_NAME "gpgerrortest"
24 NAME_PREFIX "mimetreeparser-" 23 NAME_PREFIX "mimetreeparser-"
25 LINK_LIBRARIES Qt5::Core Qt5::Test kube_otp Gpgmepp QGpgme 24 LINK_LIBRARIES Qt5::Core Qt5::Test kube_otp gpgme
26) 25)