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 }