Bug 117799 - duplicate Key ID confuse kgpg
Summary: duplicate Key ID confuse kgpg
Status: RESOLVED FIXED
Alias: None
Product: kgpg
Classification: Applications
Component: general (show other bugs)
Version: 1.2.1
Platform: Unlisted Binaries Linux
: NOR normal
Target Milestone: ---
Assignee: bj
URL:
Keywords:
: 143483 164376 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-12-06 16:32 UTC by Hubert Figuiere
Modified: 2008-06-18 15:32 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hubert Figuiere 2005-12-06 16:32:15 UTC
Version:           1.2.1 (using KDE KDE 3.4.2)
Installed from:    Unspecified Linux
OS:                Linux

kgpg seems to be all confused when it has two GPG keys that have the same 32-bits key UID.

My key is 0xA56E15A3, and it has a "duplicate" on the keyserver.

Various symptoms:

I refresh my key from the keyserver, it does download the other key with the same key id.

Then once they are both in the keyring, the list of signature and sub-keys is completely incorrect as the other key have signatures that belongs to mine.
Using GPG in the command line does not exhibit the problem.
Comment 1 Rolf Eike Beer 2007-08-08 13:28:30 UTC
*** Bug 143483 has been marked as a duplicate of this bug. ***
Comment 2 Rolf Eike Beer 2007-08-16 10:49:30 UTC
SVN commit 700719 by dakon:

Fix wrong import key ids if key server returns complete fingerprint

BUG:139774

While at it: use the last 16 bytes of the fingerprint to receive the key. 
This should ease the problem with duplicate key ids a bit.

CCBUG:117799


 M  +5 -5      keyservers.cpp  


--- trunk/KDE/kdeutils/kgpg/keyservers.cpp #700718:700719
@@ -535,7 +535,7 @@
         return;
 
     QString kid;
-    QString keysToSearch;
+    QStringList keysToSearch;
     m_listpop->kLEID->clear();
     QList<Q3ListViewItem*>searchList = m_listpop->kLVsearch->selectedItems();
 
@@ -549,13 +549,13 @@
                 kid = searchList.at(i)->text(0).simplified();
 
             kid = kid.section("key", 1, 1);
-            kid = kid.simplified();
-            keysToSearch.append(' ' + kid.left(8));
+            kid = kid.simplified().section(",", 0, 0);
+            keysToSearch << kid.right(16);
         }
     }
 
-    kDebug(2100) << keysToSearch ;
-    m_listpop->kLEID->setText(keysToSearch.simplified());
+    kDebug(2100) << keysToSearch;
+    m_listpop->kLEID->setText(keysToSearch.join(" "));
 }
 
 void KeyServer::slotPreImport()
Comment 3 Rolf Eike Beer 2007-08-18 10:11:19 UTC
SVN commit 701415 by dakon:

Make the rest of default key operations work better with 16 byte key ids

CCBUG:117799


 M  +34 -4     keylistview.cpp  
 M  +2 -0      keylistview.h  
 M  +17 -15    keysmanager.cpp  
 M  +1 -1      kgpg.cpp  
 M  +1 -1      kgpgsettings_addons.h  


--- trunk/KDE/kdeutils/kgpg/keylistview.cpp #701414:701415
@@ -356,7 +356,7 @@
 
     refreshKeys(keyids);
 
-    ensureItemVisible(this->findItem((keyids.last()).right(8), Q3ListView::BeginsWith | Q3ListView::EndsWith));
+    ensureItemVisible(this->findItemByKeyId(keyids.last()));
     emit statusMessage(i18n("%1 Keys, %2 Groups", childCount() - groupNb, groupNb), 1);
     emit statusMessage(i18n("Ready"), 0);
 }
@@ -395,7 +395,7 @@
     {
         // select previous selected
         if (!current->text(6).isEmpty())
-            newPos = findItem(current->text(6), 6);
+            newPos = findItemByKeyId(current->keyId());
         else
             newPos = findItem(current->text(0), 0);
         delete current;
@@ -521,13 +521,13 @@
     QStringList::Iterator it;
     QStringList list;
     for (it = issec.begin(); it != issec.end(); ++it)
-        if (findItem(*it, 6) == 0)
+        if (findItemByKeyId(*it) == NULL)
             list += *it;
 
     if (list.size() != 0)
         insertOrphans(list);
 
-    setSelected(findItem(*it, 6), true);
+    setSelected(findItemByKeyId(*it), true);
     emit statusMessage(i18n("%1 Keys, %2 Groups", childCount() - groupNb, groupNb), 1);
     emit statusMessage(i18n("Ready"), 0);
 }
@@ -810,6 +810,36 @@
 	return list;
 }
 
+/**
+ * Find the item that is a primary key with the given id. Match will be
+ * by full id if possible, else by short id. Passing a fingerprint is
+ * explicitely allowed (forward compatibility) but currently matching
+ * is only done by full id.
+ */
+KeyListViewItem *KeyListView::findItemByKeyId(const QString &id)
+{
+	QString fullid = id.right(16);
+	KeyListViewItem *cur = findItem(fullid.right(8), 6);
+
+	if ((cur == NULL) || ((fullid.length() < 16) && (cur->getKey() != NULL)))
+		return cur;
+
+	KgpgKey *key = cur->getKey();
+	if ((key != NULL) && (key->fullId() == id))
+		return cur;
+
+	// The first hit doesn't match the full id. Do deep scanning.
+	for (int i = 0; i < childCount(); i++) {
+		cur = itemAtIndex(i);
+		key = cur->getKey();
+		if (key == NULL)
+			continue;
+		if (key->fullId() == fullid)
+			return cur;
+	}
+	return NULL;
+}
+
 KeyListViewSearchLine::KeyListViewSearchLine(QWidget *parent, KeyListView *listView)
                      : K3ListViewSearchLine(parent, listView)
 {
--- trunk/KDE/kdeutils/kgpg/keylistview.h #701414:701415
@@ -115,6 +115,8 @@
 		{ return static_cast<KeyListViewItem *>(K3ListView::findItem(text, column, compare)); }
     virtual QList<KeyListViewItem *> selectedItems(void);
     virtual KeyListViewItem *lastChild() const { return static_cast<KeyListViewItem*>(K3ListView::lastChild()); }
+    virtual KeyListViewItem *itemAtIndex(int index) { return static_cast<KeyListViewItem*>(K3ListView::itemAtIndex(index)); }
+    virtual KeyListViewItem *findItemByKeyId(const QString &id);
 
 private slots:
     void droppedFile(const KUrl &url);
--- trunk/KDE/kdeutils/kgpg/keysmanager.cpp #701414:701415
@@ -606,7 +606,7 @@
 
         keyCreated->exec();
 
-        KeyListViewItem *newdef = keysList2->findItem(id, 6);
+        KeyListViewItem *newdef = keysList2->findItemByKeyId(fingerprint);
         if (newdef)
         {
             if (page->CBdefault->isChecked())
@@ -701,7 +701,7 @@
 
 void KeysManager::slotGotoDefaultKey()
 {
-    KeyListViewItem *myDefaulKey = keysList2->findItem(KGpgSettings::defaultKey(), 6);
+    KeyListViewItem *myDefaulKey = keysList2->findItemByKeyId(KGpgSettings::defaultKey());
     keysList2->clearSelection();
     keysList2->setCurrentItem(myDefaulKey);
     keysList2->setSelected(myDefaulKey, true);
@@ -1245,30 +1245,32 @@
 
 void KeysManager::slotSetDefaultKey(const QString &newID)
 {
-    KeyListViewItem *newdef = keysList2->findItem(newID, 6);
-    if (newdef)
-        slotSetDefaultKey(newdef);
+    if (newID == KGpgSettings::defaultKey())
+      return;
+
+    KeyListViewItem *newdef = keysList2->findItemByKeyId(newID);
+    if (newdef == NULL) {
+      kDebug(3125) << "key with id" << newID << "not found in keys list";
+      return;
+    }
+
+    return slotSetDefaultKey(newdef);
 }
 
 void KeysManager::slotSetDefaultKey(KeyListViewItem *newdef)
 {
-    //kDebug(2100)<<"------------------start ------------";
-    if ((!newdef) || (newdef->pixmap(2)==NULL))
-        return;
-    //kDebug(2100)<<newdef->text(6);
-    //kDebug(2100)<<KGpgSettings::defaultKey();
-    if ((newdef->text(6)==KGpgSettings::defaultKey()) || (newdef->keyId() == KGpgSettings::defaultKey()))
-        return;
+    Q_ASSERT(newdef->pixmap(2) != NULL);
+
     if ((newdef->pixmap(2)->serialNumber()!=keysList2->trustgood.serialNumber()) &&
         (newdef->pixmap(2)->serialNumber()!=keysList2->trustultimate.serialNumber()))
     {
-        KMessageBox::sorry(this,i18n("Sorry, this key is not valid for encryption or not trusted."));
+        KMessageBox::sorry(this, i18n("<qt>Sorry, the key <b>%1</b> is not valid for encryption or not trusted.</qt>", newdef->keyId()));
         return;
     }
 
-    KeyListViewItem *olddef = keysList2->findItem(KGpgSettings::defaultKey(), 6);
+    KeyListViewItem *olddef = keysList2->findItemByKeyId(KGpgSettings::defaultKey());
 
-    KGpgSettings::setDefaultKey(newdef->text(6));
+    KGpgSettings::setDefaultKey(newdef->keyId());
     KGpgSettings::self()->writeConfig();
     if (olddef)
         keysList2->refreshcurrentkey(olddef);
--- trunk/KDE/kdeutils/kgpg/kgpg.cpp #701414:701415
@@ -1055,7 +1055,7 @@
 
 void KgpgAppletApp::wizardOver(const QString &defaultKeyId)
 {
-    if (defaultKeyId.length() == 8)
+    if (defaultKeyId.length() >= 8)
         s_keyManager->slotSetDefaultKey(defaultKeyId);
 
     s_keyManager->show();
--- trunk/KDE/kdeutils/kgpg/kgpgsettings_addons.h #701414:701415
@@ -30,7 +30,7 @@
    void setDefaultKey(const QString &_defaultKey)
    {
      self()->mDefaultKey = _defaultKey;
-     KgpgInterface::setGpgSetting("default-key",_defaultKey.right(8),gpgConfigPath());
+     KgpgInterface::setGpgSetting("default-key", _defaultKey, gpgConfigPath());
    }
    
 private:
Comment 4 Rolf Eike Beer 2007-08-20 16:30:01 UTC
I think this should work now as far as KGpg is involved, e.g. displaying signatures at the correct key etc. What remains is is refreshing from keyserver. But this is either a gpg or keyserver problem, testing it on the command line shows that even gpg get's it wrong:

gpg --refresh-key 5FEE05E6A56E15A3
gpg: refreshing 1 key from hkp://subkeys.pgp.net
gpg: requesting key A56E15A3 from hkp server subkeys.pgp.net
gpg: key A56E15A3: "Pedro R. Fernandez (GNU/Linux User #000.204.555 http://counter.li.org/) <prafer@eresmas.com>" not changed
gpg: key A56E15A3: "Hubert Figuiere <hub@figuiere.net>" not changed
gpg: Total number processed: 2
gpg:              unchanged: 2

Please retest with recent SVN version (KDE 4 beta) and reopen if there are still open issues.
Comment 5 Rolf Eike Beer 2008-06-18 14:35:35 UTC
*** Bug 164376 has been marked as a duplicate of this bug. ***
Comment 6 Ralph Moenchmeyer 2008-06-18 15:32:35 UTC
Is there a solution available which works for KDE 3.5.x ?