diff options
author | Tomas Touceda <chiiph@leap.se> | 2013-06-21 11:52:33 -0300 |
---|---|---|
committer | Tomas Touceda <chiiph@leap.se> | 2013-06-21 11:52:33 -0300 |
commit | fbd0a8d86232e0e6d717d8c3fc5ace88e167eb74 (patch) | |
tree | 7a61b4624d4cdc84b34de44e824d2ee46ddcb21d | |
parent | c84521f7881dc7b4197f57300bfe0511aa47dac2 (diff) | |
parent | 7a60675f20c03a0afba931dcae6b48fa737efd57 (diff) |
Merge remote-tracking branch 'drebs/feature/2602-remove-soledad-strict-dependency-on-leap.common' into develop
-rw-r--r-- | changes/feature_move-symmetric-encryption-code-to-leap.soledad | 1 | ||||
-rw-r--r-- | src/leap/common/crypto.py | 114 | ||||
-rw-r--r-- | src/leap/common/tests/test_crypto.py | 88 |
3 files changed, 1 insertions, 202 deletions
diff --git a/changes/feature_move-symmetric-encryption-code-to-leap.soledad b/changes/feature_move-symmetric-encryption-code-to-leap.soledad new file mode 100644 index 0000000..1541362 --- /dev/null +++ b/changes/feature_move-symmetric-encryption-code-to-leap.soledad @@ -0,0 +1 @@ + o Move symmetric encryption code to leap.soledad. diff --git a/src/leap/common/crypto.py b/src/leap/common/crypto.py deleted file mode 100644 index 7f80a8a..0000000 --- a/src/leap/common/crypto.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -# crypto.py -# Copyright (C) 2013 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 binascii - -from Crypto.Cipher import AES -from Crypto.Util import Counter -from leap.common.check import leap_assert, leap_assert_type - -# -# encryption methods -# - -class EncryptionMethods(object): - """ - Representation of encryption methods that can be used. - """ - - AES_256_CTR = 'aes-256-ctr' - - -class UnknownEncryptionMethod(Exception): - """ - Raised when trying to encrypt/decrypt with unknown method. - """ - pass - - -# -# encrypt/decrypt functions -# - -# In the future, we might want to implement other encryption schemes and -# possibly factor out the actual encryption/decryption routines of the -# following functions to specific classes, while not changing the API. - -def encrypt_sym(data, key, method=EncryptionMethods.AES_256_CTR): - """ - Encrypt C{data} with C{key}, using C{method} encryption method. - - :param data: The data to be encrypted. - :type data: str - :param key: The key used to encrypt C{data} (must be 256 bits long). - :type key: str - :param method: The encryption method to use. - :type method: str - - :return: A tuple with the initial value and the encrypted data. - :rtype: (long, str) - """ - leap_assert_type(key, str) - - # AES-256 in CTR mode - if method == EncryptionMethods.AES_256_CTR: - leap_assert( - len(key) == 32, # 32 x 8 = 256 bits. - 'Wrong key size: %s bits (must be 256 bits long).' % (len(key)*8)) - iv = os.urandom(8) - ctr = Counter.new(64, prefix=iv) - cipher = AES.new(key=key, mode=AES.MODE_CTR, counter=ctr) - return binascii.b2a_base64(iv), cipher.encrypt(data) - - # raise if method is unknown - raise UnknownEncryptionMethod('Unkwnown method: %s' % method) - - -def decrypt_sym(data, key, method=EncryptionMethods.AES_256_CTR, **kwargs): - """ - Decrypt C{data} with C{key} using C{method} encryption method. - - :param data: The data to be decrypted. - :type data: str - :param key: The key used to decrypt C{data} (must be 256 bits long). - :type key: str - :param method: The encryption method to use. - :type method: str - :param kwargs: Other parameters specific to each encryption method. - :type kwargs: dict - - :return: The decrypted data. - :rtype: str - """ - leap_assert_type(key, str) - - # AES-256 in CTR mode - if method == EncryptionMethods.AES_256_CTR: - # assert params - leap_assert( - len(key) == 32, # 32 x 8 = 256 bits. - 'Wrong key size: %s (must be 256 bits long).' % len(key)) - leap_assert( - 'iv' in kwargs, - 'AES-256-CTR needs an initial value given as.') - ctr = Counter.new(64, prefix=binascii.a2b_base64(kwargs['iv'])) - cipher = AES.new(key=key, mode=AES.MODE_CTR, counter=ctr) - return cipher.decrypt(data) - - # raise if method is unknown - raise UnknownEncryptionMethod('Unkwnown method: %s' % method) diff --git a/src/leap/common/tests/test_crypto.py b/src/leap/common/tests/test_crypto.py deleted file mode 100644 index ae7dc71..0000000 --- a/src/leap/common/tests/test_crypto.py +++ /dev/null @@ -1,88 +0,0 @@ -## -*- coding: utf-8 -*- -# test_crypto.py -# Copyright (C) 2013 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/>. - - -""" -Tests for the crypto submodule. -""" - - -import os -import binascii - - -from leap.common.testing.basetest import BaseLeapTest -from leap.common import crypto -from Crypto import Random - - -class CryptoTestCase(BaseLeapTest): - - def setUp(self): - pass - - def tearDown(self): - pass - - def test_encrypt_decrypt_sym(self): - # generate 256-bit key - key = Random.new().read(32) - iv, cyphertext = crypto.encrypt_sym( - 'data', key, - method=crypto.EncryptionMethods.AES_256_CTR) - self.assertTrue(cyphertext is not None) - self.assertTrue(cyphertext != '') - self.assertTrue(cyphertext != 'data') - plaintext = crypto.decrypt_sym( - cyphertext, key, iv=iv, - method=crypto.EncryptionMethods.AES_256_CTR) - self.assertEqual('data', plaintext) - - def test_decrypt_with_wrong_iv_fails(self): - key = Random.new().read(32) - iv, cyphertext = crypto.encrypt_sym( - 'data', key, - method=crypto.EncryptionMethods.AES_256_CTR) - self.assertTrue(cyphertext is not None) - self.assertTrue(cyphertext != '') - self.assertTrue(cyphertext != 'data') - # get a different iv by changing the first byte - rawiv = binascii.a2b_base64(iv) - wrongiv = rawiv - while wrongiv == rawiv: - wrongiv = os.urandom(1) + rawiv[1:] - plaintext = crypto.decrypt_sym( - cyphertext, key, iv=binascii.b2a_base64(wrongiv), - method=crypto.EncryptionMethods.AES_256_CTR) - self.assertNotEqual('data', plaintext) - - def test_decrypt_with_wrong_key_fails(self): - key = Random.new().read(32) - iv, cyphertext = crypto.encrypt_sym( - 'data', key, - method=crypto.EncryptionMethods.AES_256_CTR) - self.assertTrue(cyphertext is not None) - self.assertTrue(cyphertext != '') - self.assertTrue(cyphertext != 'data') - wrongkey = Random.new().read(32) # 256-bits key - # ensure keys are different in case we are extremely lucky - while wrongkey == key: - wrongkey = Random.new().read(32) - plaintext = crypto.decrypt_sym( - cyphertext, wrongkey, iv=iv, - method=crypto.EncryptionMethods.AES_256_CTR) - self.assertNotEqual('data', plaintext) |