summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kanakarakis <ivan.kanak@gmail.com>2018-07-17 01:20:36 +0300
committerIvan Kanakarakis <ivan.kanak@gmail.com>2018-08-02 15:06:10 +0300
commita7763cdee88b39fb812df66e63c16063c468f006 (patch)
treeca39e58ebf15a8e86dc13c2e6f6274d3e45b3a5b
parent912a1b34402ca26c2fb86b57aeebbdc7685efa2d (diff)
downloadpysaml2-a7763cdee88b39fb812df66e63c16063c468f006.tar.gz
Deprecate AESCipher and aes.py module
aes.py is deprecated and will be completely removed in a following release. Users should switch to saml2.cryptography.symmetric instead. Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
-rw-r--r--src/saml2/aes.py111
-rw-r--r--src/saml2/cryptography/symmetric.py124
2 files changed, 136 insertions, 99 deletions
diff --git a/src/saml2/aes.py b/src/saml2/aes.py
index 54808e67..d58e34e5 100644
--- a/src/saml2/aes.py
+++ b/src/saml2/aes.py
@@ -1,105 +1,18 @@
-import os
-from base64 import b64decode
-from base64 import b64encode
+import warnings as _warnings
-from cryptography.hazmat.backends import default_backend
-from cryptography.hazmat.primitives.ciphers import Cipher
-from cryptography.hazmat.primitives.ciphers import algorithms
-from cryptography.hazmat.primitives.ciphers import modes
+from saml2.cryptography.symmetric import AESCipher as _AESCipher
-POSTFIX_MODE = {
- 'cbc': modes.CBC,
- 'cfb': modes.CFB,
-}
+_deprecation_msg = (
+ '{name} {type} is deprecated. '
+ 'It will be removed in the next version. '
+ 'Use saml2.cryptography.symmetric instead.'
+).format(name=__name__, type='module')
-AES_BLOCK_SIZE = int(algorithms.AES.block_size / 8)
+_warnings.simplefilter('default')
+_warnings.warn(_deprecation_msg, DeprecationWarning)
-class AESCipher(object):
- def __init__(self, key):
- """
- :param key: The encryption key
- :return: AESCipher instance
- """
- self.key = key
-
- def build_cipher(self, alg='aes_128_cbc'):
- """
- :param alg: cipher algorithm
- :return: A Cipher instance
- """
- typ, bits, cmode = alg.lower().split('_')
- bits = int(bits)
- iv = os.urandom(AES_BLOCK_SIZE)
-
- if len(iv) != AES_BLOCK_SIZE:
- raise Exception('Wrong iv size: {}'.format(len(iv)))
-
- if bits not in algorithms.AES.key_sizes:
- raise Exception('Unsupported key length: {}'.format(bits))
-
- if len(self.key) != bits / 8:
- raise Exception('Wrong Key length: {}'.format(len(self.key)))
-
- try:
- mode = POSTFIX_MODE[cmode]
- except KeyError:
- raise Exception('Unsupported chaining mode: {}'.format(cmode))
-
- cipher = Cipher(
- algorithms.AES(self.key),
- mode(iv),
- backend=default_backend())
-
- return cipher, iv
-
- def encrypt(self, msg, alg='aes_128_cbc', padding='PKCS#7', b64enc=True,
- block_size=AES_BLOCK_SIZE):
- """
- :param key: The encryption key
- :param msg: Message to be encrypted
- :param padding: Which padding that should be used
- :param b64enc: Whether the result should be base64encoded
- :param block_size: If PKCS#7 padding which block size to use
- :return: The encrypted message
- """
-
- if padding == 'PKCS#7':
- _block_size = block_size
- elif padding == 'PKCS#5':
- _block_size = 8
- else:
- _block_size = 0
-
- if _block_size:
- plen = _block_size - (len(msg) % _block_size)
- c = chr(plen).encode()
- msg += c * plen
-
- cipher, iv = self.build_cipher(alg)
- encryptor = cipher.encryptor()
- cmsg = iv + encryptor.update(msg) + encryptor.finalize()
-
- if b64enc:
- enc_msg = b64encode(cmsg)
- else:
- enc_msg = cmsg
-
- return enc_msg
-
- def decrypt(self, msg, alg='aes_128_cbc', padding='PKCS#7', b64dec=True):
- """
- :param key: The encryption key
- :param msg: Base64 encoded message to be decrypted
- :return: The decrypted message
- """
- data = b64decode(msg) if b64dec else msg
-
- cipher, iv = self.build_cipher(alg=alg)
- decryptor = cipher.decryptor()
- res = decryptor.update(data)[AES_BLOCK_SIZE:] + decryptor.finalize()
- if padding in ['PKCS#5', 'PKCS#7']:
- idx = bytearray(res)[-1]
- res = res[:-idx]
- return res
+AESCipher = _AESCipher
+POSTFIX_MODE = _AESCipher.POSTFIX_MODE
+AES_BLOCK_SIZE = _AESCipher.AES_BLOCK_SIZE
diff --git a/src/saml2/cryptography/symmetric.py b/src/saml2/cryptography/symmetric.py
index 93d9cdf8..16df21f3 100644
--- a/src/saml2/cryptography/symmetric.py
+++ b/src/saml2/cryptography/symmetric.py
@@ -4,7 +4,16 @@ The default symmetric cryptography method used is Fernet by the cryptography
library. Reference: https://cryptography.io/en/latest/fernet/
"""
+import base64 as _base64
+import os as _os
+import warnings as _warnings
+
import cryptography.fernet as _fernet
+import cryptography.hazmat.backends as _backends
+import cryptography.hazmat.primitives.ciphers as _ciphers
+
+
+_warnings.simplefilter('default')
class Default(object):
@@ -43,3 +52,118 @@ class Default(object):
"""
plaintext = self._symmetric.decrypt(ciphertext)
return plaintext
+
+
+class AESCipher(object):
+ """[deprecated] Symmetric cryptography method using AES.
+
+ The default parameter set is AES 128bit in CBC mode.
+ """
+
+ POSTFIX_MODE = {
+ 'cbc': _ciphers.modes.CBC,
+ 'cfb': _ciphers.modes.CFB,
+ }
+
+ AES_BLOCK_SIZE = int(_ciphers.algorithms.AES.block_size / 8)
+
+ @classmethod
+ def _deprecation_notice(cls):
+ """Warn about deprecation of this class."""
+ _deprecation_msg = (
+ '{name} {type} is deprecated. '
+ 'It will be removed in the next version. '
+ 'Use saml2.cryptography.symmetric instead.'
+ ).format(name=cls.__name__, type=type(cls).__name__)
+ _warnings.warn(_deprecation_msg, DeprecationWarning)
+
+ def __init__(self, key):
+ """
+ :param key: The encryption key
+ :return: AESCipher instance
+ """
+ self.__class__._deprecation_notice()
+ self.key = key
+
+ def build_cipher(self, alg='aes_128_cbc'):
+ """
+ :param alg: cipher algorithm
+ :return: A Cipher instance
+ """
+ self.__class__._deprecation_notice()
+ typ, bits, cmode = alg.lower().split('_')
+ bits = int(bits)
+ iv = _os.urandom(self.AES_BLOCK_SIZE)
+
+ if len(iv) != self.AES_BLOCK_SIZE:
+ raise Exception('Wrong iv size: {}'.format(len(iv)))
+
+ if bits not in _ciphers.algorithms.AES.key_sizes:
+ raise Exception('Unsupported key length: {}'.format(bits))
+
+ if len(self.key) != bits / 8:
+ raise Exception('Wrong Key length: {}'.format(len(self.key)))
+
+ try:
+ mode = self.POSTFIX_MODE[cmode]
+ except KeyError:
+ raise Exception('Unsupported chaining mode: {}'.format(cmode))
+
+ cipher = _ciphers.Cipher(
+ _ciphers.algorithms.AES(self.key),
+ mode(iv),
+ backend=_backends.default_backend())
+
+ return cipher, iv
+
+ def encrypt(self, msg, alg='aes_128_cbc', padding='PKCS#7', b64enc=True,
+ block_size=AES_BLOCK_SIZE):
+ """
+ :param key: The encryption key
+ :param msg: Message to be encrypted
+ :param padding: Which padding that should be used
+ :param b64enc: Whether the result should be base64encoded
+ :param block_size: If PKCS#7 padding which block size to use
+ :return: The encrypted message
+ """
+ self.__class__._deprecation_notice()
+ if padding == 'PKCS#7':
+ _block_size = block_size
+ elif padding == 'PKCS#5':
+ _block_size = 8
+ else:
+ _block_size = 0
+
+ if _block_size:
+ plen = _block_size - (len(msg) % _block_size)
+ c = chr(plen).encode()
+ msg += c * plen
+
+ cipher, iv = self.build_cipher(alg)
+ encryptor = cipher.encryptor()
+ cmsg = iv + encryptor.update(msg) + encryptor.finalize()
+
+ if b64enc:
+ enc_msg = _base64.b64encode(cmsg)
+ else:
+ enc_msg = cmsg
+
+ return enc_msg
+
+ def decrypt(self, msg, alg='aes_128_cbc', padding='PKCS#7', b64dec=True):
+ """
+ :param key: The encryption key
+ :param msg: Base64 encoded message to be decrypted
+ :return: The decrypted message
+ """
+ self.__class__._deprecation_notice()
+ data = _base64.b64decode(msg) if b64dec else msg
+
+ cipher, iv = self.build_cipher(alg=alg)
+ decryptor = cipher.decryptor()
+ res = decryptor.update(data)[self.AES_BLOCK_SIZE:]
+ res += decryptor.finalize()
+ if padding in ['PKCS#5', 'PKCS#7']:
+ idx = bytearray(res)[-1]
+ res = res[:-idx]
+ return res