summaryrefslogtreecommitdiff
path: root/src/leap/soledad/crypto.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/soledad/crypto.py')
-rw-r--r--src/leap/soledad/crypto.py207
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')