Imported Upstream version 17.6.3
[platform/upstream/libzypp.git] / zypp / KeyRing.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/KeyRing.h
10  *
11 */
12 #ifndef ZYPP_KEYRING_H
13 #define ZYPP_KEYRING_H
14
15 #include <iosfwd>
16 #include <map>
17 #include <list>
18 #include <set>
19 #include <string>
20
21 #include "zypp/base/ReferenceCounted.h"
22 #include "zypp/base/Flags.h"
23 #include "zypp/Callback.h"
24 #include "zypp/base/PtrTypes.h"
25 #include "zypp/Locale.h"
26 #include "zypp/PublicKey.h"
27 #include "zypp/KeyContext.h"
28
29 ///////////////////////////////////////////////////////////////////
30 namespace zypp
31 { /////////////////////////////////////////////////////////////////
32
33   DEFINE_PTR_TYPE(KeyRing);
34
35   /** Callbacks from signature verification workflow.
36    *
37    * Per default all methods answer \c false. This may be canged
38    * by calling \ref KeyRing::setDefaultAccept.
39    * \code
40    *  KeyRing::setDefaultAccept( KeyRing::ACCEPT_UNSIGNED_FILE | KeyRing::ACCEPT_VERIFICATION_FAILED );
41    * \endcode
42    * \see \ref KeyRing
43   */
44   struct KeyRingReport : public callback::ReportBase
45   {
46     /**
47      * User reply options for the askUserToTrustKey callback.
48      *
49      * \param filedes Name of the file (repo alias) or filename if not available
50      */
51     enum KeyTrust
52     {
53       /**
54        * User has chosen not to trust the key.
55        */
56       KEY_DONT_TRUST = 0,
57       /**
58        * This basically means, we knew the key, but it was not trusted. User
59        * has chosen to continue, but not import the key.
60        */
61       KEY_TRUST_TEMPORARILY,
62       /**
63        * Import the key.
64        * This means saving the key in the trusted database so next run it will appear as trusted.
65        * Nothing to do with KEY_TRUST_TEMPORARILY, as you CAN trust a key without importing it,
66        * basically you will be asked every time again.
67        * There are programs who prefer to manage the trust keyring on their own and use trustKey
68        * without importing it into rpm.
69        */
70       KEY_TRUST_AND_IMPORT
71     };
72
73     /**
74      * Ask user to trust and/or import the key to trusted keyring.
75      * \see KeyTrust
76      */
77     virtual KeyTrust askUserToAcceptKey( const PublicKey &key, const KeyContext &keycontext = KeyContext() );
78
79     /** Informal callback showing the trusted key that will be used for verification. */
80     virtual void infoVerify( const std::string & file_r, const PublicKeyData & keyData_r, const KeyContext &keycontext = KeyContext() );
81
82     virtual bool askUserToAcceptUnsignedFile( const std::string &file, const KeyContext &keycontext = KeyContext() );
83
84     /**
85      * we DONT know the key, only its id, but we have never seen it, the difference
86      * with trust key is that if you dont have it, you can't import it later.
87      * The answer means continue yes or no?
88      *
89      */
90     virtual bool askUserToAcceptUnknownKey( const std::string &file, const std::string &id, const KeyContext &keycontext = KeyContext() );
91
92     /**
93      * The file \ref filedesc is signed but the verification failed
94      *
95      * \param filedesc Filename or its description.
96      */
97     virtual bool askUserToAcceptVerificationFailed( const std::string &file, const PublicKey &key, const KeyContext &keycontext = KeyContext() );
98
99     /**
100      * Ask user to trust and/or import the package key to trusted keyring, using ReportBase::report
101      *
102      * The UserData object will have the following fields:
103      * UserData::type           \ref ACCEPT_PACKAGE_KEY_REQUEST
104      * "PublicKey"              The PublicKey to be accepted
105      * "KeyContext"             The KeyContext
106      *
107      * Userdata accepted:
108      * "TrustKey"                       bool user can either trust or not trust the key
109      *
110      * \see KeyTrust
111      * \sa ReportBase::report
112      * \note this is a non virtual function and will use ReportBase::report to send the report.
113      *
114      */
115     bool askUserToAcceptPackageKey( const PublicKey &key_r, const KeyContext &keycontext_r = KeyContext() );
116     /** \relates askUserToAcceptPackageKey generic reports UserData::type */
117     constexpr static const char * ACCEPT_PACKAGE_KEY_REQUEST = "KeyRingReport/AcceptPackageKey";
118
119     /**
120      * Notify the user about keys that were not imported from the
121      * rpm key database into zypp keyring
122      *
123      * The UserData object will have the following fields:
124      * UserData::type                   \ref KEYS_NOT_IMPORTED_REPORT
125      * std::set<Edition> "Keys"         set of keys that were not imported
126      *
127      */
128      void reportNonImportedKeys( const std::set<Edition> &keys_r );
129      /** \relates reportNonImportedKeys generic reports UserData::type */
130      constexpr static const char *KEYS_NOT_IMPORTED_REPORT = "KeyRingReport/KeysNotImported";
131
132   };
133
134   struct KeyRingSignals : public callback::ReportBase
135   {
136     virtual void trustedKeyAdded( const PublicKey &/*key*/ )
137     {}
138     virtual void trustedKeyRemoved( const PublicKey &/*key*/ )
139     {}
140   };
141
142   class KeyRingException : public Exception
143    {
144      public:
145        /** Ctor taking message.
146       * Use \ref ZYPP_THROW to throw exceptions.
147         */
148        KeyRingException()
149        : Exception( "Bad Key Exception" )
150        {}
151        /** Ctor taking message.
152         * Use \ref ZYPP_THROW to throw exceptions.
153         */
154        KeyRingException( const std::string & msg_r )
155        : Exception( msg_r )
156        {}
157        /** Dtor. */
158        virtual ~KeyRingException() throw() {};
159    };
160
161   ///////////////////////////////////////////////////////////////////
162   //
163   //    CLASS NAME : KeyRing
164   //
165   /** Gpg key handling.
166    *
167   */
168   class KeyRing : public base::ReferenceCounted, private base::NonCopyable
169   {
170     friend std::ostream & operator<<( std::ostream & str, const KeyRing & obj );
171
172     public:
173       /** \name Default answers in verification workflow.
174        * Per default all answers are \c false.
175        */
176       //@{
177       /** \ref DefaultAccept flags (\see \ref base::Flags) are used to
178        *  define the default callback answers during signature verification.
179        * \code
180        *  KeyRing::setDefaultAccept( KeyRing::ACCEPT_UNSIGNED_FILE | ACCEPT_VERIFICATION_FAILED );
181        * \endcode
182        * \see \ref KeyRingReport.
183        */
184       enum DefaultAcceptBits
185       {
186         ACCEPT_NOTHING             = 0x0000,
187         ACCEPT_UNSIGNED_FILE       = 0x0001,
188         ACCEPT_UNKNOWNKEY          = 0x0002,
189         TRUST_KEY_TEMPORARILY      = 0x0004,
190         TRUST_AND_IMPORT_KEY       = 0x0008,
191         ACCEPT_VERIFICATION_FAILED = 0x0010,
192       };
193       ZYPP_DECLARE_FLAGS( DefaultAccept, DefaultAcceptBits );
194
195       /** Get the active accept bits. */
196       static DefaultAccept defaultAccept();
197
198       /** Set the active accept bits. */
199       static void setDefaultAccept( DefaultAccept value_r );
200      //@}
201
202   public:
203     /** Implementation  */
204     class Impl;
205
206   public:
207     /** Default ctor */
208     KeyRing(const Pathname &baseTmpDir);
209
210     /**
211      * imports a key from a file.
212      * throw if key was not imported
213      */
214     void importKey( const PublicKey &key, bool trusted = false);
215
216     /** Initial import from \ref RpmDb. */
217     void multiKeyImport( const Pathname & keyfile_r, bool trusted_r = false );
218
219     void dumpTrustedPublicKey( const std::string &id, std::ostream &stream )
220     { dumpPublicKey(id, true, stream); }
221
222     void dumpUntrustedPublicKey( const std::string &id, std::ostream &stream )
223     { dumpPublicKey(id, false, stream); }
224
225     void dumpPublicKey( const std::string &id, bool trusted, std::ostream &stream );
226
227     /** Export a public key identified by its key data. */
228     PublicKey exportPublicKey( const PublicKeyData & keyData );
229
230     /** Export a trusted public key identified by its key data. */
231     PublicKey exportTrustedPublicKey( const PublicKeyData & keyData );
232
233     /**
234      * reads the public key id from a signature
235      */
236     std::string readSignatureKeyId( const Pathname &signature );
237
238     /**
239      * true if the key id is trusted
240      */
241     bool isKeyTrusted( const std::string &id );
242
243     /**
244      * true if the key id is knows, that means
245      * at least exist on the untrusted keyring
246      */
247     bool isKeyKnown( const std::string &id );
248
249     /**
250      * removes a key from the keyring.
251      * If trusted is true, Remove it from trusted keyring too.
252      */
253     void deleteKey( const std::string &id, bool trusted =  false );
254
255     /**
256      * Get a list of public keys in the keyring (incl. ASCII armored keys in tmpfiles)
257      */
258     std::list<PublicKey> publicKeys();
259
260     /**
261      * Get a list of trusted public keys in the keyring (incl. ASCII armored keys in tmpfiles)
262      */
263     std::list<PublicKey> trustedPublicKeys();
264
265     /**
266      * Get a list of public key data in the keyring (key data only)
267      */
268     std::list<PublicKeyData> publicKeyData();
269
270     /**
271      * Get a list of trusted public key data in the keyring (key data only)
272      */
273     std::list<PublicKeyData> trustedPublicKeyData();
274
275     /**
276      * Get a trusted public key's data in the keyring (key data only)
277      */
278     PublicKeyData trustedPublicKeyData( const std::string &id );
279
280     /**
281      * Follows a signature verification interacting with the user.
282      * The bool returned depends on user decision to trust or not.
283      *
284      * To propagate user decisions, either connect to the \ref KeyRingReport
285      * or use its static methods to set the desired defaults.
286      *
287      * A second bool passed as reference arg \a sigValid_r tells whether the
288      * signature was actually successfully verified. If \a sigValid_r returns
289      * \c false, but the method \c true, you know it's due to user callback or
290      * defaults.
291      *
292      * \code
293      * struct KeyRingReportReceive : public callback::ReceiveReport<KeyRingReport>
294      * {
295      *   KeyRingReportReceive() { connect(); }
296      *
297      *   // Overload the virtual methods to return the appropriate values.
298      *   virtual bool askUserToAcceptUnsignedFile( const std::string &file );
299      *   ...
300      * };
301      * \endcode
302      *
303      * \param file Path of the file to be verified
304      * \param filedesc Description of the file (to give the user some context)
305      * \param signature Signature to verify the file against
306      * \param sigValid_r Returns whether signature was successfully verified
307      *
308      * \see \ref KeyRingReport
309      */
310     bool verifyFileSignatureWorkflow( const Pathname &file, const std::string &filedesc, const Pathname &signature, bool & sigValid_r, const KeyContext &keycontext = KeyContext());
311     /** \overload legacy version without 'bool & sigValid_r' */
312     bool verifyFileSignatureWorkflow( const Pathname &file, const std::string filedesc, const Pathname &signature, const KeyContext &keycontext = KeyContext());
313
314     /**
315      * Verifies a file against a signature, with no user interaction
316      *
317      * \param file Path of the file to be verified
318      * \param signature Signature to verify the file against
319      */
320     bool verifyFileSignature( const Pathname &file, const Pathname &signature );
321
322     bool verifyFileTrustedSignature( const Pathname &file, const Pathname &signature );
323
324     /** Dtor */
325     ~KeyRing();
326
327   private:
328     /** Pointer to implementation */
329     RW_pointer<Impl> _pimpl;
330   };
331   ///////////////////////////////////////////////////////////////////
332
333   /** \relates KeyRing Stream output */
334   inline std::ostream & operator<<( std::ostream & str, const KeyRing & /*obj*/ )
335   {
336     //return str << obj.asString();
337     return str;
338   }
339
340   /** \relates KeyRing::DefaultAccept  */
341   ZYPP_DECLARE_OPERATORS_FOR_FLAGS( KeyRing::DefaultAccept );
342
343   ///////////////////////////////////////////////////////////////////
344
345   namespace target
346   {
347     namespace rpm
348     {
349       /** Internal connection to rpm database. Not for public use. */
350       struct KeyRingSignals : public ::zypp::KeyRingSignals
351       {};
352     }
353   }
354
355  /////////////////////////////////////////////////////////////////
356 } // namespace zypp
357 ///////////////////////////////////////////////////////////////////
358 #endif // ZYPP_KEYRING_H