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