Line data Source code
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 354 : class GPGMEPP_EXPORT Key
55 : {
56 : friend class ::GpgME::Context;
57 : struct Null {
58 8 : 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 11 : const Key &operator=(Key other)
69 : {
70 11 : swap(other);
71 11 : return *this;
72 : }
73 :
74 : const Key &mergeWith(const Key &other);
75 :
76 18 : void swap(Key &other)
77 : {
78 : using std::swap;
79 18 : swap(this->key, other.key);
80 18 : }
81 :
82 25 : bool isNull() const
83 : {
84 25 : 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 34 : gpgme_key_t impl() const
168 : {
169 34 : return key.get();
170 : }
171 : shared_gpgme_key_t key;
172 : };
173 :
174 : //
175 : // class Subkey
176 : //
177 :
178 28 : 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 102 : 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 0 : const UserID &operator=(UserID other)
294 : {
295 0 : swap(other);
296 0 : return *this;
297 : }
298 :
299 0 : void swap(UserID &other)
300 : {
301 : using std::swap;
302 0 : swap(this->key, other.key);
303 0 : swap(this->uid, other.uid);
304 0 : }
305 :
306 0 : bool isNull() const
307 : {
308 0 : 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 0 : 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 0 : 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 0 : 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__
|