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