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