cpp: Add ostream operators for key and uid
[gpgme.git] / lang / cpp / src / key.h
1 /*
2   key.h - wraps a gpgme key
3   Copyright (C) 2003, 2005 Klarälvdalens Datakonsult AB
4
5   This file is part of GPGME++.
6
7   GPGME++ is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Library General Public
9   License as published by the Free Software Foundation; either
10   version 2 of the License, or (at your option) any later version.
11
12   GPGME++ is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU Library General Public License for more details.
16
17   You should have received a copy of the GNU Library General Public License
18   along with GPGME++; see the file COPYING.LIB.  If not, write to the
19   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20   Boston, MA 02110-1301, USA.
21 */
22
23 // -*- c++ -*-
24 #ifndef __GPGMEPP_KEY_H__
25 #define __GPGMEPP_KEY_H__
26
27 #include "global.h"
28 #include "notation.h"
29
30 #include "gpgmefw.h"
31
32 #include <memory>
33 #include <sys/time.h>
34
35 #include <vector>
36 #include <algorithm>
37 #include <string>
38
39 namespace GpgME
40 {
41
42 class Context;
43
44 class Subkey;
45 class UserID;
46 class TofuInfo;
47
48 typedef std::shared_ptr< std::remove_pointer<gpgme_key_t>::type > shared_gpgme_key_t;
49
50 //
51 // class Key
52 //
53
54 class GPGMEPP_EXPORT Key
55 {
56     friend class ::GpgME::Context;
57     struct Null {
58                 Null() {}
59         };
60 public:
61     Key();
62     /* implicit */ Key(const Null &);
63     Key(const shared_gpgme_key_t &key);
64     Key(gpgme_key_t key, bool acquireRef);
65
66     static const Null null;
67
68     const Key &operator=(Key other)
69     {
70         swap(other);
71         return *this;
72     }
73
74     const Key &mergeWith(const Key &other);
75
76     void swap(Key &other)
77     {
78         using std::swap;
79         swap(this->key, other.key);
80     }
81
82     bool isNull() const
83     {
84         return !key;
85     }
86
87     UserID userID(unsigned int index) const;
88     Subkey subkey(unsigned int index) const;
89
90     unsigned int numUserIDs() const;
91     unsigned int numSubkeys() const;
92
93     std::vector<UserID> userIDs() const;
94     std::vector<Subkey> subkeys() const;
95
96     bool isRevoked() const;
97     bool isExpired() const;
98     bool isDisabled() const;
99     bool isInvalid() const;
100
101     bool canEncrypt() const;
102     /*!
103       This function contains a workaround for old gpgme's: all secret
104       OpenPGP keys canSign() == true, which canReallySign() doesn't
105       have. I don't have time to find what breaks when I remove this
106       workaround, but since Kleopatra merges secret into public keys,
107       the workaround is not necessary there (and actively harms), I've
108       added a new function instead.
109      */
110     bool canSign() const;
111     bool canReallySign() const;
112     bool canCertify() const;
113     bool canAuthenticate() const;
114     bool isQualified() const;
115
116     bool hasSecret() const;
117     GPGMEPP_DEPRECATED bool isSecret() const
118     {
119         return hasSecret();
120     }
121
122     /*!
123       @return true if this is a X.509 root certificate (currently
124       equivalent to something like
125       strcmp( chainID(), subkey(0).fingerprint() ) == 0 )
126     */
127     bool isRoot() const;
128
129     enum OwnerTrust { Unknown = 0, Undefined = 1, Never = 2,
130                       Marginal = 3, Full = 4, Ultimate = 5
131                     };
132
133     OwnerTrust ownerTrust() const;
134     char ownerTrustAsString() const;
135
136     Protocol protocol() const;
137     const char *protocolAsString() const;
138
139     const char *issuerSerial() const;
140     const char *issuerName() const;
141     const char *chainID() const;
142
143     const char *keyID() const;
144     const char *shortKeyID() const;
145     const char *primaryFingerprint() const;
146
147     unsigned int keyListMode() const;
148
149 private:
150     gpgme_key_t impl() const
151     {
152         return key.get();
153     }
154     shared_gpgme_key_t key;
155 };
156
157 //
158 // class Subkey
159 //
160
161 class GPGMEPP_EXPORT Subkey
162 {
163 public:
164     Subkey();
165     Subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey);
166     Subkey(const shared_gpgme_key_t &key, unsigned int idx);
167
168     const Subkey &operator=(Subkey other)
169     {
170         swap(other);
171         return *this;
172     }
173
174     void swap(Subkey &other)
175     {
176         using std::swap;
177         swap(this->key, other.key);
178         swap(this->subkey, other.subkey);
179     }
180
181     bool isNull() const
182     {
183         return !key || !subkey;
184     }
185
186     Key parent() const;
187
188     const char *keyID() const;
189     const char *fingerprint() const;
190
191     time_t creationTime() const;
192     time_t expirationTime() const;
193     bool neverExpires() const;
194
195     bool isRevoked() const;
196     bool isExpired() const;
197     bool isInvalid() const;
198     bool isDisabled() const;
199
200     bool canEncrypt() const;
201     bool canSign() const;
202     bool canCertify() const;
203     bool canAuthenticate() const;
204     bool isQualified() const;
205     bool isCardKey() const;
206
207     bool isSecret() const;
208
209     /** Same as gpgme_pubkey_algo_t */
210     enum PubkeyAlgo {
211         AlgoUnknown = 0,
212         AlgoRSA     = 1,
213         AlgoRSA_E   = 2,
214         AlgoRSA_S   = 3,
215         AlgoELG_E   = 16,
216         AlgoDSA     = 17,
217         AlgoECC     = 18,
218         AlgoELG     = 20,
219         AlgoECDSA   = 301,
220         AlgoECDH    = 302,
221         AlgoEDDSA   = 303,
222         AlgoMax     = 1 << 31
223     };
224
225     PubkeyAlgo publicKeyAlgorithm() const;
226
227     /**
228       @brief Get the public key algorithm name.
229
230       This only works for the pre 2.1 algorithms for ECC NULL is returned.
231
232       @returns a statically allocated string with the name of the public
233                key algorithm, or NULL if that name is not known.
234     */
235     const char *publicKeyAlgorithmAsString() const;
236
237     /** @brief Same as publicKeyAlgorithmAsString but static. */
238     static const char *publicKeyAlgorithmAsString(PubkeyAlgo algo);
239
240     /**
241        @brief Get the key algo string like GnuPG 2.1 prints it.
242
243        This returns combinations of size and algorithm. Like
244        bp512 or rsa2048. Misnamed because publicKeyAlgorithmAsString
245        already used the older pubkey_algo_name.
246        Actually uses gpgme_pubkey_algo_string.
247
248        @returns the key algorithm as string. Empty string on error.
249     */
250     std::string algoName() const;
251
252     unsigned int length() const;
253
254     const char *cardSerialNumber() const;
255
256 private:
257     shared_gpgme_key_t key;
258     gpgme_sub_key_t subkey;
259 };
260
261 //
262 // class UserID
263 //
264
265 class GPGMEPP_EXPORT UserID
266 {
267 public:
268     class Signature;
269
270     UserID();
271     UserID(const shared_gpgme_key_t &key, gpgme_user_id_t uid);
272     UserID(const shared_gpgme_key_t &key, unsigned int idx);
273
274     const UserID &operator=(UserID other)
275     {
276         swap(other);
277         return *this;
278     }
279
280     void swap(UserID &other)
281     {
282         using std::swap;
283         swap(this->key, other.key);
284         swap(this->uid, other.uid);
285     }
286
287     bool isNull() const
288     {
289         return !key || !uid;
290     }
291
292     Key parent() const;
293
294     unsigned int numSignatures() const;
295     Signature signature(unsigned int index) const;
296     std::vector<Signature> signatures() const;
297
298     const char *id() const;
299     const char *name() const;
300     const char *email() const;
301     const char *comment() const;
302
303     enum Validity { Unknown = 0, Undefined = 1, Never = 2,
304                     Marginal = 3, Full = 4, Ultimate = 5
305                   };
306
307     Validity validity() const;
308     char validityAsString() const;
309
310     bool isRevoked() const;
311     bool isInvalid() const;
312
313     /** TOFU info for this userid.
314      * @returns The TOFU stats or a null TofuInfo.
315      */
316     GpgME::TofuInfo tofuInfo() const;
317 private:
318     shared_gpgme_key_t key;
319     gpgme_user_id_t uid;
320 };
321
322 //
323 // class UserID::Signature
324 //
325
326 class GPGMEPP_EXPORT UserID::Signature
327 {
328 public:
329     typedef GPGMEPP_DEPRECATED GpgME::Notation Notation;
330
331     Signature();
332     Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, gpgme_key_sig_t sig);
333     Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, unsigned int idx);
334
335     const Signature &operator=(Signature other)
336     {
337         swap(other);
338         return *this;
339     }
340
341     void swap(Signature &other)
342     {
343         using std::swap;
344         swap(this->key, other.key);
345         swap(this->uid, other.uid);
346         swap(this->sig, other.sig);
347     }
348
349     bool isNull() const
350     {
351         return !sig || !uid || !key ;
352     }
353
354     UserID parent() const;
355
356     const char *signerKeyID() const;
357
358     const char *algorithmAsString() const;
359     unsigned int algorithm() const;
360     time_t creationTime() const;
361     time_t expirationTime() const;
362     bool neverExpires() const;
363
364     bool isRevokation() const;
365     bool isInvalid() const;
366     bool isExpired() const;
367     bool isExportable() const;
368
369     const char *signerUserID() const;
370     const char *signerName() const;
371     const char *signerEmail() const;
372     const char *signerComment() const;
373
374     unsigned int certClass() const;
375
376     enum Status { NoError = 0, SigExpired, KeyExpired,
377                   BadSignature, NoPublicKey, GeneralError
378                 };
379     Status status() const;
380     std::string statusAsString() const;
381
382     const char *policyURL() const;
383
384     unsigned int numNotations() const;
385     GpgME::Notation notation(unsigned int idx) const;
386     std::vector<GpgME::Notation> notations() const;
387
388 private:
389     shared_gpgme_key_t key;
390     gpgme_user_id_t uid;
391     gpgme_key_sig_t sig;
392 };
393
394 GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const UserID &uid);
395 GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Key &key);
396
397 } // namespace GpgME
398
399 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Key)
400 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Subkey)
401 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(UserID)
402 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(UserID::Signature)
403
404 GPGMEPP_MAKE_STRCMP(ByFingerprint, .primaryFingerprint());
405 GPGMEPP_MAKE_STRCMP(ByKeyID, .keyID());
406 GPGMEPP_MAKE_STRCMP(ByShortKeyID, .shortKeyID());
407 GPGMEPP_MAKE_STRCMP(ByChainID, .chainID());
408
409 #endif // __GPGMEPP_KEY_H__