Imported Upstream version 17.13.0
[platform/upstream/libzypp.git] / zypp / PublicKey.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/PublicKey.h
10  *
11 */
12 #ifndef ZYPP_PUBLICKEY_H
13 #define ZYPP_PUBLICKEY_H
14
15 #include <iosfwd>
16 #include <map>
17 #include <list>
18 #include <set>
19 #include <string>
20
21 #include "zypp/base/Iterable.h"
22 #include "zypp/base/PtrTypes.h"
23 #include "zypp/base/Exception.h"
24 #include "zypp/base/DrunkenBishop.h"
25 #include "zypp/Pathname.h"
26 #include "zypp/Edition.h"
27 #include "zypp/Date.h"
28
29 struct _gpgme_key;
30 struct _gpgme_subkey;
31
32 ///////////////////////////////////////////////////////////////////
33 namespace zypp
34 { /////////////////////////////////////////////////////////////////
35
36   namespace filesystem
37   {
38     class TmpFile;
39   }
40   class PublicKeyData;
41   class KeyManagerCtx;
42
43   ///////////////////////////////////////////////////////////////////
44   /// \class BadKeyException
45   /// \brief Exception thrown when the supplied key is not a valid gpg key
46   ///////////////////////////////////////////////////////////////////
47   class BadKeyException : public Exception
48   {
49     public:
50       /** Ctor taking message.
51      * Use \ref ZYPP_THROW to throw exceptions.
52        */
53       BadKeyException()
54       : Exception( "Bad Key Exception" )
55       {}
56
57       Pathname keyFile() const
58       { return _keyfile; }
59
60       /** Ctor taking message.
61        * Use \ref ZYPP_THROW to throw exceptions.
62        */
63       BadKeyException( const std::string & msg_r, const Pathname &keyfile = Pathname() )
64       : Exception( msg_r ), _keyfile(keyfile)
65       {}
66       /** Dtor. */
67       virtual ~BadKeyException() throw() {};
68     private:
69       Pathname _keyfile;
70   };
71   ///////////////////////////////////////////////////////////////////
72
73   ///////////////////////////////////////////////////////////////////
74   /// \class PublicSubkeyData
75   /// \brief Class representing a GPG Public Keys subkeys.
76   /// \see \ref PublicKeyData.
77   ///////////////////////////////////////////////////////////////////
78   class PublicSubkeyData
79   {
80   public:
81     /** Default constructed: empty data. */
82     PublicSubkeyData();
83
84     ~PublicSubkeyData();
85
86     /** Whether this contains valid data (not default constructed). */
87     explicit operator bool() const;
88
89   public:
90     /** Subkey ID. */
91     std::string id() const;
92
93     /** Creation date. */
94     Date created() const;
95
96     /** Expiry date, or \c Date() if the key never expires. */
97     Date expires() const;
98
99     /**  Whether the key has expired. */
100     bool expired() const;
101
102     /** Number of days (24h) until the key expires (or since it exired).
103      * A value of \c 0 means the key will expire within the next 24h.
104      * Negative values indicate the key has expired less than \c N days ago.
105      * For keys without expiration date \c INT_MAX is returned.
106      */
107     int daysToLive() const;
108
109     /** Simple string representation.
110      * Encodes \ref id, \ref created and \ref expires
111      * \code
112      * 640DB551 2016-04-12 [expires: 2019-04-12]
113      * \endcode
114      */
115     std::string asString() const;
116
117   private:
118     class Impl;
119     RWCOW_pointer<Impl> _pimpl;
120     friend class PublicKeyData;
121     friend std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj );
122     PublicSubkeyData(const _gpgme_subkey *rawSubKeyData);
123   };
124   ///////////////////////////////////////////////////////////////////
125
126   /** \relates PublicSubkeyData Stream output */
127   inline std::ostream & operator<<( std::ostream & str, const PublicSubkeyData & obj )
128   { return str << obj.asString(); }
129
130   ///////////////////////////////////////////////////////////////////
131   /// \class PublicKeyData
132   /// \brief Class representing one GPG Public Keys data.
133   /// \ref PublicKeyData are provided e.g. by a \ref PublicKey or
134   /// a \ref KeyRing. \ref PublicKeyData are usually easier to
135   /// retrieve and sufficient unless you actually need an ASCII
136   /// armored version of the key placed in a tempfile. In this
137   /// case use \ref PublicKey.
138   ///////////////////////////////////////////////////////////////////
139   class PublicKeyData
140   {
141   public:
142     /** Default constructed: empty data. */
143     PublicKeyData();
144
145     ~PublicKeyData();
146
147     /** Whether this contains valid data (not default constructed). */
148     explicit operator bool() const;
149
150   public:
151     /** Key ID. */
152     std::string id() const;
153
154     /** Key name.  */
155     std::string name() const;
156
157     /** Key fingerprint.*/
158     std::string fingerprint() const;
159
160     /** Creation / last modification date (latest selfsig). */
161     Date created() const;
162
163     /** Expiry date, or \c Date() if the key never expires. */
164     Date expires() const;
165
166     /**  Whether the key has expired. */
167     bool expired() const;
168
169     /** Number of days (24h) until the key expires (or since it exired).
170      * A value of \c 0 means the key will expire within the next 24h.
171      * Negative values indicate the key has expired less than \c N days ago.
172      * For keys without expiration date \c INT_MAX is returned.
173      */
174     int daysToLive() const;
175
176     /** * Expiry info in a human readable form.
177      * The exipry daye plus an annotation if the key has expired, or will
178      * expire within 90 days.
179      * \code
180      * (does not expire)
181      * Tue May 11 13:37:33 CEST 2010
182      * Tue May 11 13:37:33 CEST 2010 (expires in 90 days)
183      * Tue May 11 13:37:33 CEST 2010 (expires in 1 day)
184      * Tue May 11 13:37:33 CEST 2010 (expires within 24h)
185      * Tue May 11 13:37:33 CEST 2010 (EXPIRED)
186      * \endcode
187      */
188     std::string expiresAsString() const;
189
190     /** Gpg-pubkey version as computed by rpm (trailing 8 byte \ref id) */
191     std::string gpgPubkeyVersion() const;
192
193     /** Gpg-pubkey release as computed by rpm (hexencoded \ref created) */
194     std::string gpgPubkeyRelease() const;
195
196     /** Gpg-pubkey name as computed by rpm*/
197     std::string rpmName () const;
198
199     /** Gpg-pubkey \ref Edition built from version and release.*/
200     Edition gpgPubkeyEdition() const
201     { return Edition( gpgPubkeyVersion(), gpgPubkeyRelease() ); }
202
203     /** Simple string representation.
204      * Encodes \ref id, \ref gpgPubkeyRelease, \ref name and \ref fingerprint.
205      * \code
206      * [E3A5C360307E3D54-4be01a65] [SuSE Package Signing Key <build@suse.de>] [4E98E67519D98DC7362A5990E3A5C360307E3D54]
207      * \endcode
208      */
209     std::string asString() const;
210
211   public:
212     typedef const PublicSubkeyData * SubkeyIterator;
213
214     /** Whether \ref subkeys is not empty. */
215     bool hasSubkeys() const;
216
217     /** Iterate any subkeys. */
218     Iterable<SubkeyIterator> subkeys() const;
219
220     /** Whether \a id_r is the \ref id of the primary key or of a subkey. */
221     bool providesKey( const std::string & id_r ) const;
222
223   public:
224     /** Random art fingerprint visualization type (\ref base::DrunkenBishop). */
225     typedef base::DrunkenBishop AsciiArt;
226
227     /** Random art fingerprint visualization (\ref base::DrunkenBishop).
228      * \code
229      *    PublicKeyData key;
230      *    cout << key.asciiArt( PublicKey::AsciiArt::USE_COLOR ) << endl;
231      * \endcode
232      */
233     AsciiArt asciiArt() const;
234
235   private:
236     class Impl;
237     RWCOW_pointer<Impl> _pimpl;
238
239     friend class KeyManagerCtx;
240     static PublicKeyData fromGpgmeKey(_gpgme_key *data);
241
242     PublicKeyData(shared_ptr<Impl> data);
243     friend std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj );
244   };
245   ///////////////////////////////////////////////////////////////////
246
247   /** \relates PublicKeyData Stream output */
248   inline std::ostream & operator<<( std::ostream & str, const PublicKeyData & obj )
249   { return str << obj.asString(); }
250
251   /** \relates PublicKeyData Detailed stream output */
252   std::ostream & dumpOn( std::ostream & str, const PublicKeyData & obj );
253
254   /** \relates PublicKeyData Equal based on  fingerprint anf creation date. */
255   bool operator==( const PublicKeyData & lhs, const PublicKeyData & rhs );
256
257   /** \relates PublicKeyData NotEqual. */
258   inline bool operator!=( const PublicKeyData & lhs, const PublicKeyData & rhs )
259   { return !( lhs == rhs ); }
260
261   ///////////////////////////////////////////////////////////////////
262   /// \class PublicKey
263   /// \brief Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
264   ///
265   /// If you don't need the ASCII armored version of the key stored in
266   /// a tempfile, using \ref PublicKeyData might be sufficient.
267   ///
268   /// \note In case the ASCII armored blob actually contains multiple
269   /// keys, the \b last keys data are made available via the API. The
270   /// additional keys data are made available via \ref hiddenKeys.
271   ///////////////////////////////////////////////////////////////////
272   class PublicKey
273   {
274   public:
275     /** Implementation  */
276     class Impl;
277
278   public:
279     /** Default ctor. */
280     PublicKey();
281
282     /** Ctor taking the key from a file.
283      *
284      * This is quite expensive, as a copy of the file is created and
285      * used. If you can construct PublicKey from a \ref filesystem::TmpFile,
286      * this prevents copying.
287      *
288      * \throws when data does not make a key
289      */
290     explicit PublicKey( const Pathname & keyFile_r );
291
292     /** Ctor reading the key from a \ref TmpFile.
293      *
294      * PublicKey holds a reference on the TmpFile providing the key.
295      *
296      * \throws when data does not make a key
297      */
298     explicit PublicKey( const filesystem::TmpFile & sharedFile_r );
299
300     ~PublicKey();
301
302   public:
303     /** The public keys data (\see \ref PublicKeyData).*/
304     const PublicKeyData & keyData() const;
305
306     typedef PublicKeyData::SubkeyIterator SubkeyIterator;
307
308     bool isValid() const
309     { return ! ( id().empty() || fingerprint().empty() ); }
310
311     std::string id() const;                     //!< \see \ref PublicKeyData
312     std::string name() const;                   //!< \see \ref PublicKeyData
313     std::string fingerprint() const;            //!< \see \ref PublicKeyData
314     Date created() const;                       //!< \see \ref PublicKeyData
315     Date expires() const;                       //!< \see \ref PublicKeyData
316     std::string expiresAsString() const;        //!< \see \ref PublicKeyData
317     bool expired() const;                       //!< \see \ref PublicKeyData
318     int daysToLive() const;                     //!< \see \ref PublicKeyData
319     std::string gpgPubkeyVersion() const;       //!< \see \ref PublicKeyData
320     std::string gpgPubkeyRelease() const;       //!< \see \ref PublicKeyData
321     std::string asString() const;               //!< \see \ref PublicKeyData
322     std::string rpmName () const;
323
324     Edition gpgPubkeyEdition() const            ///!< \see \ref PublicKeyData
325     { return keyData().gpgPubkeyEdition(); }
326
327     bool hasSubkeys() const                     ///!< \see \ref PublicKeyData
328     { return keyData().hasSubkeys(); }
329
330     Iterable<SubkeyIterator> subkeys() const    ///!< \see \ref PublicKeyData
331     { return keyData().subkeys(); }
332
333     bool providesKey( const std::string & id_r ) const  ///!< \see \ref PublicKeyData
334     { return keyData().providesKey( id_r ); }
335
336   public:
337     typedef PublicKeyData::AsciiArt AsciiArt;   ///!< \see \ref PublicKeyData
338
339     AsciiArt asciiArt() const                   ///!< \see \ref PublicKeyData
340     { return keyData().asciiArt(); }
341
342   public:
343     /** File containig the ASCII armored key. */
344     Pathname path() const;
345
346     /** Additional keys data in case the ASCII armored blob containes multiple keys. */
347     const std::list<PublicKeyData> & hiddenKeys() const;
348
349   public:
350     bool operator==( const PublicKey & rhs ) const;
351     bool operator==( const std::string & sid ) const;
352
353   private:
354     friend class KeyRing;
355     /** KeyRing ctor: No need to parse file if KeyRing already had valid KeyData. */
356     PublicKey( const filesystem::TmpFile & sharedFile_r, const PublicKeyData & keyData_r );
357     /** KeyRing ctor: Legacy callback APIs take PublicKey, but just need the PublicKeyData No need to export to file. */
358     explicit PublicKey( const PublicKeyData & keyData_r );
359
360   private:
361     /** Pointer to implementation */
362     RWCOW_pointer<Impl> _pimpl;
363   };
364   ///////////////////////////////////////////////////////////////////
365
366   /** \relates PublicKey Stream output */
367   inline std::ostream & operator<<( std::ostream & str, const PublicKey & obj )
368   { return str << obj.asString(); }
369
370   /** \relates PublicKey Detailed stream output */
371   std::ostream & dumpOn( std::ostream & str, const PublicKey & obj );
372
373  /////////////////////////////////////////////////////////////////
374 } // namespace zypp
375 ///////////////////////////////////////////////////////////////////
376 #endif // ZYPP_PUBLICKEY_H