diff options
-rw-r--r-- | src/leap/soledad/__init__.py | 31 | ||||
-rw-r--r-- | src/leap/soledad/tests/test_encrypted.py | 88 |
2 files changed, 102 insertions, 17 deletions
diff --git a/src/leap/soledad/__init__.py b/src/leap/soledad/__init__.py index d883a8d0..316eeaf7 100644 --- a/src/leap/soledad/__init__.py +++ b/src/leap/soledad/__init__.py @@ -253,6 +253,9 @@ class Soledad(object): random.choice( string.ascii_letters + string.digits) for x in range(self.SECRET_LENGTH)) + self._store_secret() + + def _store_secret(self): ciphertext = self._gpg.encrypt(self._secret, self._fingerprint, self._fingerprint) f = open(self.secret_path, 'w') @@ -472,16 +475,34 @@ class Soledad(object): - private key. - key for symmetric encryption """ - data = json.dumps([ - self._user_email, - self._gpg.export_keys(self._fingerprint, secret=True), - self._secret - ]) + data = json.dumps({ + 'user_email': self._user_email, + 'privkey': self._gpg.export_keys(self._fingerprint, secret=True), + 'secret': self._secret, + }) if passphrase: data = str(self._gpg.encrypt(data, None, sign=None, passphrase=passphrase, symmetric=True)) return data + def import_recovery_document(self, data, passphrase): + if self._has_keys(): + raise KeyAlreadyExists("You tried to import a recovery document " + "but secret keys are already present.") + if passphrase and not self._gpg.is_encrypted_sym(data): + raise DocumentNotEncrypted("You provided a password but the " + "recovery document is not encrypted.") + if passphrase: + data = str(self._gpg.decrypt(data, passphrase=passphrase)) + data = json.loads(data) + self._user_email = data['user_email'] + self._gpg.import_keys(data['privkey']) + self._load_openpgp_keypair() + self._secret = data['secret'] + self._store_secret() + # TODO: make this work well with bootstrap. + self._load_keys() + __all__ = ['backends', 'util', 'server', 'shared_db'] diff --git a/src/leap/soledad/tests/test_encrypted.py b/src/leap/soledad/tests/test_encrypted.py index 0a4eb9cc..eb78fbe3 100644 --- a/src/leap/soledad/tests/test_encrypted.py +++ b/src/leap/soledad/tests/test_encrypted.py @@ -1,6 +1,11 @@ from leap.soledad.backends.leap_backend import LeapDocument from leap.soledad.tests import BaseSoledadTest from leap.soledad.tests import KEY_FINGERPRINT +from leap.soledad import ( + Soledad, + KeyAlreadyExists, +) +from leap.soledad.util import GPGWrapper try: import simplejson as json @@ -41,12 +46,13 @@ class EncryptedSyncTestCase(BaseSoledadTest): def test_export_recovery_document_raw(self): rd = self._soledad.export_recovery_document(None) self.assertEqual( - [ - self._soledad._user_email, - self._soledad._gpg.export_keys(self._soledad._fingerprint, - secret=True), - self._soledad._secret - ], + { + 'user_email': self._soledad._user_email, + 'privkey': self._soledad._gpg.export_keys( + self._soledad._fingerprint, + secret=True), + 'secret': self._soledad._secret + }, json.loads(rd), "Could not export raw recovery document." ) @@ -55,12 +61,13 @@ class EncryptedSyncTestCase(BaseSoledadTest): rd = self._soledad.export_recovery_document('123456') self.assertEqual(True, self._soledad._gpg.is_encrypted_sym(rd)) - data = [ - self._soledad._user_email, - self._soledad._gpg.export_keys(self._soledad._fingerprint, - secret=True), - self._soledad._secret, - ] + data = { + 'user_email': self._soledad._user_email, + 'privkey': self._soledad._gpg.export_keys( + self._soledad._fingerprint, + secret=True), + 'secret': self._soledad._secret, + } raw_data = json.loads(str(self._soledad._gpg.decrypt( rd, passphrase='123456'))) @@ -69,3 +76,60 @@ class EncryptedSyncTestCase(BaseSoledadTest): data, "Could not export raw recovery document." ) + + def test_import_recovery_document_raises_exception(self): + rd = self._soledad.export_recovery_document(None) + self.assertRaises(KeyAlreadyExists, + self._soledad.import_recovery_document, rd, None) + + def test_import_recovery_document_raw(self): + rd = self._soledad.export_recovery_document(None) + gnupg_home = self.gnupg_home = "%s/gnupg2" % self.tempdir + s = Soledad('anotheruser@leap.se', gnupg_home=gnupg_home, + initialize=False, prefix=self.tempdir) + s._init_dirs() + s._gpg = GPGWrapper(gnupghome=gnupg_home) + s.import_recovery_document(rd, None) + self.assertEqual(self._soledad._user_email, + s._user_email, 'Failed setting user email.') + self.assertEqual(self._soledad._secret, + s._secret, + 'Failed settinng secret for symmetric encryption.') + self.assertEqual(self._soledad._fingerprint, + s._fingerprint, + 'Failed settinng fingerprint.') + pk1 = self._soledad._gpg.export_keys( + self._soledad._fingerprint, + secret=True) + pk2 = s._gpg.export_keys(s._fingerprint, secret=True) + self.assertEqual( + pk1, + pk2, + 'Failed settinng private key.' + ) + + def test_import_recovery_document_crypt(self): + rd = self._soledad.export_recovery_document('123456') + gnupg_home = self.gnupg_home = "%s/gnupg2" % self.tempdir + s = Soledad('anotheruser@leap.se', gnupg_home=gnupg_home, + initialize=False, prefix=self.tempdir) + s._init_dirs() + s._gpg = GPGWrapper(gnupghome=gnupg_home) + s.import_recovery_document(rd, '123456') + self.assertEqual(self._soledad._user_email, + s._user_email, 'Failed setting user email.') + self.assertEqual(self._soledad._secret, + s._secret, + 'Failed settinng secret for symmetric encryption.') + self.assertEqual(self._soledad._fingerprint, + s._fingerprint, + 'Failed settinng fingerprint.') + pk1 = self._soledad._gpg.export_keys( + self._soledad._fingerprint, + secret=True) + pk2 = s._gpg.export_keys(s._fingerprint, secret=True) + self.assertEqual( + pk1, + pk2, + 'Failed settinng private key.' + ) |