[bug] don't repush a public key with different address
authorRuben Pollan <meskio@sindominio.net>
Wed, 23 Sep 2015 23:15:11 +0000 (01:15 +0200)
committerRuben Pollan <meskio@sindominio.net>
Thu, 24 Sep 2015 15:08:59 +0000 (17:08 +0200)
During decryption the signing public key was getting repush with a
different address as part of the verify usage flagging.

- Resolves: https://github.com/pixelated/pixelated-user-agent/issues/466
- Related: #7420

changes/bug-address_mixup [new file with mode: 0644]
src/leap/keymanager/__init__.py
src/leap/keymanager/tests/test_validation.py

diff --git a/changes/bug-address_mixup b/changes/bug-address_mixup
new file mode 100644 (file)
index 0000000..24170c9
--- /dev/null
@@ -0,0 +1 @@
+- Don't repush a public key with different address
index cf099bb..22fb725 100644 (file)
@@ -590,10 +590,12 @@ class KeyManager(object):
             if pubkey is None:
                 signature = KeyNotFound(verify)
             elif signed:
-                pubkey.sign_used = True
-                d = self._wrapper_map[ktype].put_key(pubkey, address)
-                d.addCallback(lambda _: (decrypted, pubkey))
-                return d
+                signature = pubkey
+                if not pubkey.sign_used:
+                    pubkey.sign_used = True
+                    d = self._wrapper_map[ktype].put_key(pubkey, verify)
+                    d.addCallback(lambda _: (decrypted, signature))
+                    return d
             else:
                 signature = InvalidSignature(
                     'Failed to verify signature with key %s' %
@@ -685,10 +687,12 @@ class KeyManager(object):
             signed = self._wrapper_map[ktype].verify(
                 data, pubkey, detached_sig=detached_sig)
             if signed:
-                pubkey.sign_used = True
-                d = self._wrapper_map[ktype].put_key(pubkey, address)
-                d.addCallback(lambda _: pubkey)
-                return d
+                if not pubkey.sign_used:
+                    pubkey.sign_used = True
+                    d = self._wrapper_map[ktype].put_key(pubkey, address)
+                    d.addCallback(lambda _: pubkey)
+                    return d
+                return pubkey
             else:
                 raise InvalidSignature(
                     'Failed to verify signature with key %s' %
index ddf1170..bcf41c4 100644 (file)
@@ -30,6 +30,9 @@ from leap.keymanager.tests import (
     KeyManagerWithSoledadTestCase,
     ADDRESS,
     PUBLIC_KEY,
+    ADDRESS_2,
+    PUBLIC_KEY_2,
+    PRIVATE_KEY_2,
     KEY_FINGERPRINT
 )
 from leap.keymanager.validation import ValidationLevels
@@ -101,7 +104,7 @@ class ValidationLevelsTestCase(KeyManagerWithSoledadTestCase):
         self.assertEqual(key.fingerprint, UNRELATED_FINGERPRINT)
 
     @inlineCallbacks
-    def test_used(self):
+    def test_used_with_verify(self):
         TEXT = "some text"
 
         km = self._key_manager()
@@ -119,6 +122,27 @@ class ValidationLevelsTestCase(KeyManagerWithSoledadTestCase):
         yield self.assertFailure(d, KeyNotValidUpgrade)
 
     @inlineCallbacks
+    def test_used_with_decrypt(self):
+        TEXT = "some text"
+
+        km = self._key_manager()
+        yield km.put_raw_key(UNEXPIRED_KEY, OpenPGPKey, ADDRESS)
+        yield km.put_raw_key(PRIVATE_KEY_2, OpenPGPKey, ADDRESS_2)
+        yield km.encrypt(TEXT, ADDRESS, OpenPGPKey)
+
+        km2 = self._key_manager()
+        yield km2.put_raw_key(UNEXPIRED_PRIVATE, OpenPGPKey, ADDRESS)
+        yield km2.put_raw_key(PUBLIC_KEY_2, OpenPGPKey, ADDRESS_2)
+        encrypted = yield km2.encrypt(TEXT, ADDRESS_2, OpenPGPKey,
+                                      sign=ADDRESS)
+
+        yield km.decrypt(encrypted, ADDRESS_2, OpenPGPKey, verify=ADDRESS)
+        d = km.put_raw_key(
+            UNRELATED_KEY, OpenPGPKey, ADDRESS,
+            validation=ValidationLevels.Provider_Endorsement)
+        yield self.assertFailure(d, KeyNotValidUpgrade)
+
+    @inlineCallbacks
     def test_signed_key(self):
         km = self._key_manager()
         yield km.put_raw_key(PUBLIC_KEY, OpenPGPKey, ADDRESS)