diff options
| author | drebs <drebs@leap.se> | 2013-03-11 13:14:14 -0300 | 
|---|---|---|
| committer | drebs <drebs@leap.se> | 2013-03-11 13:14:14 -0300 | 
| commit | ab1e1c8862b70d47c7e5f10267639ef71b3bc536 (patch) | |
| tree | 972b626c405cc7a40c4501a8cde3e6199da0d31d | |
| parent | aa48da25c13c1565c72bf5f0cb93b49fbc27c29a (diff) | |
Add import recovery document.
| -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.' +        ) | 
