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