summaryrefslogtreecommitdiff
path: root/src/leap
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap')
-rw-r--r--src/leap/soledad/backends/leap_backend.py85
-rw-r--r--src/leap/soledad/tests/__init__.py6
-rw-r--r--src/leap/soledad/tests/test_crypto.py34
-rw-r--r--src/leap/soledad/tests/test_leap_backend.py3
-rw-r--r--src/leap/soledad/tests/test_sqlcipher.py7
5 files changed, 63 insertions, 72 deletions
diff --git a/src/leap/soledad/backends/leap_backend.py b/src/leap/soledad/backends/leap_backend.py
index 2585379a..6f1f9546 100644
--- a/src/leap/soledad/backends/leap_backend.py
+++ b/src/leap/soledad/backends/leap_backend.py
@@ -48,7 +48,7 @@ class DocumentNotEncrypted(Exception):
pass
-class UnknownEncryptionSchemes(Exception):
+class UnknownEncryptionScheme(Exception):
"""
Raised when trying to decrypt from unknown encryption schemes.
"""
@@ -74,54 +74,56 @@ class EncryptionSchemes(object):
ENC_JSON_KEY = '_enc_json'
ENC_SCHEME_KEY = '_enc_scheme'
-MAC_KEY = '_mac'
-def encrypt_doc_json(crypto, doc_id, doc_json):
+def encrypt_doc(crypto, doc):
"""
- Return a valid JSON string containing the C{doc} content encrypted to
- a symmetric key and the encryption scheme.
+ Encrypt C{doc}'s content.
- The returned JSON string is the serialization of the following dictionary:
+ Return a valid JSON string representing the following:
{
- '_enc_json': encrypt_sym(doc_content),
- '_enc_scheme': 'symkey',
- '_mac': <mac> [Not implemented yet]
+ ENC_JSON_KEY: '<encrypted doc JSON string>',
+ ENC_SCHEME_KEY: 'symkey',
}
- @param crypto: A SoledadCryto instance to perform the encryption.
+ @param crypto: A SoledadCryto instance used to perform the encryption.
@type crypto: leap.soledad.crypto.SoledadCrypto
- @param doc_id: The unique id of the document.
- @type doc_id: str
- @param doc_json: The JSON serialization of the document's contents.
- @type doc_json: str
+ @param doc: The document with contents to be encrypted.
+ @type doc: LeapDocument
- @return: The JSON serialization representing the encrypted content.
+ @return: The JSON serialization of the dict representing the encrypted
+ content.
@rtype: str
"""
+ leap_assert(doc.is_tombstone() is False)
+ # encrypt content
ciphertext = crypto.encrypt_sym(
- doc_json,
- crypto.passphrase_hash(doc_id))
+ doc.get_json(),
+ crypto.passphrase_hash(doc.doc_id))
+ # verify it is indeed encrypted
if not crypto.is_encrypted_sym(ciphertext):
raise DocumentNotEncrypted('Failed encrypting document.')
+ # calculate hmac
+ #mac = hmac.new(doc_id,, doc_json,
+ # update doc's content with encrypted version
return json.dumps({
ENC_JSON_KEY: ciphertext,
ENC_SCHEME_KEY: EncryptionSchemes.SYMKEY,
})
-def decrypt_doc_json(crypto, doc_id, doc_json):
+def decrypt_doc(crypto, doc):
"""
- Return a JSON serialization of the decrypted content contained in
- C{encrypted_json}.
+ Decrypt C{doc}'s content.
+
+ Return the JSON string representation of the document's decrypted content.
- The C{encrypted_json} parameter is the JSON serialization of the
- following dictionary:
+ The content of the document should have the following structure:
{
- ENC_JSON_KEY: enc_blob,
- ENC_SCHEME_KEY: enc_scheme,
+ ENC_JSON_KEY: '<enc_blob>',
+ ENC_SCHEME_KEY: '<enc_scheme>',
}
C{enc_blob} is the encryption of the JSON serialization of the document's
@@ -130,22 +132,18 @@ def decrypt_doc_json(crypto, doc_id, doc_json):
@param crypto: A SoledadCryto instance to perform the encryption.
@type crypto: leap.soledad.crypto.SoledadCrypto
- @param doc_id: The unique id of the document.
- @type doc_id: str
- @param doc_json: The JSON serialization representation of the encrypted
- document's contents.
- @type doc_json: str
+ @param doc: The document to be decrypted.
+ @type doc: LeapDocument
@return: The JSON serialization of the decrypted content.
@rtype: str
"""
- leap_assert(isinstance(doc_id, str), 'Document id is not a string.')
- leap_assert(doc_id != '', 'Received empty document id.')
- leap_assert(isinstance(doc_json, str), 'Document JSON is not a string.')
- leap_assert(doc_json != '', 'Received empty document JSON.')
- content = json.loads(doc_json)
- ciphertext = content[ENC_JSON_KEY]
- enc_scheme = content[ENC_SCHEME_KEY]
+ leap_assert(doc.is_tombstone() is False)
+ leap_assert(ENC_JSON_KEY in doc.content)
+ leap_assert(ENC_SCHEME_KEY in doc.content)
+ # decrypt doc's content
+ ciphertext = doc.content[ENC_JSON_KEY]
+ enc_scheme = doc.content[ENC_SCHEME_KEY]
plainjson = None
if enc_scheme == EncryptionSchemes.SYMKEY:
if not crypto.is_encrypted_sym(ciphertext):
@@ -155,9 +153,9 @@ def decrypt_doc_json(crypto, doc_id, doc_json):
'symmetric key.')
plainjson = crypto.decrypt_sym(
ciphertext,
- crypto.passphrase_hash(doc_id))
+ crypto.passphrase_hash(doc.doc_id))
else:
- raise UnknownEncryptionSchemes(enc_scheme)
+ raise UnknownEncryptionScheme(enc_scheme)
return plainjson
@@ -354,9 +352,7 @@ class LeapSyncTarget(HTTPSyncTarget, TokenBasedAuth):
if doc.content and ENC_SCHEME_KEY in doc.content:
if doc.content[ENC_SCHEME_KEY] == \
EncryptionSchemes.SYMKEY:
- doc.set_json(
- decrypt_doc_json(
- self._crypto, doc.doc_id, entry['content']))
+ doc.set_json(decrypt_doc(self._crypto, doc))
#-------------------------------------------------------------
# end of symmetric decryption
#-------------------------------------------------------------
@@ -433,15 +429,14 @@ class LeapSyncTarget(HTTPSyncTarget, TokenBasedAuth):
#-------------------------------------------------------------
# symmetric encryption of document's contents
#-------------------------------------------------------------
- enc_json = doc.get_json()
+ doc_json = doc.get_json()
if not doc.is_tombstone():
- enc_json = encrypt_doc_json(
- self._crypto, doc.doc_id, doc.get_json())
+ doc_json = encrypt_doc(self._crypto, doc)
#-------------------------------------------------------------
# end of symmetric encryption
#-------------------------------------------------------------
size += prepare(id=doc.doc_id, rev=doc.rev,
- content=enc_json,
+ content=doc_json,
gen=gen, trans_id=trans_id)
entries.append('\r\n]')
size += len(entries[-1])
diff --git a/src/leap/soledad/tests/__init__.py b/src/leap/soledad/tests/__init__.py
index 6787aa9d..6ddc9832 100644
--- a/src/leap/soledad/tests/__init__.py
+++ b/src/leap/soledad/tests/__init__.py
@@ -10,7 +10,7 @@ from leap.soledad import Soledad
from leap.soledad.crypto import SoledadCrypto
from leap.soledad.backends.leap_backend import (
LeapDocument,
- decrypt_doc_json,
+ decrypt_doc,
ENC_SCHEME_KEY,
)
from leap.common.testing.basetest import BaseLeapTest
@@ -75,9 +75,7 @@ class BaseSoledadTest(BaseLeapTest):
has_conflicts=has_conflicts)
doc = db.get_doc(doc_id)
if ENC_SCHEME_KEY in doc.content:
- doc.set_json(
- decrypt_doc_json(
- self._soledad._crypto, doc.doc_id, doc.get_json()))
+ doc.set_json(decrypt_doc(self._soledad._crypto, doc))
self.assertEqual(exp_doc.doc_id, doc.doc_id)
self.assertEqual(exp_doc.rev, doc.rev)
self.assertEqual(exp_doc.has_conflicts, doc.has_conflicts)
diff --git a/src/leap/soledad/tests/test_crypto.py b/src/leap/soledad/tests/test_crypto.py
index 61c5f5b0..720e95fa 100644
--- a/src/leap/soledad/tests/test_crypto.py
+++ b/src/leap/soledad/tests/test_crypto.py
@@ -31,13 +31,12 @@ except ImportError:
from leap.soledad.backends.leap_backend import (
LeapDocument,
- encrypt_doc_json,
- decrypt_doc_json,
+ encrypt_doc,
+ decrypt_doc,
EncryptionSchemes,
LeapSyncTarget,
ENC_JSON_KEY,
ENC_SCHEME_KEY,
- MAC_KEY,
)
from leap.soledad.backends.couch import CouchDatabase
from leap.soledad import KeyAlreadyExists, Soledad
@@ -66,16 +65,21 @@ class EncryptedSyncTestCase(BaseSoledadTest):
"""
Test encrypting and decrypting documents.
"""
+ simpledoc = {'key': 'val'}
doc1 = LeapDocument(doc_id='id')
- doc1.content = {'key': 'val'}
- enc_json = encrypt_doc_json(
- self._soledad._crypto, doc1.doc_id, doc1.get_json())
- plain_json = decrypt_doc_json(
- self._soledad._crypto, doc1.doc_id, enc_json)
- doc2 = LeapDocument(doc_id=doc1.doc_id, json=plain_json)
- res1 = doc1.get_json()
- res2 = doc2.get_json()
- self.assertEqual(res1, res2, 'incorrect document encryption')
+ doc1.content = simpledoc
+ # encrypt doc
+ doc1.set_json(encrypt_doc(self._soledad._crypto, doc1))
+ # assert content is different and includes keys
+ self.assertNotEqual(simpledoc, doc1.content,
+ 'incorrect document encryption')
+ self.assertTrue(ENC_JSON_KEY in doc1.content)
+ self.assertTrue(ENC_SCHEME_KEY in doc1.content)
+ # decrypt doc
+ doc1.set_json(decrypt_doc(self._soledad._crypto, doc1))
+ self.assertEqual(
+ simpledoc, doc1.content, 'incorrect document encryption')
+
def test_encrypt_sym(self):
"""
@@ -84,9 +88,7 @@ class EncryptedSyncTestCase(BaseSoledadTest):
doc1 = LeapDocument()
doc1.content = {'key': 'val'}
enc_json = json.loads(
- encrypt_doc_json(
- self._soledad._crypto,
- doc1.doc_id, doc1.get_json()))[ENC_JSON_KEY]
+ encrypt_doc(self._soledad._crypto, doc1))[ENC_JSON_KEY]
self.assertEqual(
True,
self._soledad._crypto.is_encrypted_sym(enc_json),
@@ -161,7 +163,7 @@ class EncryptedSyncTestCase(BaseSoledadTest):
# # create and encrypt a doc to insert directly in couchdb
# doc = LeapDocument('doc-id')
# doc.set_json(
-# encrypt_doc_json(
+# encrypt_doc(
# self._soledad._crypto, 'doc-id', json.dumps(simple_doc)))
# db.put_doc(doc)
# # setup credentials for access to soledad server
diff --git a/src/leap/soledad/tests/test_leap_backend.py b/src/leap/soledad/tests/test_leap_backend.py
index dbebadb5..c0510373 100644
--- a/src/leap/soledad/tests/test_leap_backend.py
+++ b/src/leap/soledad/tests/test_leap_backend.py
@@ -286,8 +286,7 @@ class TestLeapParsingSyncStream(
"""
doc = leap_backend.LeapDocument('i')
doc.content = {}
- enc_json = leap_backend.encrypt_doc_json(
- self._soledad._crypto, doc.doc_id, doc.get_json())
+ enc_json = leap_backend.encrypt_doc(self._soledad._crypto, doc)
tgt = leap_backend.LeapSyncTarget(
"http://foo/foo", crypto=self._soledad._crypto)
diff --git a/src/leap/soledad/tests/test_sqlcipher.py b/src/leap/soledad/tests/test_sqlcipher.py
index c4282c0f..ea56edc9 100644
--- a/src/leap/soledad/tests/test_sqlcipher.py
+++ b/src/leap/soledad/tests/test_sqlcipher.py
@@ -52,10 +52,9 @@ from leap.soledad.backends.sqlcipher import open as u1db_open
from leap.soledad.backends.leap_backend import (
LeapDocument,
EncryptionSchemes,
- decrypt_doc_json,
+ decrypt_doc,
ENC_JSON_KEY,
ENC_SCHEME_KEY,
- MAC_KEY,
)
@@ -634,9 +633,7 @@ class SQLCipherDatabaseSyncTests(
self.sync(self.db2, db3)
doc3 = db3.get_doc('the-doc')
if ENC_SCHEME_KEY in doc3.content:
- doc3.set_json(
- decrypt_doc_json(
- self._soledad._crypto, doc3.doc_id, doc3.get_json()))
+ doc3.set_json(decrypt_doc(self._soledad._crypto, doc3))
self.assertEqual(doc4.get_json(), doc3.get_json())
self.assertFalse(doc3.has_conflicts)