diff options
Diffstat (limited to 'src/leap/soledad')
-rw-r--r-- | src/leap/soledad/backends/leap_backend.py | 85 | ||||
-rw-r--r-- | src/leap/soledad/tests/__init__.py | 6 | ||||
-rw-r--r-- | src/leap/soledad/tests/test_crypto.py | 34 | ||||
-rw-r--r-- | src/leap/soledad/tests/test_leap_backend.py | 3 | ||||
-rw-r--r-- | src/leap/soledad/tests/test_sqlcipher.py | 7 |
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) |