spelling: fix misspellings
[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     /*! Shorthand for isNull || isRevoked || isExpired ||
102      *                          isDisabled || isInvalid */
103     bool isBad() const;
104
105     bool canEncrypt() const;
106     /*!
107       This function contains a workaround for old gpgme's: all secret
108       OpenPGP keys canSign() == true, which canReallySign() doesn't
109       have. I don't have time to find what breaks when I remove this
110       workaround, but since Kleopatra merges secret into public keys,
111       the workaround is not necessary there (and actively harms), I've
112       added a new function instead.
113      */
114     bool canSign() const;
115     bool canReallySign() const;
116     bool canCertify() const;
117     bool canAuthenticate() const;
118     bool isQualified() const;
119     bool isDeVs() const;
120
121     bool hasSecret() const;
122     GPGMEPP_DEPRECATED bool isSecret() const
123     {
124         return hasSecret();
125     }
126
127     /*!
128       @return true if this is a X.509 root certificate (currently
129       equivalent to something like
130       strcmp( chainID(), subkey(0).fingerprint() ) == 0 )
131     */
132     bool isRoot() const;
133
134     enum OwnerTrust { Unknown = 0, Undefined = 1, Never = 2,
135                       Marginal = 3, Full = 4, Ultimate = 5
136                     };
137
138     OwnerTrust ownerTrust() const;
139     char ownerTrustAsString() const;
140
141     Protocol protocol() const;
142     const char *protocolAsString() const;
143
144     const char *issuerSerial() const;
145     const char *issuerName() const;
146     const char *chainID() const;
147
148     const char *keyID() const;
149     const char *shortKeyID() const;
150     const char *primaryFingerprint() const;
151
152     unsigned int keyListMode() const;
153
154     /*! Update information about this key.
155      * Starts a keylisting for this key with validity
156      * and tofu information gathering. Blocks for
157      * how long the keylisting takes.*/
158     void update();
159
160     /**
161      * @brief Add a user id to this key.
162      *
163      * Needs gnupg 2.1.13 and the key needs to be updated
164      * afterwards to see the new uid.
165      *
166      * @param uid should be fully formatted and UTF-8 encoded.
167      *
168      * @returns a possible error.
169      **/
170     Error addUid(const char *uid);
171
172     /**
173      * @brief try to locate the best pgp key for a given mailbox.
174      *
175      * Boils down to gpg --locate-key <mbox>
176      * This may take some time if remote sources are also
177      * used.
178      *
179      * @param mbox should be a mail address does not need to be normalized.
180      *
181      * @returns The best key for a mailbox or a null key.
182      */
183     static Key locate(const char *mbox);
184
185     /* @enum Origin
186      * @brief The Origin of the key. */
187     enum Origin : unsigned int {
188         OriginUnknown = 0,
189         OriginKS = 1,
190         OriginDane = 3,
191         OriginWKD = 4,
192         OriginURL = 5,
193         OriginFile = 6,
194         OriginSelf = 7,
195         OriginOther = 31,
196     };
197     /*! Get the origin of the key.
198      *
199      * @returns the Origin. */
200     Origin origin() const;
201
202     /*! Get the last update time.
203      *
204      * @returns the last update time. */
205     time_t lastUpdate() const;
206 private:
207     gpgme_key_t impl() const
208     {
209         return key.get();
210     }
211     shared_gpgme_key_t key;
212 };
213
214 //
215 // class Subkey
216 //
217
218 class GPGMEPP_EXPORT Subkey
219 {
220 public:
221     Subkey();
222     Subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey);
223     Subkey(const shared_gpgme_key_t &key, unsigned int idx);
224
225     const Subkey &operator=(Subkey other)
226     {
227         swap(other);
228         return *this;
229     }
230
231     void swap(Subkey &other)
232     {
233         using std::swap;
234         swap(this->key, other.key);
235         swap(this->subkey, other.subkey);
236     }
237
238     bool isNull() const
239     {
240         return !key || !subkey;
241     }
242
243     Key parent() const;
244
245     const char *keyID() const;
246     const char *fingerprint() const;
247
248     time_t creationTime() const;
249     time_t expirationTime() const;
250     bool neverExpires() const;
251
252     bool isRevoked() const;
253     bool isExpired() const;
254     bool isInvalid() const;
255     bool isDisabled() const;
256
257     /*! Shorthand for isNull || isRevoked || isExpired ||
258      *                          isDisabled || isInvalid */
259     bool isBad() const;
260
261     bool canEncrypt() const;
262     bool canSign() const;
263     bool canCertify() const;
264     bool canAuthenticate() const;
265     bool isQualified() const;
266     bool isDeVs() const;
267     bool isCardKey() const;
268
269     bool isSecret() const;
270
271     /** Same as gpgme_pubkey_algo_t */
272     enum PubkeyAlgo {
273         AlgoUnknown = 0,
274         AlgoRSA     = 1,
275         AlgoRSA_E   = 2,
276         AlgoRSA_S   = 3,
277         AlgoELG_E   = 16,
278         AlgoDSA     = 17,
279         AlgoECC     = 18,
280         AlgoELG     = 20,
281         AlgoECDSA   = 301,
282         AlgoECDH    = 302,
283         AlgoEDDSA   = 303,
284         AlgoMax     = 1 << 31
285     };
286
287     PubkeyAlgo publicKeyAlgorithm() const;
288
289     /**
290       @brief Get the public key algorithm name.
291
292       This only works for the pre 2.1 algorithms for ECC NULL is returned.
293
294       @returns a statically allocated string with the name of the public
295                key algorithm, or NULL if that name is not known.
296     */
297     const char *publicKeyAlgorithmAsString() const;
298
299     /** @brief Same as publicKeyAlgorithmAsString but static. */
300     static const char *publicKeyAlgorithmAsString(PubkeyAlgo algo);
301
302     /**
303        @brief Get the key algo string like GnuPG 2.1 prints it.
304
305        This returns combinations of size and algorithm. Like
306        bp512 or rsa2048. Misnamed because publicKeyAlgorithmAsString
307        already used the older pubkey_algo_name.
308        Actually uses gpgme_pubkey_algo_string.
309
310        @returns the key algorithm as string. Empty string on error.
311     */
312     std::string algoName() const;
313
314     unsigned int length() const;
315
316     const char *cardSerialNumber() const;
317
318     const char *keyGrip() const;
319
320 private:
321     shared_gpgme_key_t key;
322     gpgme_sub_key_t subkey;
323 };
324
325 //
326 // class UserID
327 //
328
329 class GPGMEPP_EXPORT UserID
330 {
331 public:
332     class Signature;
333
334     UserID();
335     UserID(const shared_gpgme_key_t &key, gpgme_user_id_t uid);
336     UserID(const shared_gpgme_key_t &key, unsigned int idx);
337
338     const UserID &operator=(UserID other)
339     {
340         swap(other);
341         return *this;
342     }
343
344     void swap(UserID &other)
345     {
346         using std::swap;
347         swap(this->key, other.key);
348         swap(this->uid, other.uid);
349     }
350
351     bool isNull() const
352     {
353         return !key || !uid;
354     }
355
356     Key parent() const;
357
358     unsigned int numSignatures() const;
359     Signature signature(unsigned int index) const;
360     std::vector<Signature> signatures() const;
361
362     const char *id() const;
363     const char *name() const;
364     const char *email() const;
365     const char *comment() const;
366
367     enum Validity { Unknown = 0, Undefined = 1, Never = 2,
368                     Marginal = 3, Full = 4, Ultimate = 5
369                   };
370
371     Validity validity() const;
372     char validityAsString() const;
373
374     bool isRevoked() const;
375     bool isInvalid() const;
376
377     /*! Shorthand for isNull || isRevoked || isInvalid */
378     bool isBad() const;
379
380     /** TOFU info for this userid.
381      * @returns The TOFU stats or a null TofuInfo.
382      */
383     GpgME::TofuInfo tofuInfo() const;
384
385     /*! Wrapper around gpgme_addrspec_from_uid.
386      *
387      * The input string should match the format of
388      * a user id string.
389      *
390      * @returns a normalized mail address if found
391      * or an empty string. */
392     static std::string addrSpecFromString(const char *uid);
393
394     /*! Wrapper around gpgme_addrspec_from_uid.
395      *
396      * @returns a normalized mail address for this userid
397      * or an empty string. */
398     std::string addrSpec() const;
399
400     /*! Revoke the user id.
401      *
402      * Key needs update afterwards.
403      *
404      * @returns an error on error.*/
405     Error revoke();
406
407     /*! Get the origin of the key.
408      *
409      * @returns the Origin. */
410     Key::Origin origin() const;
411
412     /*! Get the last update time.
413      *
414      * @returns the last update time. */
415     time_t lastUpdate() const;
416 private:
417     shared_gpgme_key_t key;
418     gpgme_user_id_t uid;
419 };
420
421 //
422 // class UserID::Signature
423 //
424
425 class GPGMEPP_EXPORT UserID::Signature
426 {
427 public:
428     typedef GPGMEPP_DEPRECATED GpgME::Notation Notation;
429
430     Signature();
431     Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, gpgme_key_sig_t sig);
432     Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, unsigned int idx);
433
434     const Signature &operator=(Signature other)
435     {
436         swap(other);
437         return *this;
438     }
439
440     void swap(Signature &other)
441     {
442         using std::swap;
443         swap(this->key, other.key);
444         swap(this->uid, other.uid);
445         swap(this->sig, other.sig);
446     }
447
448     bool isNull() const
449     {
450         return !sig || !uid || !key ;
451     }
452
453     UserID parent() const;
454
455     const char *signerKeyID() const;
456
457     const char *algorithmAsString() const;
458     unsigned int algorithm() const;
459     time_t creationTime() const;
460     time_t expirationTime() const;
461     bool neverExpires() const;
462
463     bool isRevokation() const;
464     bool isInvalid() const;
465     bool isExpired() const;
466     bool isExportable() const;
467
468     /*! Shorthand for isNull || isExpired || isInvalid */
469     bool isBad() const;
470
471     const char *signerUserID() const;
472     const char *signerName() const;
473     const char *signerEmail() const;
474     const char *signerComment() const;
475
476     unsigned int certClass() const;
477
478     enum Status { NoError = 0, SigExpired, KeyExpired,
479                   BadSignature, NoPublicKey, GeneralError
480                 };
481     Status status() const;
482     std::string statusAsString() const;
483
484     const char *policyURL() const;
485
486     unsigned int numNotations() const;
487     GpgME::Notation notation(unsigned int idx) const;
488     std::vector<GpgME::Notation> notations() const;
489
490 private:
491     shared_gpgme_key_t key;
492     gpgme_user_id_t uid;
493     gpgme_key_sig_t sig;
494 };
495
496 GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const UserID &uid);
497 GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Key &key);
498
499 } // namespace GpgME
500
501 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Key)
502 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Subkey)
503 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(UserID)
504 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(UserID::Signature)
505
506 GPGMEPP_MAKE_STRCMP(ByFingerprint, .primaryFingerprint());
507 GPGMEPP_MAKE_STRCMP(ByKeyID, .keyID());
508 GPGMEPP_MAKE_STRCMP(ByShortKeyID, .shortKeyID());
509 GPGMEPP_MAKE_STRCMP(ByChainID, .chainID());
510
511 #endif // __GPGMEPP_KEY_H__