File indexing completed on 2024-06-23 05:18:25
0001 /* SPDX-FileCopyrightText: 2023 Sandro Knauß <sknauss@kde.org> 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 */ 0004 0005 #include "composer/autocryptkeyresolvercore.h" 0006 0007 #include <Akonadi/ContactSearchJob> 0008 #include <MessageComposer/ContactPreference> 0009 #include <MessageCore/AutocryptStorage> 0010 0011 #include <messagecomposer_debug.h> 0012 0013 using namespace MessageComposer; 0014 0015 class MessageComposer::AutocryptKeyResolverCorePrivate 0016 { 0017 public: 0018 QStringList autocrypt_keys; 0019 QStringList gossip_keys; 0020 }; 0021 0022 0023 AutocryptKeyResolverCore::AutocryptKeyResolverCore(bool encrypt, bool sign, GpgME::Protocol format) 0024 : Kleo::KeyResolverCore(encrypt, sign, format) 0025 , d(new AutocryptKeyResolverCorePrivate) 0026 { 0027 } 0028 0029 AutocryptKeyResolverCore::~AutocryptKeyResolverCore() = default; 0030 0031 Kleo::KeyResolverCore::Result AutocryptKeyResolverCore::resolve() 0032 { 0033 auto result = Kleo::KeyResolverCore::resolve(); 0034 0035 if ((result.flags & Kleo::KeyResolverCore::AllResolved)) { 0036 qCDebug(MESSAGECOMPOSER_LOG) << "We found already for all recipient keys and we don't need to add Autocrypt keys."; 0037 return result; 0038 } 0039 0040 if (!(result.flags & Kleo::KeyResolverCore::OpenPGPOnly)) { 0041 qCWarning(MESSAGECOMPOSER_LOG) << "Autocrypt is only defined for OpenPGP not for SMIME"; 0042 return result; 0043 } 0044 0045 Kleo::KeyResolver::Solution *solution = &result.solution; 0046 0047 if (solution->protocol != GpgME::OpenPGP) { 0048 solution = &result.alternative; 0049 } 0050 0051 Q_ASSERT(solution->protocol == GpgME::OpenPGP); 0052 0053 bool allResolved = true; 0054 const auto storage = MessageCore::AutocryptStorage::self(); 0055 for (const auto &recipient: solution->encryptionKeys.keys()) { 0056 auto &keys = solution->encryptionKeys[recipient]; 0057 if (keys.size() > 0) { // already keys found 0058 continue; 0059 } 0060 if (recipient == normalizedSender()) { // Own key needs to be in normal key store (Autocrypt do not offer private keys) 0061 allResolved = false; 0062 continue; 0063 } 0064 0065 const auto rec = storage->getRecipient(recipient.toUtf8()); 0066 GpgME::Key autocryptKey; 0067 if (rec) { 0068 const auto key = rec->gpgKey(); 0069 if (!key.isBad() && key.canEncrypt()) { 0070 d->autocrypt_keys.push_back(recipient); 0071 autocryptKey = std::move(key); 0072 } else { 0073 const auto gossipKey = rec->gossipKey(); 0074 if (!gossipKey.isBad() && gossipKey.canEncrypt()) { 0075 d->gossip_keys.push_back(recipient); 0076 autocryptKey = std::move(gossipKey); 0077 } 0078 } 0079 } 0080 if (!autocryptKey.isNull()) { 0081 keys.push_back(autocryptKey); 0082 } else { 0083 allResolved = false; 0084 } 0085 } 0086 if (allResolved) { 0087 result.flags = Kleo::KeyResolverCore::SolutionFlags(result.flags | Kleo::KeyResolverCore::AllResolved); 0088 if (solution == &result.alternative) { 0089 const auto _tmp = std::move(result.solution); 0090 result.solution = std::move(result.alternative); 0091 result.alternative = std::move(_tmp); 0092 } 0093 } 0094 0095 return result; 0096 } 0097 0098 bool AutocryptKeyResolverCore::isAutocryptKey(const QString &recipient) const 0099 { 0100 return d->autocrypt_keys.contains(recipient) || isGossipKey(recipient); 0101 } 0102 0103 bool AutocryptKeyResolverCore::isGossipKey(const QString &recipient) const 0104 { 0105 return d->gossip_keys.contains(recipient); 0106 }