Merge keys when updating an exisiting key
authorRuben Pollan <meskio@sindominio.net>
Fri, 31 Oct 2014 03:54:32 +0000 (21:54 -0600)
committerRuben Pollan <meskio@sindominio.net>
Tue, 4 Nov 2014 17:53:24 +0000 (11:53 -0600)
This is needed to prevent roll back attacks where the attacker push us
to accept a key with an old expiration date that could be use to push an
untrusted key when after it's expiration.

src/leap/keymanager/openpgp.py
src/leap/keymanager/tests/test_validation.py
src/leap/keymanager/validation.py

index e84cd29..f86b35d 100644 (file)
@@ -37,6 +37,8 @@ from leap.keymanager.keys import (
     build_key_from_dict,
     KEYMANAGER_KEY_TAG,
     TAGS_ADDRESS_PRIVATE_INDEX,
+    KEY_FINGERPRINT_KEY,
+    KEY_DATA_KEY,
 )
 from leap.keymanager.validation import ValidationLevel
 
@@ -394,6 +396,16 @@ class OpenPGPScheme(EncryptionScheme):
         if doc is None:
             self._soledad.create_doc_from_json(key.get_json())
         else:
+            if key.fingerprint == doc.content[KEY_FINGERPRINT_KEY]:
+                # in case of an update of the key merge them with gnupg
+                with self._temporary_gpgwrapper() as gpg:
+                    gpg.import_keys(doc.content[KEY_DATA_KEY])
+                    gpg.import_keys(key.key_data)
+                    gpgkey = gpg.list_keys(secret=key.private).pop()
+                    key = _build_key_from_gpg(
+                        key.address, gpgkey,
+                        gpg.export_keys(gpgkey['fingerprint'],
+                                        secret=key.private))
             doc.set_json(key.get_json())
             self._soledad.put_doc(doc)
 
index c7170ab..0f4d81a 100644 (file)
@@ -72,6 +72,13 @@ class ValidationLevelTestCase(KeyManagerWithSoledadTestCase):
             OpenPGPKey,
             validation=ValidationLevel.Provider_Trust)
 
+    def test_roll_back(self):
+        km = self._key_manager()
+        km.put_raw_key(EXPIRED_KEY_UPDATED, OpenPGPKey)
+        km.put_raw_key(EXPIRED_KEY, OpenPGPKey)
+        key = km.get_key(ADDRESS, OpenPGPKey, fetch_remote=False)
+        self.assertEqual(key.expiry_date, EXPIRED_KEY_NEW_EXPIRY_DATE)
+
 
 # Key material for testing
 
@@ -144,6 +151,42 @@ Osuse7+NkyUHgMXMVW7cz+nU7iO+ht2rkBtv+Z5LGlzgHTeFjKci
 =WhX+
 -----END PGP PUBLIC KEY BLOCK-----
 """
+# updated expiration date
+# Tue 24 Oct 2034 05:13:00 PM BST
+EXPIRED_KEY_NEW_EXPIRY_DATE = "2045319180"
+EXPIRED_KEY_UPDATED = """
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+mQENBBvrfd0BCADGNpspaNhsbhSjKioCWrE2MTTYC+Sdpes22RabdhQyOCWvlSbj
+b8p0y3kmnMOtVBT+c22/w7eu2YBfIpS4RswgE5ypr/1kZLFQueVe/cp29GjPvLwJ
+82A3EOHcmXs8rSJ76h2bnkySvbJawz9rwCcaXhpdAwC+sjWvbqiwZYEL+90I4Xp3
+acDh9vNtPxDCg5RdI0bfdIEBGgHTfsda3kWGvo1wH5SgrTRq0+EcTI7aJgkMmM/A
+IhnpACE52NvGdG9eB3x7xyQFsQqK8F0XvEev2UJH4SR7vb+Z7FNTJKCy6likYbSV
+wGGFuowFSESnzXuUI6PcjyuO6FUbMgeM5euFABEBAAG0HExlYXAgVGVzdCBLZXkg
+PGxlYXBAbGVhcC5zZT6JAT4EEwECACgCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B
+AheABQJUURIXBQld/ZovAAoJEG8V8AShiFp8xUcIALcAHZbaxvyhHRGOrwDddbH0
+fFDK0AqKTsIT7y4D/HLFCP5zG3Ck7qGPZdkHXZfzq8rIb+zUjW3oJIVI1IucHxG2
+T5kppa8RFCBAFlRWYf6R3isX3YL0d3QSragjoxRNPcHNU8ALHcvfSonFHBoi4fH4
+4rvgksAiT68SsdPaoXDlabx5T15evu/7T5e/DGMQVPMxiaSuSQhbOKuMk2wcFdmL
+tBYHLZPa54hHPNhEDyxLgtKKph0gObk9ojKfH9kPvLveIcpS5CqTJfN/kqBz7CJW
+wEeAi2iG3H1OEB25aCUdTxXSRNlGqEgcWPaWxtc1RzlARu7LB64OUZuRy4puiAG5
+AQ0EG+t93QEIAKqRq/2sBDW4g3FU+11LhixT+GosrfVvnitz3S9k2tBXok/wYpI1
+XeA+kTHiF0LaqoaciDRvkA9DvhDbSrNM1yeuYRyZiHlTmoPZ/Fkl60oA2cyLd1L5
+sXbuipY3TEiakugdSU4rzgi0hFycm6Go6yq2G6eC6UALvD9CTMdZHw40TadG9xpm
+4thYPuJ1kPH8/bkbTi9sLHoApYgL+7ssje8w4epr0qD4IGxeKwJPf/tbTRpnd8w3
+leldixHHKAutNt49p0pkXlORAHRpUmp+KMZhFvCvIPwe9o5mYtMR7sDRxjY61ZEQ
+KLyKoh5wsJsaPXBjdG7cf6G/cBcwvnQVUHcAEQEAAYkBJQQYAQIADwUCG+t93QIb
+DAUJAAFRgAAKCRBvFfAEoYhafOPgB/9z4YCyT/N0262HtegHykhsyykuqEeNb1LV
+D9INcP+RbCX/0IjFgP4DTMPP7qqF1OBwR276maALT321Gqxc5HN5YrwxGdmoyBLm
+unaQJJlD+7B1C+jnO6r4m44obvJ/NMERxVyzkXap3J2VgRIO1wNLI9I0sH6Kj5/j
+Mgy06OwXDcqIc+jB4sIJ3Tnm8LZ3phJzNEm9mI8Ak0oJ7IEcMndR6DzmRt1rJQcq
+K/D7hOG02zvyRhxF27U1qR1MxeU/gNnOx8q4dnVyWB+EiV1sFl4iTOyYHEsoyd7W
+Osuse7+NkyUHgMXMVW7cz+nU7iO+ht2rkBtv+Z5LGlzgHTeFjKci
+=79Ll
+-----END PGP PUBLIC KEY BLOCK-----
+"""
+
 
 import unittest
 if __name__ == "__main__":
index 6dceb78..7d68966 100644 (file)
@@ -73,7 +73,6 @@ def can_upgrade(new_key, old_key):
 
     # An update of the same key
     if new_key.fingerprint == old_key.fingerprint:
-        # XXX wich one is newer? is that a downgrade attack? (#6210)
         return True
 
     # Manually verified fingerprint