diff options
Diffstat (limited to 'client/src/leap/soledad/client/_secrets/__init__.py')
-rw-r--r-- | client/src/leap/soledad/client/_secrets/__init__.py | 129 |
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 |