summaryrefslogtreecommitdiff
path: root/client/src/leap/soledad/client/_secrets/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/leap/soledad/client/_secrets/__init__.py')
-rw-r--r--client/src/leap/soledad/client/_secrets/__init__.py129
1 files changed, 0 insertions, 129 deletions
diff --git a/client/src/leap/soledad/client/_secrets/__init__.py b/client/src/leap/soledad/client/_secrets/__init__.py
deleted file mode 100644
index b6c81cda..00000000
--- a/client/src/leap/soledad/client/_secrets/__init__.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# -*- coding: utf-8 -*-
-# _secrets/__init__.py
-# Copyright (C) 2016 LEAP
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-import scrypt
-
-from leap.soledad.common.log import getLogger
-
-from leap.soledad.client._secrets.storage import SecretsStorage
-from leap.soledad.client._secrets.crypto import SecretsCrypto
-from leap.soledad.client._secrets.util import emit, UserDataMixin
-
-
-logger = getLogger(__name__)
-
-
-class Secrets(UserDataMixin):
-
- lengths = {
- 'remote_secret': 512, # remote_secret is used to encrypt remote data.
- 'local_salt': 64, # local_salt is used in conjunction with
- 'local_secret': 448, # local_secret to derive a local_key for storage
- }
-
- def __init__(self, soledad):
- self._soledad = soledad
- self._secrets = {}
- self.crypto = SecretsCrypto(soledad)
- self.storage = SecretsStorage(soledad)
- self._bootstrap()
-
- #
- # bootstrap
- #
-
- def _bootstrap(self):
-
- # attempt to load secrets from local storage
- encrypted = self.storage.load_local()
- if encrypted:
- self._secrets = self.crypto.decrypt(encrypted)
- # maybe update the format of storage of local secret.
- if encrypted['version'] < self.crypto.VERSION:
- self.store_secrets()
- return
-
- # no secret was found in local storage, so this is a first run of
- # soledad for this user in this device. It is mandatory that we check
- # if there's a secret stored in server.
- encrypted = self.storage.load_remote()
- if encrypted:
- self._secrets = self.crypto.decrypt(encrypted)
- self.store_secrets()
- return
-
- # we have *not* found a secret neither in local nor in remote storage,
- # so we have to generate a new one, and then store it.
- self._secrets = self._generate()
- self.store_secrets()
-
- #
- # generation
- #
-
- @emit('creating')
- def _generate(self):
- logger.info("generating new set of secrets...")
- secrets = {}
- for name, length in self.lengths.iteritems():
- secret = os.urandom(length)
- secrets[name] = secret
- logger.info("new set of secrets successfully generated")
- return secrets
-
- #
- # crypto
- #
-
- def store_secrets(self):
- # TODO: we have to improve the logic here, as we want to make sure that
- # whatever is stored locally should only be used after remote storage
- # is successful. Otherwise, this soledad could start encrypting with a
- # secret while another soledad in another device could start encrypting
- # with another secret, which would lead to decryption failures during
- # sync.
- encrypted = self.crypto.encrypt(self._secrets)
- self.storage.save_local(encrypted)
- self.storage.save_remote(encrypted)
-
- #
- # secrets
- #
-
- @property
- def remote_secret(self):
- return self._secrets.get('remote_secret')
-
- @property
- def local_salt(self):
- return self._secrets.get('local_salt')
-
- @property
- def local_secret(self):
- return self._secrets.get('local_secret')
-
- @property
- def local_key(self):
- # local storage key is scrypt-derived from `local_secret` and
- # `local_salt` above
- secret = scrypt.hash(
- password=self.local_secret,
- salt=self.local_salt,
- buflen=32, # we need a key with 256 bits (32 bytes)
- )
- return secret