You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
320 lines
12 KiB
320 lines
12 KiB
/* -*- c++ -*-
|
|
keyresolver.h
|
|
|
|
This file is part of libkleopatra, the KDE keymanagement library
|
|
Copyright (c) 2004 Klarälvdalens Datakonsult AB
|
|
|
|
Based on kpgp.h
|
|
Copyright (C) 2001,2002 the KPGP authors
|
|
See file libkdenetwork/AUTHORS.kpgp for details
|
|
|
|
Libkleopatra is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
Libkleopatra is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
In addition, as a special exception, the copyright holders give
|
|
permission to link the code of this program with any edition of
|
|
the Qt library by Trolltech AS, Norway (or with modified versions
|
|
of Qt that use the same license as Qt), and distribute linked
|
|
combinations including the two. You must obey the GNU General
|
|
Public License in all respects for all of the code used other than
|
|
Qt. If you modify this file, you may extend this exception to
|
|
your version of the file, but you are not obligated to do so. If
|
|
you do not wish to do so, delete this exception statement from
|
|
your version.
|
|
*/
|
|
|
|
#ifndef __KLEO_KEYRESOLVER_H__
|
|
#define __KLEO_KEYRESOLVER_H__
|
|
|
|
#include <ui/keyapprovaldialog.h>
|
|
|
|
#include <kleo/enum.h>
|
|
|
|
#include <kpgp.h> // for Kpgp::Result
|
|
#include <gpgmepp/key.h>
|
|
|
|
#include <vector>
|
|
|
|
class QStringList;
|
|
|
|
namespace Kleo {
|
|
|
|
|
|
/**
|
|
\short A class to resolve signing/encryption keys w.r.t. per-recipient preferences
|
|
|
|
\section Step 1: Set the information needed
|
|
|
|
The constructor takes some basic options as arguments, such as
|
|
whether or not encryption was actually requested. Recipient and
|
|
sender information is then set by using \c
|
|
setEncryptToSelfKeys(), \c setSigningKeys(), \c
|
|
setPrimaryRecipients() (To/Cc) and \c setSecondaryRecipients()
|
|
(Bcc).
|
|
|
|
\section Step 2: Lookup and check per-recipient crypto preferences / Opportunistic Encryption
|
|
|
|
First, \c checkSigningPreferences() goes through all recipient's
|
|
signing perferences, to determine whether or not to sign. It also
|
|
takes into account the available signing keys and whether or not
|
|
the user explicitly requested signing.
|
|
|
|
\c checkEncryptionPreferences() does the same for encryption
|
|
preferences. If opportunistic encryption is enabled, recipients
|
|
without encryption preferences set are treated as if they had a
|
|
preference of \c AskWheneverPossible.
|
|
|
|
In both cases an Action code is returned, with the following
|
|
meanings:
|
|
|
|
<dl><dt>Conflict</dt><dd>A conflict was detected. E.g. one
|
|
recipient's preference was set to "always encrypt", while another
|
|
one's preference was set to "never encrypt". You should ask the
|
|
user what to do.</dd></dt>
|
|
|
|
<dt>DoIt, DontDoIt</dt><dd>Do/Don't sign/encrypt</dd>
|
|
|
|
<dt>Ask</dt><dd>(Some) crypto preferences request to prompt the
|
|
user, so do it.</dd>
|
|
|
|
<dt>Impossible</dt><dd>Signing or encryption is impossible,
|
|
e.g. due to missing keys or unsupported formats.</dd> </dl>
|
|
|
|
\section Step 3: Resolve all keys.
|
|
|
|
In case signing or encryption was implicitly or explicitly
|
|
requested by the user, \c resolveAllKeys() tries to find signing
|
|
keys for each required format, as well as encryption keys for all
|
|
recipients (incl. the sender, if encrypt-to-self is set).
|
|
|
|
\section Step 4: Get signing keys.
|
|
|
|
If, after key resolving, signing is still requested and
|
|
apparently possible, you can get the result of all this by
|
|
iterating over the available message formats and retrieving the
|
|
set of signing keys to use with a call to \c signingKeys().
|
|
|
|
\section Step 5: Get encrytion key sets.
|
|
|
|
If after key resolving, encryption is still requested and
|
|
apparently possible, you can get the result of all this by
|
|
calling \c encryptionItems() with the current message format at
|
|
hand as its argument.
|
|
|
|
This will return a list of recipient-list/key-list pairs that
|
|
each describe a copy of the (possibly signed) message to be
|
|
encrypted independantly.
|
|
|
|
Note that it's only necessary to sign the message once for each
|
|
message format, although it might be necessary to create more
|
|
than one message when encrypting. This is because encryption
|
|
allows the recipients to learn about the other recipients the
|
|
message was encrypted to, so each secondary (BCC) recipient need
|
|
a copy of it's own to hide the other secondary recipients.
|
|
*/
|
|
|
|
class KeyResolver {
|
|
public:
|
|
KeyResolver( bool encToSelf, bool showApproval, bool oppEncryption,
|
|
unsigned int format,
|
|
int encrKeyNearExpiryThresholdDays,
|
|
int signKeyNearExpiryThresholdDays,
|
|
int encrRootCertNearExpiryThresholdDays,
|
|
int signRootCertNearExpiryThresholdDays,
|
|
int encrChainCertNearExpiryThresholdDays,
|
|
int signChainCertNearExpiryThresholdDays );
|
|
|
|
~KeyResolver();
|
|
|
|
struct Item : public KeyApprovalDialog::Item {
|
|
Item()
|
|
: KeyApprovalDialog::Item(),
|
|
signPref( UnknownSigningPreference ),
|
|
format( AutoFormat ),
|
|
needKeys( true ) {}
|
|
Item( const QString & a,
|
|
EncryptionPreference e, SigningPreference s,
|
|
CryptoMessageFormat f )
|
|
: KeyApprovalDialog::Item( a, std::vector<GpgME::Key>(), e ),
|
|
signPref( s ), format( f ), needKeys( true ) {}
|
|
Item( const QString & a, const std::vector<GpgME::Key> & k,
|
|
EncryptionPreference e, SigningPreference s,
|
|
CryptoMessageFormat f )
|
|
: KeyApprovalDialog::Item( a, k, e ),
|
|
signPref( s ), format( f ), needKeys( false ) {}
|
|
|
|
SigningPreference signPref;
|
|
CryptoMessageFormat format;
|
|
bool needKeys;
|
|
};
|
|
|
|
|
|
/**
|
|
Set the fingerprints of keys to be used for encrypting to
|
|
self. Also looks them up and complains if they're not usable or
|
|
found.
|
|
*/
|
|
Kpgp::Result setEncryptToSelfKeys( const QStringList & fingerprints );
|
|
/**
|
|
Set the fingerprints of keys to be used for signing. Also
|
|
looks them up and complains if they're not usable or found.
|
|
*/
|
|
Kpgp::Result setSigningKeys( const QStringList & fingerprints );
|
|
/**
|
|
Set the list of primary (To/CC) recipient addresses. Also looks
|
|
up possible keys, but doesn't interact with the user.
|
|
*/
|
|
void setPrimaryRecipients( const QStringList & addresses );
|
|
/**
|
|
Set the list of secondary (BCC) recipient addresses. Also looks
|
|
up possible keys, but doesn't interact with the user.
|
|
*/
|
|
void setSecondaryRecipients( const QStringList & addresses );
|
|
|
|
|
|
/**
|
|
Determine whether to sign or not, depending on the
|
|
per-recipient signing preferences, as well as the availability
|
|
of usable signing keys.
|
|
*/
|
|
Action checkSigningPreferences( bool signingRequested ) const;
|
|
/**
|
|
Determine whether to encrypt or not, depending on the
|
|
per-recipient encryption preferences, as well as the availability
|
|
of usable encryption keys.
|
|
*/
|
|
Action checkEncryptionPreferences( bool encryptionRequested ) const;
|
|
|
|
/**
|
|
Queries the user for missing keys and displays a key approval
|
|
dialog if needed.
|
|
*/
|
|
Kpgp::Result resolveAllKeys( bool& signingRequested, bool& encryptionRequested );
|
|
|
|
/**
|
|
@return the signing keys to use (if any) for the given message
|
|
format.
|
|
*/
|
|
std::vector<GpgME::Key> signingKeys( CryptoMessageFormat f ) const;
|
|
|
|
struct SplitInfo {
|
|
SplitInfo() {}
|
|
SplitInfo( const QStringList & r ) : recipients( r ) {}
|
|
SplitInfo( const QStringList & r, const std::vector<GpgME::Key> & k )
|
|
: recipients( r ), keys( k ) {}
|
|
QStringList recipients;
|
|
std::vector<GpgME::Key> keys;
|
|
};
|
|
/** @return the found distinct sets of items for format \a f. The
|
|
returned vector will contain more than one item only if
|
|
secondary recipients have been specified.
|
|
*/
|
|
std::vector<SplitInfo> encryptionItems( CryptoMessageFormat f ) const;
|
|
|
|
private:
|
|
void dump() const;
|
|
std::vector<Item> getEncryptionItems( const QStringList & recipients );
|
|
std::vector<GpgME::Key> getEncryptionKeys( const QString & recipient, bool quiet ) const;
|
|
|
|
Kpgp::Result showKeyApprovalDialog();
|
|
|
|
bool encryptionPossible() const;
|
|
bool signingPossible() const;
|
|
Kpgp::Result resolveEncryptionKeys( bool signingRequested );
|
|
Kpgp::Result resolveSigningKeysForEncryption();
|
|
Kpgp::Result resolveSigningKeysForSigningOnly();
|
|
Kpgp::Result checkKeyNearExpiry( const GpgME::Key & key,
|
|
const char * dontAskAgainName, bool mine,
|
|
bool sign, bool ca=false, int recurse_limit=100,
|
|
const GpgME::Key & orig_key=GpgME::Key::null ) const;
|
|
void collapseAllSplitInfos();
|
|
void addToAllSplitInfos( const std::vector<GpgME::Key> & keys, unsigned int formats );
|
|
void addKeys( const std::vector<Item> & items, CryptoMessageFormat f );
|
|
void addKeys( const std::vector<Item> & items );
|
|
QStringList allRecipients() const;
|
|
std::vector<GpgME::Key> signingKeysFor( CryptoMessageFormat f ) const;
|
|
std::vector<GpgME::Key> encryptToSelfKeysFor( CryptoMessageFormat f ) const;
|
|
|
|
std::vector<GpgME::Key> lookup( const QStringList & patterns, bool secret=false ) const;
|
|
|
|
bool haveTrustedEncryptionKey( const QString & person ) const;
|
|
|
|
std::vector<GpgME::Key> selectKeys( const QString & person, const QString & msg,
|
|
const std::vector<GpgME::Key> & selectedKeys=std::vector<GpgME::Key>() ) const;
|
|
|
|
QStringList keysForAddress( const QString & address ) const;
|
|
void setKeysForAddress( const QString & address, const QStringList& pgpKeyFingerprints, const QStringList& smimeCertFingerprints ) const;
|
|
|
|
bool encryptToSelf() const { return mEncryptToSelf; }
|
|
bool showApprovalDialog() const { return mShowApprovalDialog; }
|
|
|
|
int encryptKeyNearExpiryWarningThresholdInDays() const {
|
|
return mEncryptKeyNearExpiryWarningThreshold;
|
|
}
|
|
int signingKeyNearExpiryWarningThresholdInDays() const {
|
|
return mSigningKeyNearExpiryWarningThreshold;
|
|
}
|
|
|
|
int encryptRootCertNearExpiryWarningThresholdInDays() const {
|
|
return mEncryptRootCertNearExpiryWarningThreshold;
|
|
}
|
|
int signingRootCertNearExpiryWarningThresholdInDays() const {
|
|
return mSigningRootCertNearExpiryWarningThreshold;
|
|
}
|
|
|
|
int encryptChainCertNearExpiryWarningThresholdInDays() const {
|
|
return mEncryptChainCertNearExpiryWarningThreshold;
|
|
}
|
|
int signingChainCertNearExpiryWarningThresholdInDays() const {
|
|
return mSigningChainCertNearExpiryWarningThreshold;
|
|
}
|
|
|
|
struct ContactPreferences {
|
|
ContactPreferences();
|
|
Kleo::EncryptionPreference encryptionPreference;
|
|
Kleo::SigningPreference signingPreference;
|
|
Kleo::CryptoMessageFormat cryptoMessageFormat;
|
|
QStringList pgpKeyFingerprints;
|
|
QStringList smimeCertFingerprints;
|
|
};
|
|
|
|
ContactPreferences lookupContactPreferences( const QString& address ) const;
|
|
void saveContactPreference( const QString& email, const ContactPreferences& pref ) const;
|
|
|
|
private:
|
|
class EncryptionPreferenceCounter;
|
|
friend class ::Kleo::KeyResolver::EncryptionPreferenceCounter;
|
|
class SigningPreferenceCounter;
|
|
friend class ::Kleo::KeyResolver::SigningPreferenceCounter;
|
|
|
|
class Private;
|
|
Private * d;
|
|
|
|
bool mEncryptToSelf;
|
|
const bool mShowApprovalDialog : 1;
|
|
const bool mOpportunisticEncyption : 1;
|
|
const unsigned int mCryptoMessageFormats;
|
|
|
|
const int mEncryptKeyNearExpiryWarningThreshold;
|
|
const int mSigningKeyNearExpiryWarningThreshold;
|
|
const int mEncryptRootCertNearExpiryWarningThreshold;
|
|
const int mSigningRootCertNearExpiryWarningThreshold;
|
|
const int mEncryptChainCertNearExpiryWarningThreshold;
|
|
const int mSigningChainCertNearExpiryWarningThreshold;
|
|
};
|
|
|
|
} // namespace Kleo
|
|
|
|
#endif // __KLEO_KEYRESOLVER_H__
|