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