diff options
| -rw-r--r-- | src/leap/soledad/__init__.py | 80 | ||||
| -rw-r--r-- | src/leap/soledad/tests/test_crypto.py | 6 | 
2 files changed, 40 insertions, 46 deletions
| diff --git a/src/leap/soledad/__init__.py b/src/leap/soledad/__init__.py index b0acb91a..6bb88094 100644 --- a/src/leap/soledad/__init__.py +++ b/src/leap/soledad/__init__.py @@ -199,7 +199,7 @@ class Soledad(object):          @param uuid: User's uuid.          @type uuid: str          @param passphrase: The passphrase for locking and unlocking encryption -            secrets for disk storage. +            secrets for local and remote storage.          @type passphrase: str          @param secrets_path: Path for storing encrypted key used for              symmetric encryption. @@ -294,7 +294,7 @@ class Soledad(object):                  logger.info(                      'Found cryptographic secrets in shared recovery '                      'database.') -                self.import_recovery_document(doc.content[self.SECRET_KEY]) +                self.import_recovery_document(doc.content)              else:                  # there are no secrets in server also, so generate a secret.                  logger.info( @@ -572,9 +572,7 @@ class Soledad(object):          if doc is None:              doc = LeapDocument(doc_id=self._uuid_hash())          # fill doc with encrypted secrets -        doc.content = { -            self.SECRET_KEY: self.export_recovery_document() -        } +        doc.content = self.export_recovery_document(include_uuid=False)          # upload secrets to server          events.signal(              events.events_pb2.SOLEDAD_UPLOADING_KEYS, self._uuid) @@ -590,9 +588,6 @@ class Soledad(object):      # Document storage, retrieval and sync.      # -    # TODO: refactor the following methods to somewhere out of here -    # (SoledadLocalDatabase, maybe?) -      def put_doc(self, doc):          """          Update a document in the local encrypted database. @@ -893,57 +888,56 @@ class Soledad(object):      token = property(_get_token, _set_token, doc='The authentication Token.')      # -    # Recovery document export and import methodsecret -    def export_recovery_document(self, passphrase=None): +    # Recovery document export and import methods +    # +    def export_recovery_document(self, include_uuid=True):          """ -        Exports username, provider, private key and key for symmetric -        encryption, optionally encrypted with a password. - -        The LEAP client gives the user the option to export a text file with a -        complete copy of their private keys and authorization information, -        either password protected or not. This "recovery document" can be -        printed or saved electronically as the user sees fit. If the user -        needs to recover their data, they can load this recover document into -        any LEAP client. The user can also type the recovery document in -        manually, although it will be long and very painful to copy manually. +        Export the storage secrets and (optionally) the uuid. -        Contents of recovery document: +        A recovery document has the following structure: -           - username -           - provider -           - private key. -           - key for symmetric encryption +            { +                self.STORAGE_SECRET_KEY: <secrets dict>, +                self.UUID_KEY: '<uuid>',  # (optional) +            } -        @param passphrase: an optional passphrase for encrypting the document -        @type passphrase: str +        @param include_uuid: Should the uuid be included? +        @type include_uuid: bool -        @return: the recovery document json serialization -        @rtype: str +        @return: The recovery document. +        @rtype: dict          """ -        data = json.dumps({ -            self.UUID_KEY: self._uuid, -            self.STORAGE_SECRETS_KEY: self._secrets, -        }) +        data = {self.STORAGE_SECRETS_KEY: self._secrets} +        if include_uuid: +            data[self.UUID_KEY] = self._uuid          return data      def import_recovery_document(self, data):          """ -        Import username, provider, private key and key for symmetric -        encryption from a recovery document. +        Import storage secrets for symmetric encryption and uuid (if present) +        from a recovery document. + +        A recovery document has the following structure: -        @param data: the recovery document json serialization -        @type data: str +            { +                self.STORAGE_SECRET_KEY: <secrets dict>, +                self.UUID_KEY: '<uuid>',  # (optional) +            } + +        @param data: The recovery document. +        @type data: dict          """ -        data = json.loads(data)          # include new secrets in our secret pool.          for secret_id, secret_data in data[self.STORAGE_SECRETS_KEY].items():              if secret_id not in self._secrets:                  self._secrets[secret_id] = secret_data -        self._store_secrets() -        # set uuid -        self._uuid = data[self.UUID_KEY] -        # choose first secret to use -        self._set_secret_id(data[self.STORAGE_SECRETS_KEY].items()[0][0]) +        self._store_secrets()  # save new secrets in local file +        # set uuid if present +        if self.UUID_KEY in data: +            self._uuid = data[self.UUID_KEY] +        # choose first secret to use is none is assigned +        if self._secret_id is None: +            self._set_secret_id(data[self.STORAGE_SECRETS_KEY].items()[0][0])      #      # Setters/getters diff --git a/src/leap/soledad/tests/test_crypto.py b/src/leap/soledad/tests/test_crypto.py index 7b8f756a..a61b931c 100644 --- a/src/leap/soledad/tests/test_crypto.py +++ b/src/leap/soledad/tests/test_crypto.py @@ -180,7 +180,7 @@ class EncryptedSyncTestCase(BaseSoledadTest):  class RecoveryDocumentTestCase(BaseSoledadTest):      def test_export_recovery_document_raw(self): -        rd = json.loads(self._soledad.export_recovery_document()) +        rd = self._soledad.export_recovery_document()          secret_id = rd[self._soledad.STORAGE_SECRETS_KEY].items()[0][0]          secret = rd[self._soledad.STORAGE_SECRETS_KEY][secret_id]          self.assertEqual(secret_id, self._soledad._secret_id) @@ -191,7 +191,7 @@ class RecoveryDocumentTestCase(BaseSoledadTest):          self.assertTrue(self._soledad.SECRET_KEY in secret)      def test_import_recovery_document(self): -        rd = self._soledad.export_recovery_document(None) +        rd = self._soledad.export_recovery_document()          s = self._soledad_instance(user='anotheruser@leap.se', prefix='/2')          s.import_recovery_document(rd)          s._set_secret_id(self._soledad._secret_id) @@ -238,7 +238,7 @@ class CryptoMethodsTestCase(BaseSoledadTest):      def test__has_secret(self): -        sol = self._soledad_instance(user='user@leap.se', prefix='/3') +        sol = self._soledad_instance(user='user@leap.se', prefix='/4')          self.assertTrue(sol._has_secret(), "Should have a secret at "                                             "this point")          # setting secret id to None should not interfere in the fact we have a | 
