f193093c025ca3ab8aa96a980b14a4fea0722ad0
[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 private:
324     shared_gpgme_key_t key;
325     gpgme_user_id_t uid;
326 };
327
328 //
329 // class UserID::Signature
330 //
331
332 class GPGMEPP_EXPORT UserID::Signature
333 {
334 public:
335     typedef GPGMEPP_DEPRECATED GpgME::Notation Notation;
336
337     Signature();
338     Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, gpgme_key_sig_t sig);
339     Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, unsigned int idx);
340
341     const Signature &operator=(Signature other)
342     {
343         swap(other);
344         return *this;
345     }
346
347     void swap(Signature &other)
348     {
349         using std::swap;
350         swap(this->key, other.key);
351         swap(this->uid, other.uid);
352         swap(this->sig, other.sig);
353     }
354
355     bool isNull() const
356     {
357         return !sig || !uid || !key ;
358     }
359
360     UserID parent() const;
361
362     const char *signerKeyID() const;
363
364     const char *algorithmAsString() const;
365     unsigned int algorithm() const;
366     time_t creationTime() const;
367     time_t expirationTime() const;
368     bool neverExpires() const;
369
370     bool isRevokation() const;
371     bool isInvalid() const;
372     bool isExpired() const;
373     bool isExportable() const;
374
375     const char *signerUserID() const;
376     const char *signerName() const;
377     const char *signerEmail() const;
378     const char *signerComment() const;
379
380     unsigned int certClass() const;
381
382     enum Status { NoError = 0, SigExpired, KeyExpired,
383                   BadSignature, NoPublicKey, GeneralError
384                 };
385     Status status() const;
386     std::string statusAsString() const;
387
388     const char *policyURL() const;
389
390     unsigned int numNotations() const;
391     GpgME::Notation notation(unsigned int idx) const;
392     std::vector<GpgME::Notation> notations() const;
393
394 private:
395     shared_gpgme_key_t key;
396     gpgme_user_id_t uid;
397     gpgme_key_sig_t sig;
398 };
399
400 GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const UserID &uid);
401 GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Key &key);
402
403 } // namespace GpgME
404
405 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Key)
406 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Subkey)
407 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(UserID)
408 GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(UserID::Signature)
409
410 GPGMEPP_MAKE_STRCMP(ByFingerprint, .primaryFingerprint());
411 GPGMEPP_MAKE_STRCMP(ByKeyID, .keyID());
412 GPGMEPP_MAKE_STRCMP(ByShortKeyID, .shortKeyID());
413 GPGMEPP_MAKE_STRCMP(ByChainID, .chainID());
414
415 #endif // __GPGMEPP_KEY_H__