From ce0d421e41cfb75a3957541d6c88fcd7b26e8cd6 Mon Sep 17 00:00:00 2001 From: drebs Date: Fri, 28 Nov 2014 11:50:15 -0200 Subject: Add encryption scheme, method and iv to symmetrically encrypted document MAC (#6400). --- common/src/leap/soledad/common/crypto.py | 8 +-- common/src/leap/soledad/common/tests/__init__.py | 2 +- .../src/leap/soledad/common/tests/test_crypto.py | 52 ++++++++++-------- .../src/leap/soledad/common/tests/test_soledad.py | 62 +++++++++++----------- 4 files changed, 65 insertions(+), 59 deletions(-) (limited to 'common/src') diff --git a/common/src/leap/soledad/common/crypto.py b/common/src/leap/soledad/common/crypto.py index ab05999b..b4f3234f 100644 --- a/common/src/leap/soledad/common/crypto.py +++ b/common/src/leap/soledad/common/crypto.py @@ -35,7 +35,7 @@ class EncryptionSchemes(object): PUBKEY = 'pubkey' -class UnknownEncryptionScheme(Exception): +class UnknownEncryptionSchemeError(Exception): """ Raised when trying to decrypt from unknown encryption schemes. """ @@ -51,7 +51,7 @@ class EncryptionMethods(object): XSALSA20 = 'xsalsa20' -class UnknownEncryptionMethod(Exception): +class UnknownEncryptionMethodError(Exception): """ Raised when trying to encrypt/decrypt with unknown method. """ @@ -66,7 +66,7 @@ class MacMethods(object): HMAC = 'hmac' -class UnknownMacMethod(Exception): +class UnknownMacMethodError(Exception): """ Raised when trying to authenticate document's content with unknown MAC mehtod. @@ -74,7 +74,7 @@ class UnknownMacMethod(Exception): pass -class WrongMac(Exception): +class WrongMacError(Exception): """ Raised when failing to authenticate document's contents based on MAC. """ diff --git a/common/src/leap/soledad/common/tests/__init__.py b/common/src/leap/soledad/common/tests/__init__.py index 3081683b..0ab159fd 100644 --- a/common/src/leap/soledad/common/tests/__init__.py +++ b/common/src/leap/soledad/common/tests/__init__.py @@ -27,9 +27,9 @@ from mock import Mock from leap.soledad.common.document import SoledadDocument +from leap.soledad.common.crypto import ENC_SCHEME_KEY from leap.soledad.client import Soledad from leap.soledad.client.crypto import decrypt_doc_dict -from leap.soledad.client.crypto import ENC_SCHEME_KEY from leap.common.testing.basetest import BaseLeapTest diff --git a/common/src/leap/soledad/common/tests/test_crypto.py b/common/src/leap/soledad/common/tests/test_crypto.py index 0302a268..f5fb4b7a 100644 --- a/common/src/leap/soledad/common/tests/test_crypto.py +++ b/common/src/leap/soledad/common/tests/test_crypto.py @@ -24,7 +24,13 @@ import binascii from leap.soledad.client import crypto from leap.soledad.common.document import SoledadDocument from leap.soledad.common.tests import BaseSoledadTest -from leap.soledad.common.crypto import WrongMac, UnknownMacMethod +from leap.soledad.common.crypto import WrongMacError +from leap.soledad.common.crypto import UnknownMacMethodError +from leap.soledad.common.crypto import EncryptionMethods +from leap.soledad.common.crypto import ENC_JSON_KEY +from leap.soledad.common.crypto import ENC_SCHEME_KEY +from leap.soledad.common.crypto import MAC_KEY +from leap.soledad.common.crypto import MAC_METHOD_KEY class EncryptedSyncTestCase(BaseSoledadTest): @@ -46,8 +52,8 @@ class EncryptedSyncTestCase(BaseSoledadTest): self.assertNotEqual( simpledoc, doc1.content, 'incorrect document encryption') - self.assertTrue(crypto.ENC_JSON_KEY in doc1.content) - self.assertTrue(crypto.ENC_SCHEME_KEY in doc1.content) + self.assertTrue(ENC_JSON_KEY in doc1.content) + self.assertTrue(ENC_SCHEME_KEY in doc1.content) # decrypt doc doc1.set_json(crypto.decrypt_doc(self._soledad._crypto, doc1)) self.assertEqual( @@ -149,13 +155,13 @@ class MacAuthTestCase(BaseSoledadTest): doc.content = simpledoc # encrypt doc doc.set_json(crypto.encrypt_doc(self._soledad._crypto, doc)) - self.assertTrue(crypto.MAC_KEY in doc.content) - self.assertTrue(crypto.MAC_METHOD_KEY in doc.content) + self.assertTrue(MAC_KEY in doc.content) + self.assertTrue(MAC_METHOD_KEY in doc.content) # mess with MAC - doc.content[crypto.MAC_KEY] = '1234567890ABCDEF' + doc.content[MAC_KEY] = '1234567890ABCDEF' # try to decrypt doc self.assertRaises( - WrongMac, + WrongMacError, crypto.decrypt_doc, self._soledad._crypto, doc) def test_decrypt_with_unknown_mac_method_raises(self): @@ -167,13 +173,13 @@ class MacAuthTestCase(BaseSoledadTest): doc.content = simpledoc # encrypt doc doc.set_json(crypto.encrypt_doc(self._soledad._crypto, doc)) - self.assertTrue(crypto.MAC_KEY in doc.content) - self.assertTrue(crypto.MAC_METHOD_KEY in doc.content) + self.assertTrue(MAC_KEY in doc.content) + self.assertTrue(MAC_METHOD_KEY in doc.content) # mess with MAC method - doc.content[crypto.MAC_METHOD_KEY] = 'mymac' + doc.content[MAC_METHOD_KEY] = 'mymac' # try to decrypt doc self.assertRaises( - UnknownMacMethod, + UnknownMacMethodError, crypto.decrypt_doc, self._soledad._crypto, doc) @@ -184,20 +190,20 @@ class SoledadCryptoAESTestCase(BaseSoledadTest): key = os.urandom(32) iv, cyphertext = self._soledad._crypto.encrypt_sym( 'data', key, - method=crypto.EncryptionMethods.AES_256_CTR) + method=EncryptionMethods.AES_256_CTR) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') plaintext = self._soledad._crypto.decrypt_sym( cyphertext, key, iv=iv, - method=crypto.EncryptionMethods.AES_256_CTR) + method=EncryptionMethods.AES_256_CTR) self.assertEqual('data', plaintext) def test_decrypt_with_wrong_iv_fails(self): key = os.urandom(32) iv, cyphertext = self._soledad._crypto.encrypt_sym( 'data', key, - method=crypto.EncryptionMethods.AES_256_CTR) + method=EncryptionMethods.AES_256_CTR) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') @@ -208,14 +214,14 @@ class SoledadCryptoAESTestCase(BaseSoledadTest): wrongiv = os.urandom(1) + rawiv[1:] plaintext = self._soledad._crypto.decrypt_sym( cyphertext, key, iv=binascii.b2a_base64(wrongiv), - method=crypto.EncryptionMethods.AES_256_CTR) + method=EncryptionMethods.AES_256_CTR) self.assertNotEqual('data', plaintext) def test_decrypt_with_wrong_key_fails(self): key = os.urandom(32) iv, cyphertext = self._soledad._crypto.encrypt_sym( 'data', key, - method=crypto.EncryptionMethods.AES_256_CTR) + method=EncryptionMethods.AES_256_CTR) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') @@ -225,7 +231,7 @@ class SoledadCryptoAESTestCase(BaseSoledadTest): wrongkey = os.urandom(32) plaintext = self._soledad._crypto.decrypt_sym( cyphertext, wrongkey, iv=iv, - method=crypto.EncryptionMethods.AES_256_CTR) + method=EncryptionMethods.AES_256_CTR) self.assertNotEqual('data', plaintext) @@ -236,20 +242,20 @@ class SoledadCryptoXSalsa20TestCase(BaseSoledadTest): key = os.urandom(32) iv, cyphertext = self._soledad._crypto.encrypt_sym( 'data', key, - method=crypto.EncryptionMethods.XSALSA20) + method=EncryptionMethods.XSALSA20) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') plaintext = self._soledad._crypto.decrypt_sym( cyphertext, key, iv=iv, - method=crypto.EncryptionMethods.XSALSA20) + method=EncryptionMethods.XSALSA20) self.assertEqual('data', plaintext) def test_decrypt_with_wrong_iv_fails(self): key = os.urandom(32) iv, cyphertext = self._soledad._crypto.encrypt_sym( 'data', key, - method=crypto.EncryptionMethods.XSALSA20) + method=EncryptionMethods.XSALSA20) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') @@ -260,14 +266,14 @@ class SoledadCryptoXSalsa20TestCase(BaseSoledadTest): wrongiv = os.urandom(1) + rawiv[1:] plaintext = self._soledad._crypto.decrypt_sym( cyphertext, key, iv=binascii.b2a_base64(wrongiv), - method=crypto.EncryptionMethods.XSALSA20) + method=EncryptionMethods.XSALSA20) self.assertNotEqual('data', plaintext) def test_decrypt_with_wrong_key_fails(self): key = os.urandom(32) iv, cyphertext = self._soledad._crypto.encrypt_sym( 'data', key, - method=crypto.EncryptionMethods.XSALSA20) + method=EncryptionMethods.XSALSA20) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') @@ -277,5 +283,5 @@ class SoledadCryptoXSalsa20TestCase(BaseSoledadTest): wrongkey = os.urandom(32) plaintext = self._soledad._crypto.decrypt_sym( cyphertext, wrongkey, iv=iv, - method=crypto.EncryptionMethods.XSALSA20) + method=EncryptionMethods.XSALSA20) self.assertNotEqual('data', plaintext) diff --git a/common/src/leap/soledad/common/tests/test_soledad.py b/common/src/leap/soledad/common/tests/test_soledad.py index 12bfbc3e..31c02fc4 100644 --- a/common/src/leap/soledad/common/tests/test_soledad.py +++ b/common/src/leap/soledad/common/tests/test_soledad.py @@ -28,7 +28,7 @@ from leap.soledad.common.tests import ( ) from leap import soledad from leap.soledad.common.document import SoledadDocument -from leap.soledad.common.crypto import WrongMac +from leap.soledad.common.crypto import WrongMacError from leap.soledad.client import Soledad from leap.soledad.client.sqlcipher import SQLCipherDatabase from leap.soledad.client.secrets import PassphraseTooShort @@ -117,7 +117,7 @@ class AuxMethodsTestCase(BaseSoledadTest): sol.close() self.assertRaises( - WrongMac, + WrongMacError, self._soledad_instance, 'leap@leap.se', passphrase=u'123', prefix=self.rand_prefix) @@ -208,7 +208,7 @@ class SoledadSignalingTestCase(BaseSoledadTest): def setUp(self): # mock signaling soledad.client.signal = Mock() - soledad.client.secrets.signal = Mock() + soledad.client.secrets.events.signal = Mock() # run parent's setUp BaseSoledadTest.setUp(self) @@ -230,57 +230,57 @@ class SoledadSignalingTestCase(BaseSoledadTest): - downloading keys / done downloading keys. - uploading keys / done uploading keys. """ - soledad.client.secrets.signal.reset_mock() + soledad.client.secrets.events.signal.reset_mock() # get a fresh instance so it emits all bootstrap signals sol = self._soledad_instance( secrets_path='alternative_stage3.json', local_db_path='alternative_stage3.u1db') # reverse call order so we can verify in the order the signals were # expected - soledad.client.secrets.signal.mock_calls.reverse() - soledad.client.secrets.signal.call_args = \ - soledad.client.secrets.signal.call_args_list[0] - soledad.client.secrets.signal.call_args_list.reverse() + soledad.client.secrets.events.signal.mock_calls.reverse() + soledad.client.secrets.events.signal.call_args = \ + soledad.client.secrets.events.signal.call_args_list[0] + soledad.client.secrets.events.signal.call_args_list.reverse() # downloading keys signals - soledad.client.secrets.signal.assert_called_with( + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DOWNLOADING_KEYS, ADDRESS, ) - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DONE_DOWNLOADING_KEYS, ADDRESS, ) # creating keys signals - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_CREATING_KEYS, ADDRESS, ) - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DONE_CREATING_KEYS, ADDRESS, ) # downloading once more (inside _put_keys_in_shared_db) - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DOWNLOADING_KEYS, ADDRESS, ) - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DONE_DOWNLOADING_KEYS, ADDRESS, ) # uploading keys signals - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_UPLOADING_KEYS, ADDRESS, ) - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DONE_UPLOADING_KEYS, ADDRESS, ) @@ -312,7 +312,7 @@ class SoledadSignalingTestCase(BaseSoledadTest): sol.close() # reset mock - soledad.client.secrets.signal.reset_mock() + soledad.client.secrets.events.signal.reset_mock() # get a fresh instance so it emits all bootstrap signals sol = self._soledad_instance( secrets_path='alternative_stage2.json', @@ -320,17 +320,17 @@ class SoledadSignalingTestCase(BaseSoledadTest): shared_db_class=Stage2MockSharedDB) # reverse call order so we can verify in the order the signals were # expected - soledad.client.secrets.signal.mock_calls.reverse() - soledad.client.secrets.signal.call_args = \ - soledad.client.secrets.signal.call_args_list[0] - soledad.client.secrets.signal.call_args_list.reverse() + soledad.client.secrets.events.signal.mock_calls.reverse() + soledad.client.secrets.events.signal.call_args = \ + soledad.client.secrets.events.signal.call_args_list[0] + soledad.client.secrets.events.signal.call_args_list.reverse() # assert download keys signals - soledad.client.secrets.signal.assert_called_with( + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DOWNLOADING_KEYS, ADDRESS, ) - self._pop_mock_call(soledad.client.secrets.signal) - soledad.client.secrets.signal.assert_called_with( + self._pop_mock_call(soledad.client.secrets.events.signal) + soledad.client.secrets.events.signal.assert_called_with( proto.SOLEDAD_DONE_DOWNLOADING_KEYS, ADDRESS, ) -- cgit v1.2.3