File indexing completed on 2024-06-16 04:58:24

0001 /*  -*- c++ -*-
0002     keyresolver.h
0003 
0004     This file is part of libkleopatra, the KDE keymanagement library
0005     SPDX-FileCopyrightText: 2018 Intevation GmbH
0006     SPDX-FileCopyrightText: 2021 g10 Code GmbH
0007     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #pragma once
0013 
0014 #include "kleo_export.h"
0015 
0016 #include <QMap>
0017 #include <QObject>
0018 #include <QString>
0019 #include <QStringList>
0020 
0021 #include <gpgme++/global.h>
0022 
0023 #include <memory>
0024 #include <vector>
0025 
0026 namespace GpgME
0027 {
0028 class Key;
0029 }
0030 
0031 namespace Kleo
0032 {
0033 /**
0034  * Class to find Keys for E-Mail signing and encryption.
0035  *
0036  * The KeyResolver uses the Keycache to find keys for signing
0037  * or encryption.
0038  *
0039  * Overrides can be provided for address book integration.
0040  *
0041  * If no override key(s) are provided for an address and no
0042  * KeyGroup for this address is found, then the key
0043  * with a uid that matches the address and has the highest
0044  * validity is used. If both keys have the same validity,
0045  * then the key with the newest subkey is used.
0046  *
0047  * The KeyResolver also supports groups so the number of
0048  * encryption keys does not necessarily
0049  * need to match the amount of sender addresses. For this reason
0050  * maps are used to map addresses to lists of keys.
0051  *
0052  * The keys can be OpenPGP keys and S/MIME (CMS) keys.
0053  * As a caller you need to partition the keys by their protocol and
0054  * send one message for each protocol for the recipients and signed
0055  * by the signing keys.
0056  */
0057 class KLEO_EXPORT KeyResolver : public QObject
0058 {
0059     Q_OBJECT
0060 
0061 public:
0062     /**
0063      * Solution represents the solution found by the KeyResolver.
0064      */
0065     struct Solution {
0066         /**
0067          * This property holds a hint at the protocol of the signing and encryption
0068          * keys, i.e. if @p protocol is either @c GpgME::OpenPGP or @c GpgME::CMS,
0069          * then all keys have the corresponding protocol. Otherwise, the keys have
0070          * mixed protocols.
0071          */
0072         GpgME::Protocol protocol = GpgME::UnknownProtocol;
0073 
0074         /**
0075          * This property contains the signing keys to use. It contains zero or one
0076          * OpenPGP key and zero or one S/MIME key.
0077          */
0078         std::vector<GpgME::Key> signingKeys;
0079 
0080         /**
0081          * This property contains the encryption keys to use for the different recipients.
0082          *
0083          * The list of keys will contain for regular users either one S/MIME key
0084          * or one OpenPGP key. For a group address, the list of keys will instead contain
0085          * the keys required to encrypt for every member of the group.
0086          *
0087          * The keys of the map represent the normalized email addresses of the recipients.
0088          *
0089          * @see Kleo::KeyGroup
0090          */
0091         QMap<QString, std::vector<GpgME::Key>> encryptionKeys;
0092     };
0093 
0094     /** Creates a new key resolver object.
0095      *
0096      * @param encrypt: Should encryption keys be selected.
0097      * @param sign: Should signing keys be selected.
0098      * @param protocol: A specific key protocol (OpenPGP, S/MIME) for selection. Default: Both protocols.
0099      * @param allowMixed: Specify if multiple message formats may be resolved.
0100      **/
0101     explicit KeyResolver(bool encrypt, bool sign, GpgME::Protocol protocol = GpgME::UnknownProtocol, bool allowMixed = true);
0102 
0103     ~KeyResolver() override;
0104 
0105     /**
0106      *  Set the list of recipient addresses.
0107      *
0108      *  @param addresses: A list of (not necessarily normalized) email addresses
0109      */
0110     void setRecipients(const QStringList &addresses);
0111 
0112     /**
0113      * Set the sender's address.
0114      *
0115      * This address is added to the list of recipients (for encryption to self)
0116      * and it is used for signing key resolution, if the signing keys are not
0117      * explicitly set through setSigningKeys.
0118      *
0119      * @param sender: The sender of this message.
0120      */
0121     void setSender(const QString &sender);
0122 
0123     /**
0124      * Set up possible override keys for recipients addresses.
0125      * The keys for the fingerprints are looked
0126      * up and used when found.
0127      *
0128      * Overrides for @c GpgME::UnknownProtocol are used regardless of the
0129      * protocol. Overrides for a specific protocol are only used for this
0130      * protocol. Overrides for @c GpgME::UnknownProtocol takes precedence over
0131      * overrides for a specific protocol.
0132      *
0133      * @param overrides: A map of \<protocol\> -> (\<address\> \<fingerprints\>)
0134      */
0135     void setOverrideKeys(const QMap<GpgME::Protocol, QMap<QString, QStringList>> &overrides);
0136 
0137     /**
0138      * Set explicit signing keys to use.
0139      */
0140     void setSigningKeys(const QStringList &fingerprints);
0141 
0142     /**
0143      * Set the minimum user id validity for autoresolution.
0144      *
0145      * The default value is marginal
0146      *
0147      * @param validity int representation of a GpgME::UserID::Validity.
0148      */
0149     void setMinimumValidity(int validity);
0150 
0151     /**
0152      * Get the result of the resolution.
0153      *
0154      * @return the resolved keys for signing and encryption.
0155      */
0156     Solution result() const;
0157 
0158     /**
0159      * Starts the key resolving procedure. Emits keysResolved on success or
0160      * error.
0161      *
0162      * @param showApproval: If set to true a dialog listing the keys
0163      *                      will always be shown.
0164      * @param parentWidget: Optional, a Widget to use as parent for dialogs.
0165      */
0166     void start(bool showApproval, QWidget *parentWidget = nullptr);
0167 
0168     /**
0169      * Set window flags for a possible dialog.
0170      */
0171     void setDialogWindowFlags(Qt::WindowFlags flags);
0172 
0173     /**
0174      * Set the protocol that is preferred to be displayed first when
0175      * it is not clear from the keys. E.g. if both OpenPGP and S/MIME
0176      * can be resolved.
0177      */
0178     void setPreferredProtocol(GpgME::Protocol proto);
0179 
0180 Q_SIGNALS:
0181     /**
0182      * Emitted when key resolution finished.
0183      *
0184      * @param success: The general result. If true continue sending,
0185      *                 if false abort.
0186      * @param sendUnencrypted: If there could be no key found for one of
0187      *                         the recipients the user was queried if the
0188      *                         mail should be sent out unencrypted.
0189      *                         sendUnencrypted is true if the user agreed
0190      *                         to this.*/
0191     void keysResolved(bool success, bool sendUnencrypted);
0192 
0193 private:
0194     class Private;
0195     std::unique_ptr<Private> d;
0196 };
0197 } // namespace Kleo