diff options
Diffstat (limited to 'src/leap/soledad/crypto.py')
-rw-r--r-- | src/leap/soledad/crypto.py | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/src/leap/soledad/crypto.py b/src/leap/soledad/crypto.py deleted file mode 100644 index be83e4a2..00000000 --- a/src/leap/soledad/crypto.py +++ /dev/null @@ -1,207 +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/>. - - -""" -Cryptographic utilities for Soledad. -""" - - -import os -import binascii -import hmac -import hashlib - - -from Crypto.Cipher import AES -from Crypto.Util import Counter - - -from leap.soledad import ( - soledad_assert, - soledad_assert_type, -) - - -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 - - -class NoSymmetricSecret(Exception): - """ - Raised when trying to get a hashed passphrase. - """ - - -class SoledadCrypto(object): - """ - General cryptographic functionality. - """ - - MAC_KEY_LENGTH = 64 - - def __init__(self, soledad): - """ - Initialize the crypto object. - - @param soledad: A Soledad instance for key lookup. - @type soledad: leap.soledad.Soledad - """ - self._soledad = soledad - - def encrypt_sym(self, data, key, - method=EncryptionMethods.AES_256_CTR): - """ - Encrypt C{data} using a {password}. - - Currently, the only encryption method supported is AES-256 CTR mode. - - @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) - """ - soledad_assert_type(key, str) - - # AES-256 in CTR mode - if method == EncryptionMethods.AES_256_CTR: - soledad_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(self, data, key, - method=EncryptionMethods.AES_256_CTR, **kwargs): - """ - Decrypt data using symmetric secret. - - Currently, the only encryption method supported is AES-256 CTR mode. - - @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 - """ - soledad_assert_type(key, str) - - # AES-256 in CTR mode - if method == EncryptionMethods.AES_256_CTR: - # assert params - soledad_assert( - len(key) == 32, # 32 x 8 = 256 bits. - 'Wrong key size: %s (must be 256 bits long).' % len(key)) - soledad_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) - - def doc_passphrase(self, doc_id): - """ - Generate a passphrase for symmetric encryption of document's contents. - - The password is derived using HMAC having sha256 as underlying hash - function. The key used for HMAC are the first - C{soledad.REMOTE_STORAGE_SECRET_KENGTH} bytes of Soledad's storage - secret stripped from the first MAC_KEY_LENGTH characters. The HMAC - message is C{doc_id}. - - @param doc_id: The id of the document that will be encrypted using - this passphrase. - @type doc_id: str - - @return: The passphrase. - @rtype: str - - @raise NoSymmetricSecret: if no symmetric secret was supplied. - """ - if self.secret is None: - raise NoSymmetricSecret() - return hmac.new( - self.secret[ - self.MAC_KEY_LENGTH: - self._soledad.REMOTE_STORAGE_SECRET_LENGTH], - doc_id, - hashlib.sha256).digest() - - def doc_mac_key(self, doc_id): - """ - Generate a key for calculating a MAC for a document whose id is - C{doc_id}. - - The key is derived using HMAC having sha256 as underlying hash - function. The key used for HMAC is the first MAC_KEY_LENGTH characters - of Soledad's storage secret. The HMAC message is C{doc_id}. - - @param doc_id: The id of the document. - @type doc_id: str - - @return: The key. - @rtype: str - - @raise NoSymmetricSecret: if no symmetric secret was supplied. - """ - if self.secret is None: - raise NoSymmetricSecret() - return hmac.new( - self.secret[:self.MAC_KEY_LENGTH], - doc_id, - hashlib.sha256).digest() - - # - # secret setters/getters - # - - def _get_secret(self): - return self._soledad.storage_secret - - secret = property( - _get_secret, doc='The secret used for symmetric encryption') |