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 336 : class GPGMEPP_EXPORT Key
55 : {
56 : friend class ::GpgME::Context;
57 : struct Null {
58 6 : 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 16 : void swap(Key &other)
77 : {
78 : using std::swap;
79 16 : swap(this->key, other.key);
80 16 : }
81 :
82 18 : bool isNull() const
83 : {
84 18 : 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 32 : gpgme_key_t impl() const
157 : {
158 32 : return key.get();
159 : }
160 : shared_gpgme_key_t key;
161 : };
162 :
163 : //
164 : // class Subkey
165 : //
166 :
167 28 : 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 78 : 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 0 : const UserID &operator=(UserID other)
281 : {
282 0 : swap(other);
283 0 : return *this;
284 : }
285 :
286 0 : void swap(UserID &other)
287 : {
288 : using std::swap;
289 0 : swap(this->key, other.key);
290 0 : swap(this->uid, other.uid);
291 0 : }
292 :
293 0 : bool isNull() const
294 : {
295 0 : 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 0 : 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 0 : 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 0 : 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__
|