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

0001 /*
0002     SPDX-FileCopyrightText: 2008, 2009, 2010, 2012, 2013, 2014, 2017 Rolf Eike Beer <kde@opensource.sf-tec.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 #include "KGpgKeyNode.h"
0007 
0008 #include "KGpgGroupMemberNode.h"
0009 #include "KGpgRootNode.h"
0010 #include "KGpgSubkeyNode.h"
0011 #include "KGpgUatNode.h"
0012 #include "KGpgUidNode.h"
0013 #include "convert.h"
0014 #include "kgpginterface.h"
0015 #include "kgpgsettings.h"
0016 #include "model/kgpgitemmodel.h"
0017 
0018 #include <KLocalizedString>
0019 
0020 KGpgKeyNode::KGpgKeyNode(KGpgRootNode *parent, const KgpgCore::KgpgKey &k)
0021     : KGpgSignableNode(parent),
0022     m_key(new KgpgCore::KgpgKey(k)),
0023     m_signs(0)
0024 {
0025 }
0026 
0027 KGpgKeyNode::~KGpgKeyNode()
0028 {
0029     // do not try to access the root node if we are being deleted from there
0030     KGpgRootNode * const root = parent() != nullptr ? m_parent->toRootNode() : nullptr;
0031     for (KGpgRefNode *nd : std::as_const(m_refs))
0032         nd->unRef(root);
0033 }
0034 
0035 KgpgCore::KgpgItemType
0036 KGpgKeyNode::getType() const
0037 {
0038     return getType(m_key);
0039 }
0040 
0041 bool
0042 KGpgKeyNode::hasChildren() const
0043 {
0044     return true;
0045 }
0046 
0047 KgpgCore::KgpgItemType
0048 KGpgKeyNode::getType(const KgpgCore::KgpgKey *k)
0049 {
0050     if (k->secret())
0051         return KgpgCore::ITYPE_PAIR;
0052 
0053     return KgpgCore::ITYPE_PUBLIC;
0054 }
0055 
0056 KgpgCore::KgpgKeyTrust
0057 KGpgKeyNode::getTrust() const
0058 {
0059     return m_key->trust();
0060 }
0061 
0062 const QString &
0063 KGpgKeyNode::getFingerprint() const
0064 {
0065     return m_key->fingerprint();
0066 }
0067 
0068 QString
0069 KGpgKeyNode::getSize() const
0070 {
0071     return i18nc("size of signing key / size of encryption key",
0072             "%1 / %2", m_key->strength(),
0073             m_key->encryptionStrength());
0074 }
0075 
0076 QString
0077 KGpgKeyNode::getName() const
0078 {
0079     return m_key->name();
0080 }
0081 
0082 QString
0083 KGpgKeyNode::getEmail() const
0084 {
0085     return m_key->email();
0086 }
0087 
0088 QDateTime
0089 KGpgKeyNode::getExpiration() const
0090 {
0091     return m_key->expirationDate();
0092 }
0093 
0094 QDateTime
0095 KGpgKeyNode::getCreation() const
0096 {
0097     return m_key->creationDate();
0098 }
0099 
0100 QString
0101 KGpgKeyNode::getId() const
0102 {
0103     return m_key->fullId();
0104 }
0105 
0106 KGpgKeyNode *
0107 KGpgKeyNode::getKeyNode(void)
0108 {
0109     return this;
0110 }
0111 
0112 bool
0113 KGpgKeyNode::isSecret() const
0114 {
0115     return m_key->secret();
0116 }
0117 
0118 const KGpgKeyNode *
0119 KGpgKeyNode::getKeyNode(void) const
0120 {
0121     return this;
0122 }
0123 
0124 QString
0125 KGpgKeyNode::getBeautifiedFingerprint() const
0126 {
0127     static const QChar space = QLatin1Char(' ');
0128     QString fingervalue = m_key->fingerprint();
0129     int len = fingervalue.length();
0130     if ((len > 0) && (len % 4 == 0))
0131         for (int n = 0; 4 * (n + 1) < len; n++)
0132             fingervalue.insert(5 * n + 4, space);
0133     return fingervalue;
0134 }
0135 
0136 QString
0137 KGpgKeyNode::getComment() const
0138 {
0139     return m_key->comment();
0140 }
0141 
0142 void
0143 KGpgKeyNode::readChildren()
0144 {
0145     KgpgInterface::readSignatures(this);
0146 
0147     m_signs = std::count_if(children.cbegin(), children.cend(),
0148             [](const KGpgNode *n) { return n->getType() == ITYPE_SIGN; });
0149 }
0150 
0151 QString
0152 KGpgKeyNode::getSignCount() const
0153 {
0154     if (!wasExpanded())
0155         return QString();
0156     return i18np("1 signature", "%1 signatures", m_signs);
0157 }
0158 
0159 KgpgKey *
0160 KGpgKeyNode::copyKey() const
0161 {
0162     return new KgpgKey(*m_key);
0163 }
0164 
0165 void
0166 KGpgKeyNode::setKey(const KgpgKey &key)
0167 {
0168     Q_ASSERT(m_key->fingerprint() == key.fingerprint());
0169     delete m_key;
0170 
0171     for (int i = 0; i < children.count(); i++)
0172         delete children.at(i);
0173     children.clear();
0174 
0175     m_key = new KgpgKey(key);
0176 }
0177 
0178 const KgpgKey *
0179 KGpgKeyNode::getKey() const
0180 {
0181     return m_key;
0182 }
0183 
0184 unsigned int
0185 KGpgKeyNode::getSignKeySize() const
0186 {
0187     return m_key->size();
0188 }
0189 
0190 unsigned int
0191 KGpgKeyNode::getEncryptionKeySize() const
0192 {
0193     return m_key->encryptionSize();
0194 }
0195 
0196 void
0197 KGpgKeyNode::addRef(KGpgRefNode *node)
0198 {
0199     Q_ASSERT(m_refs.indexOf(node) == -1);
0200     m_refs.append(node);
0201 }
0202 
0203 void
0204 KGpgKeyNode::delRef(KGpgRefNode *node)
0205 {
0206     Q_ASSERT(m_refs.indexOf(node) != -1);
0207     m_refs.removeOne(node);
0208     Q_ASSERT(m_refs.indexOf(node) == -1);
0209 }
0210 
0211 QList<KGpgGroupNode *>
0212 KGpgKeyNode::getGroups(void) const
0213 {
0214     QList<KGpgGroupNode *> ret;
0215     const QList<KGpgGroupMemberNode *> refs = getGroupRefs();
0216     ret.reserve(refs.count());
0217 
0218     for (KGpgGroupMemberNode *gnd : refs)
0219         ret.append(gnd->getParentKeyNode());
0220 
0221     return ret;
0222 }
0223 
0224 QList<KGpgRefNode *>
0225 KGpgKeyNode::getRefsOfType(const KgpgItemType &type) const
0226 {
0227     QList<KGpgRefNode *> ret;
0228 
0229     for (KGpgRefNode *nd : m_refs) {
0230         if (nd->getType() & type)
0231             ret.append(nd);
0232     }
0233 
0234     return ret;
0235 }
0236 
0237 QList<KGpgGroupMemberNode *>
0238 KGpgKeyNode::getGroupRefs(void) const
0239 {
0240     QList<KGpgGroupMemberNode *> ret;
0241     const QList<KGpgRefNode *> refs = getRefsOfType(KgpgCore::ITYPE_GROUP);
0242     ret.reserve(refs.count());
0243 
0244     for (KGpgRefNode *rn : refs)
0245         ret.append(rn->toGroupMemberNode());
0246 
0247     return ret;
0248 }
0249 
0250 KGpgSignNode::List
0251 KGpgKeyNode::getSignRefs(void) const
0252 {
0253     KGpgSignNode::List ret;
0254     const QList<KGpgRefNode *> refs = getRefsOfType(KgpgCore::ITYPE_SIGN);
0255     ret.reserve(refs.count());
0256 
0257     for (KGpgRefNode *rn : refs)
0258         ret.append(rn->toSignNode());
0259 
0260     return ret;
0261 }
0262 
0263 KGpgSignNode::List
0264 KGpgKeyNode::getSignatures(const bool subkeys) const
0265 {
0266     KGpgSignNode::List ret = KGpgSignableNode::getSignatures();
0267 
0268     if (!subkeys)
0269         return ret;
0270 
0271     for (KGpgNode *child : children) {
0272         switch (child->getType()) {
0273         case KgpgCore::ITYPE_UID:
0274         case KgpgCore::ITYPE_UAT:
0275             break;
0276         default:
0277             continue;
0278         }
0279 
0280         const KGpgSignNode::List tmp = child->toSignableNode()->getSignatures();
0281 
0282         for (KGpgSignNode *sn : tmp) {
0283             bool found = false;
0284             const QString snid(sn->getId());
0285 
0286             for (const KGpgSignNode *retsn : std::as_const(ret)) {
0287                 found = (retsn->getId() == snid);
0288                 if (found)
0289                     break;
0290             }
0291 
0292             if (!found)
0293                 ret << sn;
0294         }
0295     }
0296 
0297     return ret;
0298 }
0299 
0300 const KGpgSignableNode *
0301 KGpgKeyNode::getUid(const unsigned int index) const
0302 {
0303     Q_ASSERT(index > 0);
0304 
0305     if (index == 1)
0306         return this;
0307 
0308     const QString idxstr = QString::number(index);
0309 
0310     for (const KGpgNode *child : children) {
0311         switch (child->getType()) {
0312         case KgpgCore::ITYPE_UID:
0313         case KgpgCore::ITYPE_UAT:
0314             if (child->getId() == idxstr)
0315                 return child->toSignableNode();
0316             break;
0317         default:
0318             continue;
0319         }
0320     }
0321 
0322     return nullptr;
0323 }
0324 
0325 bool
0326 KGpgKeyNode::compareId(const QString &other) const
0327 {
0328     if (other.length() == m_key->fullId().length())
0329         return (other.compare(m_key->fullId(), Qt::CaseInsensitive) == 0);
0330 
0331     if (other.length() == m_key->fingerprint().length())
0332         return (other.compare(m_key->fingerprint(), Qt::CaseInsensitive) == 0);
0333 
0334     const QString comId = m_key->fullId().isEmpty() ? m_key->fingerprint() : m_key->fullId();
0335     return (QStringView(other).right(comId.length()).compare(QStringView(comId).right(other.length()), Qt::CaseInsensitive) == 0);
0336 }
0337 
0338 bool
0339 KGpgKeyNode::canEncrypt() const
0340 {
0341     return ((m_key->keytype() & KgpgCore::SKT_ENCRYPTION) != 0);
0342 }
0343 
0344 void
0345 KGpgKeyNode::expand()
0346 {
0347     if (!wasExpanded())
0348         readChildren();
0349 
0350     Q_EMIT expanded();
0351 }