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