File indexing completed on 2025-01-05 04:55:44

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     models/keycache.h
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "kleo_export.h"
0013 
0014 #include <QObject>
0015 
0016 #include <gpgme++/global.h>
0017 
0018 #include <memory>
0019 #include <string>
0020 #include <vector>
0021 
0022 namespace GpgME
0023 {
0024 class Key;
0025 class DecryptionResult;
0026 class VerificationResult;
0027 class KeyListResult;
0028 class Subkey;
0029 }
0030 
0031 namespace KMime
0032 {
0033 namespace Types
0034 {
0035 class Mailbox;
0036 }
0037 }
0038 
0039 namespace Kleo
0040 {
0041 
0042 class FileSystemWatcher;
0043 class KeyGroup;
0044 class KeyGroupConfig;
0045 
0046 class KeyCacheAutoRefreshSuspension;
0047 
0048 class KLEO_EXPORT KeyCache : public QObject
0049 {
0050     Q_OBJECT
0051 
0052 protected:
0053     explicit KeyCache();
0054 
0055 public:
0056     enum class KeyUsage {
0057         AnyUsage,
0058         Sign,
0059         Encrypt,
0060         Certify,
0061         Authenticate,
0062     };
0063 
0064     static std::shared_ptr<const KeyCache> instance();
0065     static std::shared_ptr<KeyCache> mutableInstance();
0066 
0067     ~KeyCache() override;
0068 
0069     void setGroupsEnabled(bool enabled);
0070     void setGroupConfig(const std::shared_ptr<KeyGroupConfig> &groupConfig);
0071 
0072     void insert(const GpgME::Key &key);
0073     void insert(const std::vector<GpgME::Key> &keys);
0074     bool insert(const KeyGroup &group);
0075 
0076     void refresh(const std::vector<GpgME::Key> &keys);
0077     bool update(const KeyGroup &group);
0078 
0079     void remove(const GpgME::Key &key);
0080     void remove(const std::vector<GpgME::Key> &keys);
0081     bool remove(const KeyGroup &group);
0082 
0083     void addFileSystemWatcher(const std::shared_ptr<FileSystemWatcher> &watcher);
0084 
0085     void enableFileSystemWatcher(bool enable);
0086 
0087     void setRefreshInterval(int hours);
0088     int refreshInterval() const;
0089 
0090     std::shared_ptr<KeyCacheAutoRefreshSuspension> suspendAutoRefresh();
0091 
0092     void enableRemarks(bool enable);
0093     bool remarksEnabled() const;
0094 
0095     const std::vector<GpgME::Key> &keys() const;
0096     std::vector<GpgME::Key> secretKeys() const;
0097 
0098     KeyGroup group(const QString &id) const;
0099     std::vector<KeyGroup> groups() const;
0100     std::vector<KeyGroup> configurableGroups() const;
0101     void saveConfigurableGroups(const std::vector<KeyGroup> &groups);
0102 
0103     const GpgME::Key &findByFingerprint(const char *fpr) const;
0104     const GpgME::Key &findByFingerprint(const std::string &fpr) const;
0105 
0106     std::vector<GpgME::Key> findByFingerprint(const std::vector<std::string> &fprs) const;
0107 
0108     std::vector<GpgME::Key> findByEMailAddress(const char *email) const;
0109     std::vector<GpgME::Key> findByEMailAddress(const std::string &email) const;
0110 
0111     /** Look through the cache and search for the best key for a mailbox.
0112      *
0113      * The best key is the key with a UID for the provided mailbox that
0114      * has the highest validity and a subkey that is capable for the given
0115      * usage.
0116      * If more then one key have a UID with the same validity
0117      * the most recently created key is taken.
0118      *
0119      * @returns the "best" key for the mailbox. */
0120     GpgME::Key findBestByMailBox(const char *addr, GpgME::Protocol proto, KeyUsage usage) const;
0121 
0122     /**
0123      * Looks for a group named @a name which contains keys with protocol @a protocol
0124      * that are suitable for the usage @a usage.
0125      *
0126      * If @a protocol is GpgME::OpenPGP or GpgME::CMS, then only groups consisting of keys
0127      * matching this protocol are considered. Use @a protocol GpgME::UnknownProtocol to consider
0128      * any groups regardless of the protocol including mixed-protocol groups.
0129      *
0130      * If @a usage is not KeyUsage::AnyUsage, then only groups consisting of keys supporting this usage
0131      * are considered.
0132      * The validity of keys and the presence of a private key (necessary for signing, certification, and
0133      * authentication) is not taken into account.
0134      *
0135      * The first group that fulfills all conditions is returned.
0136      *
0137      * @returns a matching group or a null group if no matching group is found.
0138      */
0139     KeyGroup findGroup(const QString &name, GpgME::Protocol protocol, KeyUsage usage) const;
0140 
0141     const GpgME::Key &findByShortKeyID(const char *id) const;
0142     const GpgME::Key &findByShortKeyID(const std::string &id) const;
0143 
0144     const GpgME::Key &findByKeyIDOrFingerprint(const char *id) const;
0145     const GpgME::Key &findByKeyIDOrFingerprint(const std::string &id) const;
0146 
0147     std::vector<GpgME::Key> findByKeyIDOrFingerprint(const std::vector<std::string> &ids) const;
0148 
0149     const GpgME::Subkey &findSubkeyByKeyGrip(const char *grip, GpgME::Protocol protocol = GpgME::UnknownProtocol) const;
0150     const GpgME::Subkey &findSubkeyByKeyGrip(const std::string &grip, GpgME::Protocol protocol = GpgME::UnknownProtocol) const;
0151 
0152     std::vector<GpgME::Subkey> findSubkeysByKeyID(const std::vector<std::string> &ids) const;
0153 
0154     std::vector<GpgME::Key> findRecipients(const GpgME::DecryptionResult &result) const;
0155     std::vector<GpgME::Key> findSigners(const GpgME::VerificationResult &result) const;
0156 
0157     std::vector<GpgME::Key> findSigningKeysByMailbox(const QString &mb) const;
0158     std::vector<GpgME::Key> findEncryptionKeysByMailbox(const QString &mb) const;
0159 
0160     /** Check for group keys.
0161      *
0162      * @returns A list of keys configured for groupName. Empty if no group cached.*/
0163     std::vector<GpgME::Key> getGroupKeys(const QString &groupName) const;
0164 
0165     enum Option {
0166         // clang-format off
0167         NoOption        = 0,
0168         RecursiveSearch = 1,
0169         IncludeSubject  = 2,
0170         // clang-format on
0171     };
0172     Q_DECLARE_FLAGS(Options, Option)
0173 
0174     std::vector<GpgME::Key> findSubjects(const GpgME::Key &key, Options option = RecursiveSearch) const;
0175     std::vector<GpgME::Key> findSubjects(const std::vector<GpgME::Key> &keys, Options options = RecursiveSearch) const;
0176 
0177     std::vector<GpgME::Key> findIssuers(const GpgME::Key &key, Options options = RecursiveSearch) const;
0178 
0179     /** Check if at least one keylisting was finished. */
0180     bool initialized() const;
0181 
0182     /** Check if all keys have OpenPGP Protocol. */
0183     bool pgpOnly() const;
0184 
0185     /** Set the keys the cache shall contain. Marks cache as initialized. Use for tests only. */
0186     void setKeys(const std::vector<GpgME::Key> &keys);
0187 
0188     void setGroups(const std::vector<KeyGroup> &groups);
0189 
0190 public Q_SLOTS:
0191     void clear();
0192     void startKeyListing(GpgME::Protocol proto = GpgME::UnknownProtocol)
0193     {
0194         reload(proto);
0195     }
0196     void reload(GpgME::Protocol proto = GpgME::UnknownProtocol);
0197     void cancelKeyListing();
0198 
0199 Q_SIGNALS:
0200     void keyListingDone(const GpgME::KeyListResult &result);
0201     void keysMayHaveChanged();
0202     void groupAdded(const Kleo::KeyGroup &group);
0203     void groupUpdated(const Kleo::KeyGroup &group);
0204     void groupRemoved(const Kleo::KeyGroup &group);
0205 
0206 private:
0207     class RefreshKeysJob;
0208 
0209     class Private;
0210     QScopedPointer<Private> const d;
0211 };
0212 
0213 }
0214 
0215 Q_DECLARE_OPERATORS_FOR_FLAGS(Kleo::KeyCache::Options)