1 /*
2 SPDX-FileCopyrightText: 2006, 2007 Jimmy Gilles <jimmygilles@gmail.com>
3 SPDX-FileCopyrightText: 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2017 Rolf Eike Beer <kde@opensource.sf-tec.de>
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "kgpgkey.h"
8
9 #include "convert.h"
10
11 #include <QStringList>
12
13 namespace KgpgCore
14 {
15
_describe_key_strength(KgpgKeyAlgo algorithm,const uint size,const QString & curve)16 static QString _describe_key_strength(KgpgKeyAlgo algorithm, const uint size, const QString &curve)
17 {
18 if (!curve.isEmpty())
19 return curve;
20
21 QString prefix;
22
23 switch(algorithm)
24 {
25 case ALGO_RSA: prefix = QStringLiteral("rsa"); break;
26 case ALGO_ELGAMAL: prefix = QStringLiteral("elg"); break;
27 case ALGO_DSA: prefix = QStringLiteral("dsa"); break;
28 }
29
30 return prefix + QString::number(size);
31 }
32
33 //BEGIN KeySub
KgpgKeySubPrivate(const QString & id,const uint size,const KgpgKeyTrust trust,const KgpgKeyAlgo algo,const KgpgSubKeyType type,const QDateTime & date,const QString & curve)34 KgpgKeySubPrivate::KgpgKeySubPrivate(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo,
35 const KgpgSubKeyType type, const QDateTime &date, const QString &curve)
36 : gpgsubvalid(false),
37 gpgsubid(id),
38 gpgsubsize(size),
39 gpgsubcreation(date),
40 gpgsubtrust(trust),
41 gpgsubalgo(algo),
42 gpgsubtype(type),
43 gpgcurve(curve)
44 {
45 }
46
operator ==(const KgpgKeySubPrivate & other) const47 bool KgpgKeySubPrivate::operator==(const KgpgKeySubPrivate &other) const
48 {
49 if (gpgsubvalid != other.gpgsubvalid) return false;
50 if (gpgsubalgo != other.gpgsubalgo) return false;
51 if (gpgsubid != other.gpgsubid) return false;
52 if (gpgsubsize != other.gpgsubsize) return false;
53 if (gpgsubexpiration != other.gpgsubexpiration) return false;
54 if (gpgsubcreation != other.gpgsubcreation) return false;
55 if (gpgsubtrust != other.gpgsubtrust) return false;
56 if (gpgsubtype != other.gpgsubtype) return false;
57 return true;
58 }
59
KgpgKeySub(const QString & id,const uint size,const KgpgKeyTrust trust,const KgpgKeyAlgo algo,const KgpgSubKeyType type,const QDateTime & date,const QString & curve)60 KgpgKeySub::KgpgKeySub(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo, const KgpgSubKeyType type,
61 const QDateTime &date, const QString &curve)
62 : d(new KgpgKeySubPrivate(id, size, trust, algo, type, date, curve))
63 {
64 }
65
KgpgKeySub(const KgpgKeySub & other)66 KgpgKeySub::KgpgKeySub(const KgpgKeySub &other)
67 {
68 d = other.d;
69 }
70
setExpiration(const QDateTime & date)71 void KgpgKeySub::setExpiration(const QDateTime &date)
72 {
73 d->gpgsubexpiration = date;
74 }
75
setValid(const bool valid)76 void KgpgKeySub::setValid(const bool valid)
77 {
78 d->gpgsubvalid = valid;
79 }
80
id() const81 QString KgpgKeySub::id() const
82 {
83 return d->gpgsubid;
84 }
85
size() const86 uint KgpgKeySub::size() const
87 {
88 return d->gpgsubsize;
89 }
90
strength() const91 QString KgpgKeySub::strength() const
92 {
93 return _describe_key_strength(algorithm(), size(), d->gpgcurve);
94 }
95
unlimited() const96 bool KgpgKeySub::unlimited() const
97 {
98 return d->gpgsubexpiration.isNull();
99 }
100
expirationDate() const101 QDateTime KgpgKeySub::expirationDate() const
102 {
103 return d->gpgsubexpiration;
104 }
105
creationDate() const106 QDateTime KgpgKeySub::creationDate() const
107 {
108 return d->gpgsubcreation;
109 }
110
trust() const111 KgpgKeyTrust KgpgKeySub::trust() const
112 {
113 return d->gpgsubtrust;
114 }
115
algorithm() const116 KgpgKeyAlgo KgpgKeySub::algorithm() const
117 {
118 return d->gpgsubalgo;
119 }
120
valid() const121 bool KgpgKeySub::valid() const
122 {
123 return d->gpgsubvalid;
124 }
125
type() const126 KgpgSubKeyType KgpgKeySub::type() const
127 {
128 return d->gpgsubtype;
129 }
130
curve() const131 QString KgpgKeySub::curve() const
132 {
133 return d->gpgcurve;
134 }
135
operator ==(const KgpgKeySub & other) const136 bool KgpgKeySub::operator==(const KgpgKeySub &other) const
137 {
138 if (d == other.d) return true;
139 if ((*d) == (*(other.d))) return true;
140 return false;
141 }
142
operator =(const KgpgKeySub & other)143 KgpgKeySub& KgpgKeySub::operator=(const KgpgKeySub &other)
144 {
145 d = other.d;
146 return *this;
147 }
148
149 //END KeySub
150
151
152 //BEGIN Key
153
KgpgKeyPrivate(const QString & id,const uint size,const KgpgKeyTrust trust,const KgpgKeyAlgo algo,const KgpgSubKeyType subtype,const KgpgSubKeyType keytype,const QDateTime & creationDate,const QString & curve)154 KgpgKeyPrivate::KgpgKeyPrivate(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo, const KgpgSubKeyType subtype,
155 const KgpgSubKeyType keytype, const QDateTime &creationDate, const QString &curve)
156 : gpgkeysecret(false),
157 gpgkeyvalid(false),
158 gpgkeyid(id),
159 gpgkeysize(size),
160 gpgkeytrust(trust),
161 gpgkeycreation(creationDate),
162 gpgkeyalgo(algo),
163 gpgsubtype(subtype),
164 gpgkeytype(keytype),
165 gpgcurve(curve),
166 gpgsublist(new KgpgKeySubList())
167 {
168 }
169
operator ==(const KgpgKeyPrivate & other) const170 bool KgpgKeyPrivate::operator==(const KgpgKeyPrivate &other) const
171 {
172 if (gpgkeysecret != other.gpgkeysecret) return false;
173 if (gpgkeyvalid != other.gpgkeyvalid) return false;
174 if (gpgkeymail != other.gpgkeymail) return false;
175 if (gpgkeyname != other.gpgkeyname) return false;
176 if (gpgkeycomment != other.gpgkeycomment) return false;
177 if (gpgkeyfingerprint != other.gpgkeyfingerprint) return false;
178 if (gpgkeyid != other.gpgkeyid) return false;
179 if (gpgkeysize != other.gpgkeysize) return false;
180 if (gpgkeyownertrust != other.gpgkeyownertrust) return false;
181 if (gpgkeytrust != other.gpgkeytrust) return false;
182 if (gpgkeycreation != other.gpgkeycreation) return false;
183 if (gpgkeyexpiration != other.gpgkeyexpiration) return false;
184 if (gpgkeyalgo != other.gpgkeyalgo) return false;
185 if (gpgsubtype != other.gpgsubtype) return false;
186 if (gpgkeytype != other.gpgkeytype) return false;
187 if (gpgsublist != other.gpgsublist) return false;
188 return true;
189 }
190
KgpgKey(const QString & id,const uint size,const KgpgKeyTrust trust,const KgpgKeyAlgo algo,const KgpgSubKeyType subtype,const KgpgSubKeyType keytype,const QDateTime & creationDate,const QString & curve)191 KgpgKey::KgpgKey(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo, const KgpgSubKeyType subtype,
192 const KgpgSubKeyType keytype, const QDateTime &creationDate, const QString &curve)
193 : d(new KgpgKeyPrivate(id, size, trust, algo, subtype, keytype, creationDate, curve))
194 {
195 }
196
KgpgKey(const KgpgKey & other)197 KgpgKey::KgpgKey(const KgpgKey &other)
198 {
199 d = other.d;
200 }
201
setSecret(const bool secret)202 void KgpgKey::setSecret(const bool secret)
203 {
204 d->gpgkeysecret = secret;
205 }
206
setValid(const bool valid)207 void KgpgKey::setValid(const bool valid)
208 {
209 d->gpgkeyvalid = valid;
210 }
211
setName(const QString & name)212 void KgpgKey::setName(const QString &name)
213 {
214 d->gpgkeyname = name;
215 }
216
setEmail(const QString & email)217 void KgpgKey::setEmail(const QString &email)
218 {
219 d->gpgkeymail = email;
220 }
221
setComment(const QString & comment)222 void KgpgKey::setComment(const QString &comment)
223 {
224 d->gpgkeycomment = comment;
225 }
226
setFingerprint(const QString & fingerprint)227 void KgpgKey::setFingerprint(const QString &fingerprint)
228 {
229 d->gpgkeyfingerprint = fingerprint;
230 }
231
setOwnerTrust(const gpgme_validity_t owtrust)232 void KgpgKey::setOwnerTrust(const gpgme_validity_t owtrust)
233 {
234 d->gpgkeyownertrust = owtrust;
235 }
236
setExpiration(const QDateTime & date)237 void KgpgKey::setExpiration(const QDateTime &date)
238 {
239 d->gpgkeyexpiration = date;
240 }
241
secret() const242 bool KgpgKey::secret() const
243 {
244 return d->gpgkeysecret;
245 }
246
valid() const247 bool KgpgKey::valid() const
248 {
249 return d->gpgkeyvalid;
250 }
251
id() const252 QString KgpgKey::id() const
253 {
254 return d->gpgkeyid.right(8);
255 }
256
fullId() const257 QString KgpgKey::fullId() const
258 {
259 return d->gpgkeyid;
260 }
261
name() const262 QString KgpgKey::name() const
263 {
264 return d->gpgkeyname;
265 }
266
email() const267 QString KgpgKey::email() const
268 {
269 return d->gpgkeymail;
270 }
271
comment() const272 QString KgpgKey::comment() const
273 {
274 return d->gpgkeycomment;
275 }
276
fingerprint() const277 const QString &KgpgKey::fingerprint() const
278 {
279 return d->gpgkeyfingerprint;
280 }
281
size() const282 uint KgpgKey::size() const
283 {
284 return d->gpgkeysize;
285 }
286
strength() const287 QString KgpgKey::strength() const
288 {
289 return _describe_key_strength(algorithm(), size(), d->gpgcurve);
290 }
291
292 /**
293 * @brief find the "best" encryption key
294 *
295 * The "best" is the first one that is not expired, or simply the
296 * first one.
297 */
298 static const KgpgKeySub *
bestEncryptionKey(const KgpgKeySubList & list)299 bestEncryptionKey(const KgpgKeySubList &list)
300 {
301 const KgpgKeySub *enc = nullptr;
302 // Get the first encryption subkey
303 for (const KgpgKeySub &k : list) {
304 if (k.type() & SKT_ENCRYPTION) {
305 // if the first encryption subkey is expired
306 // check if there is one that is not
307 if (k.trust() > TRUST_EXPIRED)
308 return &k;
309 if (enc == nullptr)
310 enc = &k;
311 }
312 }
313
314 return enc;
315 }
316
encryptionSize() const317 uint KgpgKey::encryptionSize() const
318 {
319 const KgpgKeySub *enc = bestEncryptionKey(*d->gpgsublist);
320 if (enc != nullptr)
321 return enc->size();
322 return 0;
323 }
324
encryptionStrength() const325 QString KgpgKey::encryptionStrength() const
326 {
327 const KgpgKeySub *enc = bestEncryptionKey(*d->gpgsublist);
328 if (enc != nullptr)
329 return _describe_key_strength(enc->algorithm(), enc->size(), enc->curve());
330 return QString();
331 }
332
ownerTrust() const333 gpgme_validity_t KgpgKey::ownerTrust() const
334 {
335 return d->gpgkeyownertrust;
336 }
337
trust() const338 KgpgKeyTrust KgpgKey::trust() const
339 {
340 return d->gpgkeytrust;
341 }
342
creationDate() const343 QDateTime KgpgKey::creationDate() const
344 {
345 return d->gpgkeycreation;
346 }
347
expirationDate() const348 QDateTime KgpgKey::expirationDate() const
349 {
350 return d->gpgkeyexpiration;
351 }
352
unlimited() const353 bool KgpgKey::unlimited() const
354 {
355 return d->gpgkeyexpiration.isNull();
356 }
357
algorithm() const358 KgpgKeyAlgo KgpgKey::algorithm() const
359 {
360 return d->gpgkeyalgo;
361 }
362
encryptionAlgorithm() const363 KgpgKeyAlgo KgpgKey::encryptionAlgorithm() const
364 {
365 // Get the first encryption subkey
366 for (const KgpgKeySub &k : qAsConst(*d->gpgsublist))
367 if (k.type() & SKT_ENCRYPTION)
368 return k.algorithm();
369
370 return ALGO_UNKNOWN;
371 }
372
subtype() const373 KgpgSubKeyType KgpgKey::subtype() const
374 {
375 return d->gpgsubtype;
376 }
377
keytype() const378 KgpgSubKeyType KgpgKey::keytype() const
379 {
380 return d->gpgkeytype;
381 }
382
curve() const383 QString KgpgKey::curve() const
384 {
385 return d->gpgcurve;
386 }
387
subList() const388 KgpgKeySubListPtr KgpgKey::subList() const
389 {
390 return d->gpgsublist;
391 }
392
operator ==(const KgpgKey & other) const393 bool KgpgKey::operator==(const KgpgKey &other) const
394 {
395 if (d == other.d) return true;
396 if ((*d) == (*(other.d))) return true;
397 return false;
398 }
399
operator =(const KgpgKey & other)400 KgpgKey& KgpgKey::operator=(const KgpgKey &other)
401 {
402 d = other.d;
403 return *this;
404 }
405
operator QStringList() const406 KgpgKeyList::operator QStringList() const
407 {
408 QStringList res;
409 res.reserve(count());
410
411 for (const KgpgKey &key : *this)
412 res << key.fullId();
413
414 return res;
415 }
416
417 //END Key
418
419 } // namespace KgpgCore
420