summaryrefslogtreecommitdiff
path: root/src/leap/soledad
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2013-05-21 20:33:48 -0300
committerdrebs <drebs@leap.se>2013-05-21 21:42:56 -0300
commit6c1b204938109de29fa53cc4e445b822f622826d (patch)
tree457528cd657c4201fd9e9ca2c4c73976e1c0a73e /src/leap/soledad
parentb86442d9ae23b91e81bcfa2d82ed90638f849578 (diff)
Improve _has_secret() logic and tests.
Diffstat (limited to 'src/leap/soledad')
-rw-r--r--src/leap/soledad/__init__.py39
-rw-r--r--src/leap/soledad/tests/__init__.py5
-rw-r--r--src/leap/soledad/tests/test_crypto.py43
-rw-r--r--src/leap/soledad/tests/test_soledad.py15
4 files changed, 80 insertions, 22 deletions
diff --git a/src/leap/soledad/__init__.py b/src/leap/soledad/__init__.py
index ab8c03b4..b0acb91a 100644
--- a/src/leap/soledad/__init__.py
+++ b/src/leap/soledad/__init__.py
@@ -131,6 +131,11 @@ class Soledad(object):
finished synchronizing with remote replica.
"""
+ LOCAL_DATABASE_FILE_NAME = 'soledad.u1db'
+ """
+ The name of the local SQLCipher U1DB database file.
+ """
+
STORAGE_SECRETS_FILE_NAME = "soledad.json"
"""
The name of the file where the storage secrets will be stored.
@@ -187,7 +192,7 @@ class Soledad(object):
"""
def __init__(self, uuid, passphrase, secrets_path, local_db_path,
- server_url, cert_file, auth_token=None):
+ server_url, cert_file, auth_token=None, secret_id=None):
"""
Initialize configuration, cryptographic keys and dbs.
@@ -216,7 +221,7 @@ class Soledad(object):
self._passphrase = passphrase
# init crypto variables
self._secrets = {}
- self._secret_id = None
+ self._secret_id = secret_id
# init config (possibly with default values)
self._init_config(secrets_path, local_db_path, server_url)
self._set_token(auth_token)
@@ -239,7 +244,7 @@ class Soledad(object):
self._local_db_path = local_db_path
if self._local_db_path is None:
self._local_db_path = os.path.join(
- self.DEFAULT_PREFIX, 'soledad.u1db')
+ self.DEFAULT_PREFIX, self.LOCAL_DATABASE_FILE_NAME)
# initialize server_url
self._server_url = server_url
leap_assert(
@@ -399,9 +404,6 @@ class Soledad(object):
}
}
}
-
- @raise leap.common.keymanager.errors.DecryptionFailed: Raised if could
- not decrypt the secret with the given passphrase.
"""
# does the file exist in disk?
if not os.path.isfile(self._secrets_path):
@@ -422,18 +424,16 @@ class Soledad(object):
@return: Whether there's a storage secret for symmetric encryption.
@rtype: bool
"""
- # if the secret is already loaded, return true
- if self._secret_id is not None and self._secret_id in self._secrets:
- return True
- # try to load from disk
+ if self._secret_id is None or self._secret_id not in self._secrets:
+ try:
+ self._load_secrets() # try to load from disk
+ except IOError, e:
+ logger.error('IOError: %s' % str(e))
try:
- self._load_secrets()
+ self._get_storage_secret()
return True
- except DecryptionFailed:
- logger.error('Could not decrypt storage secret.')
- except IOError, e:
- logger.error('IOError: %s' % str(e))
- return False
+ except:
+ return False
def _gen_secret(self):
"""
@@ -954,6 +954,13 @@ class Soledad(object):
uuid = property(_get_uuid, doc='The user uuid.')
+ def _get_secret_id(self):
+ return self._secret_id
+
+ secret_id = property(
+ _get_secret_id,
+ doc='The active secret id.')
+
def _get_secrets_path(self):
return self._secrets_path
diff --git a/src/leap/soledad/tests/__init__.py b/src/leap/soledad/tests/__init__.py
index 79ee69c4..00de687b 100644
--- a/src/leap/soledad/tests/__init__.py
+++ b/src/leap/soledad/tests/__init__.py
@@ -48,7 +48,7 @@ class BaseSoledadTest(BaseLeapTest):
prefix='',
secrets_path=Soledad.STORAGE_SECRETS_FILE_NAME,
local_db_path='/soledad.u1db', server_url='',
- cert_file=None):
+ cert_file=None, secret_id=None):
def _put_doc_side_effect(doc):
self._doc_put = doc
@@ -68,7 +68,8 @@ class BaseSoledadTest(BaseLeapTest):
secrets_path=self.tempdir+prefix+secrets_path,
local_db_path=self.tempdir+prefix+local_db_path,
server_url=server_url, # Soledad will fail if not given an url.
- cert_file=cert_file)
+ cert_file=cert_file,
+ secret_id=secret_id)
def assertGetEncryptedDoc(
self, db, doc_id, doc_rev, content, has_conflicts):
diff --git a/src/leap/soledad/tests/test_crypto.py b/src/leap/soledad/tests/test_crypto.py
index 4c57e023..7b8f756a 100644
--- a/src/leap/soledad/tests/test_crypto.py
+++ b/src/leap/soledad/tests/test_crypto.py
@@ -27,6 +27,7 @@ try:
import simplejson as json
except ImportError:
import json # noqa
+import hashlib
from leap.soledad.backends.leap_backend import (
@@ -204,9 +205,51 @@ class RecoveryDocumentTestCase(BaseSoledadTest):
class CryptoMethodsTestCase(BaseSoledadTest):
def test__gen_secret(self):
+ # instantiate and save secret_id
+ sol = self._soledad_instance(user='user@leap.se')
+ self.assertTrue(len(sol._secrets) == 1)
+ secret_id_1 = sol.secret_id
+ # assert id is hash of secret
+ self.assertTrue(
+ secret_id_1 == hashlib.sha256(sol.storage_secret).hexdigest())
+ # generate new secret
+ secret_id_2 = sol._gen_secret()
+ self.assertTrue(secret_id_1 != secret_id_2)
+ # re-instantiate
+ sol = self._soledad_instance(
+ user='user@leap.se',
+ secret_id=secret_id_1)
+ # assert ids are valid
+ self.assertTrue(len(sol._secrets) == 2)
+ self.assertTrue(secret_id_1 in sol._secrets)
+ self.assertTrue(secret_id_2 in sol._secrets)
+ # assert format of secret 1
+ self.assertTrue(sol.storage_secret is not None)
+ self.assertIsInstance(sol.storage_secret, str)
+ self.assertTrue(len(sol.storage_secret) == sol.GENERATED_SECRET_LENGTH)
+ # assert format of secret 2
+ sol._set_secret_id(secret_id_2)
+ self.assertTrue(sol.storage_secret is not None)
+ self.assertIsInstance(sol.storage_secret, str)
+ self.assertTrue(len(sol.storage_secret) == sol.GENERATED_SECRET_LENGTH)
+ # assert id is hash of new secret
+ self.assertTrue(
+ secret_id_2 == hashlib.sha256(sol.storage_secret).hexdigest())
+
+
+ def test__has_secret(self):
sol = self._soledad_instance(user='user@leap.se', prefix='/3')
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
+ # secret.
+ sol._set_secret_id(None)
+ self.assertTrue(sol._has_secret(), "Should have a secret at "
+ "this point")
+ # but not being able to decrypt correctly should
+ sol._secrets[sol.secret_id][sol.SECRET_KEY] = None
+ self.assertFalse(sol._has_secret())
+
class MacAuthTestCase(BaseSoledadTest):
diff --git a/src/leap/soledad/tests/test_soledad.py b/src/leap/soledad/tests/test_soledad.py
index 6a4261c0..45cd7eb2 100644
--- a/src/leap/soledad/tests/test_soledad.py
+++ b/src/leap/soledad/tests/test_soledad.py
@@ -64,14 +64,21 @@ class AuxMethodsTestCase(BaseSoledadTest):
"""
Test if configuration defaults point to the correct place.
"""
- sol = Soledad(
- 'leap@leap.se', passphrase='123',
- secrets_path=None, local_db_path=None,
- server_url='', cert_file=None) # otherwise Soledad will fail.
+
+ class SoledadMock(Soledad):
+
+ def __init__(self):
+ pass
+
+ # instantiate without initializing so we just test _init_config()
+ sol = SoledadMock()
+ Soledad._init_config(sol, None, None, '')
+ # assert value of secrets_path
self.assertEquals(
os.path.join(
sol.DEFAULT_PREFIX, Soledad.STORAGE_SECRETS_FILE_NAME),
sol.secrets_path)
+ # assert value of local_db_path
self.assertEquals(
os.path.join(sol.DEFAULT_PREFIX, 'soledad.u1db'),
sol.local_db_path)