File indexing completed on 2024-04-21 05:50:36

0001 /*
0002     SPDX-FileCopyrightText: 2006, 2007 Jimmy Gilles <jimmygilles@gmail.com>
0003     SPDX-FileCopyrightText: 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2017 Rolf Eike Beer <kde@opensource.sf-tec.de>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kgpgkey.h"
0008 
0009 #include "convert.h"
0010 
0011 
0012 namespace KgpgCore
0013 {
0014 
0015 static QString _describe_key_strength(KgpgKeyAlgo algorithm, const uint size, const QString &curve)
0016 {
0017     if (!curve.isEmpty())
0018         return curve;
0019 
0020     QString prefix;
0021 
0022     switch(algorithm)
0023     {
0024     case ALGO_RSA: prefix = QStringLiteral("rsa"); break;
0025     case ALGO_ELGAMAL: prefix = QStringLiteral("elg"); break;
0026     case ALGO_DSA: prefix = QStringLiteral("dsa"); break;
0027     }
0028 
0029     return prefix + QString::number(size);
0030 }
0031 
0032 //BEGIN KeySub
0033 KgpgKeySubPrivate::KgpgKeySubPrivate(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo,
0034                                      const KgpgSubKeyType type, const QDateTime &date, const QString &curve)
0035     : gpgsubvalid(false),
0036     gpgsubid(id),
0037     gpgsubsize(size),
0038     gpgsubcreation(date),
0039     gpgsubtrust(trust),
0040     gpgsubalgo(algo),
0041     gpgsubtype(type),
0042     gpgcurve(curve)
0043 {
0044 }
0045 
0046 bool KgpgKeySubPrivate::operator==(const KgpgKeySubPrivate &other) const
0047 {
0048     if (gpgsubvalid != other.gpgsubvalid) return false;
0049     if (gpgsubalgo != other.gpgsubalgo) return false;
0050     if (gpgsubid != other.gpgsubid) return false;
0051     if (gpgsubsize != other.gpgsubsize) return false;
0052     if (gpgsubexpiration != other.gpgsubexpiration) return false;
0053     if (gpgsubcreation != other.gpgsubcreation) return false;
0054     if (gpgsubtrust != other.gpgsubtrust) return false;
0055     if (gpgsubtype != other.gpgsubtype) return false;
0056     return true;
0057 }
0058 
0059 KgpgKeySub::KgpgKeySub(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo, const KgpgSubKeyType type,
0060                        const QDateTime &date, const QString &curve)
0061     : d(new KgpgKeySubPrivate(id, size, trust, algo, type, date, curve))
0062 {
0063 }
0064 
0065 KgpgKeySub::KgpgKeySub(const KgpgKeySub &other)
0066     : d(other.d)
0067 {
0068 }
0069 
0070 void KgpgKeySub::setExpiration(const QDateTime &date)
0071 {
0072     d->gpgsubexpiration = date;
0073 }
0074 
0075 void KgpgKeySub::setValid(const bool valid)
0076 {
0077     d->gpgsubvalid = valid;
0078 }
0079 
0080 QString KgpgKeySub::id() const
0081 {
0082     return d->gpgsubid;
0083 }
0084 
0085 uint KgpgKeySub::size() const
0086 {
0087     return d->gpgsubsize;
0088 }
0089 
0090 QString KgpgKeySub::strength() const
0091 {
0092     return _describe_key_strength(algorithm(), size(), d->gpgcurve);
0093 }
0094 
0095 bool KgpgKeySub::unlimited() const
0096 {
0097     return d->gpgsubexpiration.isNull();
0098 }
0099 
0100 QDateTime KgpgKeySub::expirationDate() const
0101 {
0102     return d->gpgsubexpiration;
0103 }
0104 
0105 QDateTime KgpgKeySub::creationDate() const
0106 {
0107     return d->gpgsubcreation;
0108 }
0109 
0110 KgpgKeyTrust KgpgKeySub::trust() const
0111 {
0112     return d->gpgsubtrust;
0113 }
0114 
0115 KgpgKeyAlgo KgpgKeySub::algorithm() const
0116 {
0117     return d->gpgsubalgo;
0118 }
0119 
0120 bool KgpgKeySub::valid() const
0121 {
0122     return d->gpgsubvalid;
0123 }
0124 
0125 KgpgSubKeyType KgpgKeySub::type() const
0126 {
0127     return d->gpgsubtype;
0128 }
0129 
0130 QString KgpgKeySub::curve() const
0131 {
0132     return d->gpgcurve;
0133 }
0134 
0135 bool KgpgKeySub::operator==(const KgpgKeySub &other) const
0136 {
0137     if (d == other.d) return true;
0138     if ((*d) == (*(other.d))) return true;
0139     return false;
0140 }
0141 
0142 KgpgKeySub& KgpgKeySub::operator=(const KgpgKeySub &other)
0143 {
0144     d = other.d;
0145     return *this;
0146 }
0147 
0148 //END KeySub
0149 
0150 
0151 //BEGIN Key
0152 
0153 KgpgKeyPrivate::KgpgKeyPrivate(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo, const KgpgSubKeyType subtype,
0154                                const KgpgSubKeyType keytype, const QDateTime &creationDate, const QString &curve)
0155     : gpgkeysecret(false),
0156     gpgkeyvalid(false),
0157     gpgkeyid(id),
0158     gpgkeysize(size),
0159     gpgkeytrust(trust),
0160     gpgkeycreation(creationDate),
0161     gpgkeyalgo(algo),
0162     gpgsubtype(subtype),
0163     gpgkeytype(keytype),
0164     gpgcurve(curve),
0165     gpgsublist(new KgpgKeySubList())
0166 {
0167 }
0168 
0169 bool KgpgKeyPrivate::operator==(const KgpgKeyPrivate &other) const
0170 {
0171     if (gpgkeysecret != other.gpgkeysecret) return false;
0172     if (gpgkeyvalid != other.gpgkeyvalid) return false;
0173     if (gpgkeymail != other.gpgkeymail) return false;
0174     if (gpgkeyname != other.gpgkeyname) return false;
0175     if (gpgkeycomment != other.gpgkeycomment) return false;
0176     if (gpgkeyfingerprint != other.gpgkeyfingerprint) return false;
0177     if (gpgkeyid != other.gpgkeyid) return false;
0178     if (gpgkeysize != other.gpgkeysize) return false;
0179     if (gpgkeyownertrust != other.gpgkeyownertrust) return false;
0180     if (gpgkeytrust != other.gpgkeytrust) return false;
0181     if (gpgkeycreation != other.gpgkeycreation) return false;
0182     if (gpgkeyexpiration != other.gpgkeyexpiration) return false;
0183     if (gpgkeyalgo != other.gpgkeyalgo) return false;
0184     if (gpgsubtype != other.gpgsubtype) return false;
0185     if (gpgkeytype != other.gpgkeytype) return false;
0186     if (gpgsublist != other.gpgsublist) return false;
0187     return true;
0188 }
0189 
0190 KgpgKey::KgpgKey(const QString &id, const uint size, const KgpgKeyTrust trust, const KgpgKeyAlgo algo, const KgpgSubKeyType subtype,
0191                  const KgpgSubKeyType keytype, const QDateTime &creationDate, const QString &curve)
0192     : d(new KgpgKeyPrivate(id, size, trust, algo, subtype, keytype, creationDate, curve))
0193 {
0194 }
0195 
0196 KgpgKey::KgpgKey(const KgpgKey &other)
0197     : d(other.d)
0198 {
0199 }
0200 
0201 void KgpgKey::setSecret(const bool secret)
0202 {
0203     d->gpgkeysecret = secret;
0204 }
0205 
0206 void KgpgKey::setValid(const bool valid)
0207 {
0208     d->gpgkeyvalid = valid;
0209 }
0210 
0211 void KgpgKey::setName(const QString &name)
0212 {
0213     d->gpgkeyname = name;
0214 }
0215 
0216 void KgpgKey::setEmail(const QString &email)
0217 {
0218     d->gpgkeymail = email;
0219 }
0220 
0221 void KgpgKey::setComment(const QString &comment)
0222 {
0223     d->gpgkeycomment = comment;
0224 }
0225 
0226 void KgpgKey::setFingerprint(const QString &fingerprint)
0227 {
0228     d->gpgkeyfingerprint = fingerprint;
0229 }
0230 
0231 void KgpgKey::setOwnerTrust(const gpgme_validity_t owtrust)
0232 {
0233     d->gpgkeyownertrust = owtrust;
0234 }
0235 
0236 void KgpgKey::setExpiration(const QDateTime &date)
0237 {
0238     d->gpgkeyexpiration = date;
0239 }
0240 
0241 bool KgpgKey::secret() const
0242 {
0243     return d->gpgkeysecret;
0244 }
0245 
0246 bool KgpgKey::valid() const
0247 {
0248     return d->gpgkeyvalid;
0249 }
0250 
0251 QString KgpgKey::id() const
0252 {
0253     return d->gpgkeyid.right(8);
0254 }
0255 
0256 QString KgpgKey::fullId() const
0257 {
0258     return d->gpgkeyid;
0259 }
0260 
0261 QString KgpgKey::name() const
0262 {
0263     return d->gpgkeyname;
0264 }
0265 
0266 QString KgpgKey::email() const
0267 {
0268     return d->gpgkeymail;
0269 }
0270 
0271 QString KgpgKey::comment() const
0272 {
0273     return d->gpgkeycomment;
0274 }
0275 
0276 const QString &KgpgKey::fingerprint() const
0277 {
0278     return d->gpgkeyfingerprint;
0279 }
0280 
0281 uint KgpgKey::size() const
0282 {
0283     return d->gpgkeysize;
0284 }
0285 
0286 QString KgpgKey::strength() const
0287 {
0288     return _describe_key_strength(algorithm(), size(), d->gpgcurve);
0289 }
0290 
0291 /**
0292  * @brief find the "best" encryption key
0293  *
0294  * The "best" is the first one that is not expired, or simply the
0295  * first one.
0296  */
0297 static const KgpgKeySub *
0298 bestEncryptionKey(const KgpgKeySubList &list)
0299 {
0300     const KgpgKeySub *enc = nullptr;
0301     // Get the first encryption subkey
0302     for (const KgpgKeySub &k : list) {
0303         if (k.type() & SKT_ENCRYPTION) {
0304             // if the first encryption subkey is expired
0305             // check if there is one that is not
0306             if (k.trust() > TRUST_EXPIRED)
0307                 return &k;
0308             if (enc == nullptr)
0309                 enc = &k;
0310         }
0311     }
0312 
0313     return enc;
0314 }
0315 
0316 uint KgpgKey::encryptionSize() const
0317 {
0318     const KgpgKeySub *enc = bestEncryptionKey(*d->gpgsublist);
0319     if (enc != nullptr)
0320         return enc->size();
0321     return 0;
0322 }
0323 
0324 QString KgpgKey::encryptionStrength() const
0325 {
0326     const KgpgKeySub *enc = bestEncryptionKey(*d->gpgsublist);
0327     if (enc != nullptr)
0328         return _describe_key_strength(enc->algorithm(), enc->size(), enc->curve());
0329     return QString();
0330 }
0331 
0332 gpgme_validity_t KgpgKey::ownerTrust() const
0333 {
0334     return d->gpgkeyownertrust;
0335 }
0336 
0337 KgpgKeyTrust KgpgKey::trust() const
0338 {
0339     return d->gpgkeytrust;
0340 }
0341 
0342 QDateTime KgpgKey::creationDate() const
0343 {
0344     return d->gpgkeycreation;
0345 }
0346 
0347 QDateTime KgpgKey::expirationDate() const
0348 {
0349     return d->gpgkeyexpiration;
0350 }
0351 
0352 bool KgpgKey::unlimited() const
0353 {
0354     return d->gpgkeyexpiration.isNull();
0355 }
0356 
0357 KgpgKeyAlgo KgpgKey::algorithm() const
0358 {
0359     return d->gpgkeyalgo;
0360 }
0361 
0362 KgpgKeyAlgo KgpgKey::encryptionAlgorithm() const
0363 {
0364     // Get the first encryption subkey
0365     auto it = std::find_if(d->gpgsublist->cbegin(), d->gpgsublist->cend(),
0366             [](const KgpgKeySub &k) { return k.type() & SKT_ENCRYPTION; });
0367     if (it != d->gpgsublist->cend())
0368         return it->algorithm();
0369 
0370     return ALGO_UNKNOWN;
0371 }
0372 
0373 KgpgSubKeyType KgpgKey::subtype() const
0374 {
0375     return d->gpgsubtype;
0376 }
0377 
0378 KgpgSubKeyType KgpgKey::keytype() const
0379 {
0380     return d->gpgkeytype;
0381 }
0382 
0383 QString KgpgKey::curve() const
0384 {
0385     return d->gpgcurve;
0386 }
0387 
0388 KgpgKeySubListPtr KgpgKey::subList() const
0389 {
0390     return d->gpgsublist;
0391 }
0392 
0393 bool KgpgKey::operator==(const KgpgKey &other) const
0394 {
0395     if (d == other.d) return true;
0396     if ((*d) == (*(other.d))) return true;
0397     return false;
0398 }
0399 
0400 KgpgKey& KgpgKey::operator=(const KgpgKey &other)
0401 {
0402     d = other.d;
0403     return *this;
0404 }
0405 
0406 KgpgKeyList::operator QStringList() const
0407 {
0408     QStringList res;
0409     res.reserve(count());
0410 
0411     for (const KgpgKey &key : *this)
0412         res << key.fullId();
0413 
0414     return res;
0415 }
0416 
0417 //END Key
0418 
0419 } // namespace KgpgCore