update windows build to Python 3.7
This commit is contained in:
parent
73105fa71e
commit
ddc59ab92d
5761 changed files with 750298 additions and 213405 deletions
|
|
@ -5,8 +5,8 @@
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography.hazmat.primitives.ciphers.base import (
|
||||
AEADCipherContext, AEADEncryptionContext, BlockCipherAlgorithm, Cipher,
|
||||
CipherAlgorithm, CipherContext
|
||||
AEADCipherContext, AEADDecryptionContext, AEADEncryptionContext,
|
||||
BlockCipherAlgorithm, Cipher, CipherAlgorithm, CipherContext
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -16,5 +16,6 @@ __all__ = [
|
|||
"BlockCipherAlgorithm",
|
||||
"CipherContext",
|
||||
"AEADCipherContext",
|
||||
"AEADDecryptionContext",
|
||||
"AEADEncryptionContext",
|
||||
]
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
188
Lib/site-packages/cryptography/hazmat/primitives/ciphers/aead.py
Normal file
188
Lib/site-packages/cryptography/hazmat/primitives/ciphers/aead.py
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import os
|
||||
|
||||
from cryptography import exceptions, utils
|
||||
from cryptography.hazmat.backends.openssl import aead
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
|
||||
class ChaCha20Poly1305(object):
|
||||
_MAX_SIZE = 2 ** 32
|
||||
|
||||
def __init__(self, key):
|
||||
if not backend.aead_cipher_supported(self):
|
||||
raise exceptions.UnsupportedAlgorithm(
|
||||
"ChaCha20Poly1305 is not supported by this version of OpenSSL",
|
||||
exceptions._Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
utils._check_bytes("key", key)
|
||||
|
||||
if len(key) != 32:
|
||||
raise ValueError("ChaCha20Poly1305 key must be 32 bytes.")
|
||||
|
||||
self._key = key
|
||||
|
||||
@classmethod
|
||||
def generate_key(cls):
|
||||
return os.urandom(32)
|
||||
|
||||
def encrypt(self, nonce, data, associated_data):
|
||||
if associated_data is None:
|
||||
associated_data = b""
|
||||
|
||||
if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE:
|
||||
# This is OverflowError to match what cffi would raise
|
||||
raise OverflowError(
|
||||
"Data or associated data too long. Max 2**32 bytes"
|
||||
)
|
||||
|
||||
self._check_params(nonce, data, associated_data)
|
||||
return aead._encrypt(
|
||||
backend, self, nonce, data, associated_data, 16
|
||||
)
|
||||
|
||||
def decrypt(self, nonce, data, associated_data):
|
||||
if associated_data is None:
|
||||
associated_data = b""
|
||||
|
||||
self._check_params(nonce, data, associated_data)
|
||||
return aead._decrypt(
|
||||
backend, self, nonce, data, associated_data, 16
|
||||
)
|
||||
|
||||
def _check_params(self, nonce, data, associated_data):
|
||||
utils._check_bytes("nonce", nonce)
|
||||
utils._check_bytes("data", data)
|
||||
utils._check_bytes("associated_data", associated_data)
|
||||
if len(nonce) != 12:
|
||||
raise ValueError("Nonce must be 12 bytes")
|
||||
|
||||
|
||||
class AESCCM(object):
|
||||
_MAX_SIZE = 2 ** 32
|
||||
|
||||
def __init__(self, key, tag_length=16):
|
||||
utils._check_bytes("key", key)
|
||||
if len(key) not in (16, 24, 32):
|
||||
raise ValueError("AESCCM key must be 128, 192, or 256 bits.")
|
||||
|
||||
self._key = key
|
||||
if not isinstance(tag_length, int):
|
||||
raise TypeError("tag_length must be an integer")
|
||||
|
||||
if tag_length not in (4, 6, 8, 10, 12, 14, 16):
|
||||
raise ValueError("Invalid tag_length")
|
||||
|
||||
self._tag_length = tag_length
|
||||
|
||||
if not backend.aead_cipher_supported(self):
|
||||
raise exceptions.UnsupportedAlgorithm(
|
||||
"AESCCM is not supported by this version of OpenSSL",
|
||||
exceptions._Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def generate_key(cls, bit_length):
|
||||
if not isinstance(bit_length, int):
|
||||
raise TypeError("bit_length must be an integer")
|
||||
|
||||
if bit_length not in (128, 192, 256):
|
||||
raise ValueError("bit_length must be 128, 192, or 256")
|
||||
|
||||
return os.urandom(bit_length // 8)
|
||||
|
||||
def encrypt(self, nonce, data, associated_data):
|
||||
if associated_data is None:
|
||||
associated_data = b""
|
||||
|
||||
if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE:
|
||||
# This is OverflowError to match what cffi would raise
|
||||
raise OverflowError(
|
||||
"Data or associated data too long. Max 2**32 bytes"
|
||||
)
|
||||
|
||||
self._check_params(nonce, data, associated_data)
|
||||
self._validate_lengths(nonce, len(data))
|
||||
return aead._encrypt(
|
||||
backend, self, nonce, data, associated_data, self._tag_length
|
||||
)
|
||||
|
||||
def decrypt(self, nonce, data, associated_data):
|
||||
if associated_data is None:
|
||||
associated_data = b""
|
||||
|
||||
self._check_params(nonce, data, associated_data)
|
||||
return aead._decrypt(
|
||||
backend, self, nonce, data, associated_data, self._tag_length
|
||||
)
|
||||
|
||||
def _validate_lengths(self, nonce, data_len):
|
||||
# For information about computing this, see
|
||||
# https://tools.ietf.org/html/rfc3610#section-2.1
|
||||
l_val = 15 - len(nonce)
|
||||
if 2 ** (8 * l_val) < data_len:
|
||||
raise ValueError("Nonce too long for data")
|
||||
|
||||
def _check_params(self, nonce, data, associated_data):
|
||||
utils._check_bytes("nonce", nonce)
|
||||
utils._check_bytes("data", data)
|
||||
utils._check_bytes("associated_data", associated_data)
|
||||
if not 7 <= len(nonce) <= 13:
|
||||
raise ValueError("Nonce must be between 7 and 13 bytes")
|
||||
|
||||
|
||||
class AESGCM(object):
|
||||
_MAX_SIZE = 2 ** 32
|
||||
|
||||
def __init__(self, key):
|
||||
utils._check_bytes("key", key)
|
||||
if len(key) not in (16, 24, 32):
|
||||
raise ValueError("AESGCM key must be 128, 192, or 256 bits.")
|
||||
|
||||
self._key = key
|
||||
|
||||
@classmethod
|
||||
def generate_key(cls, bit_length):
|
||||
if not isinstance(bit_length, int):
|
||||
raise TypeError("bit_length must be an integer")
|
||||
|
||||
if bit_length not in (128, 192, 256):
|
||||
raise ValueError("bit_length must be 128, 192, or 256")
|
||||
|
||||
return os.urandom(bit_length // 8)
|
||||
|
||||
def encrypt(self, nonce, data, associated_data):
|
||||
if associated_data is None:
|
||||
associated_data = b""
|
||||
|
||||
if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE:
|
||||
# This is OverflowError to match what cffi would raise
|
||||
raise OverflowError(
|
||||
"Data or associated data too long. Max 2**32 bytes"
|
||||
)
|
||||
|
||||
self._check_params(nonce, data, associated_data)
|
||||
return aead._encrypt(
|
||||
backend, self, nonce, data, associated_data, 16
|
||||
)
|
||||
|
||||
def decrypt(self, nonce, data, associated_data):
|
||||
if associated_data is None:
|
||||
associated_data = b""
|
||||
|
||||
self._check_params(nonce, data, associated_data)
|
||||
return aead._decrypt(
|
||||
backend, self, nonce, data, associated_data, 16
|
||||
)
|
||||
|
||||
def _check_params(self, nonce, data, associated_data):
|
||||
utils._check_bytes("nonce", nonce)
|
||||
utils._check_bytes("data", data)
|
||||
utils._check_bytes("associated_data", associated_data)
|
||||
if len(nonce) == 0:
|
||||
raise ValueError("Nonce must be at least 1 byte")
|
||||
|
|
@ -8,9 +8,13 @@ from cryptography import utils
|
|||
from cryptography.hazmat.primitives.ciphers import (
|
||||
BlockCipherAlgorithm, CipherAlgorithm
|
||||
)
|
||||
from cryptography.hazmat.primitives.ciphers.modes import ModeWithNonce
|
||||
|
||||
|
||||
def _verify_key_size(algorithm, key):
|
||||
# Verify that the key is instance of bytes
|
||||
utils._check_bytes("key", key)
|
||||
|
||||
# Verify that the key size matches the expected key size
|
||||
if len(key) * 8 not in algorithm.key_sizes:
|
||||
raise ValueError("Invalid key size ({0}) for {1}.".format(
|
||||
|
|
@ -24,7 +28,8 @@ def _verify_key_size(algorithm, key):
|
|||
class AES(object):
|
||||
name = "AES"
|
||||
block_size = 128
|
||||
key_sizes = frozenset([128, 192, 256])
|
||||
# 512 added to support AES-256-XTS, which uses 512-bit keys
|
||||
key_sizes = frozenset([128, 192, 256, 512])
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = _verify_key_size(self, key)
|
||||
|
|
@ -138,3 +143,26 @@ class SEED(object):
|
|||
@property
|
||||
def key_size(self):
|
||||
return len(self.key) * 8
|
||||
|
||||
|
||||
@utils.register_interface(CipherAlgorithm)
|
||||
@utils.register_interface(ModeWithNonce)
|
||||
class ChaCha20(object):
|
||||
name = "ChaCha20"
|
||||
key_sizes = frozenset([256])
|
||||
|
||||
def __init__(self, key, nonce):
|
||||
self.key = _verify_key_size(self, key)
|
||||
if not isinstance(nonce, bytes):
|
||||
raise TypeError("nonce must be bytes")
|
||||
|
||||
if len(nonce) != 16:
|
||||
raise ValueError("nonce must be 128-bits (16 bytes)")
|
||||
|
||||
self._nonce = nonce
|
||||
|
||||
nonce = utils.read_only_property("_nonce")
|
||||
|
||||
@property
|
||||
def key_size(self):
|
||||
return len(self.key) * 8
|
||||
|
|
|
|||
|
|
@ -50,6 +50,13 @@ class CipherContext(object):
|
|||
as bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_into(self, data, buf):
|
||||
"""
|
||||
Processes the provided bytes and writes the resulting data into the
|
||||
provided buffer. Returns the number of bytes written.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def finalize(self):
|
||||
"""
|
||||
|
|
@ -66,6 +73,16 @@ class AEADCipherContext(object):
|
|||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AEADDecryptionContext(object):
|
||||
@abc.abstractmethod
|
||||
def finalize_with_tag(self, tag):
|
||||
"""
|
||||
Returns the results of processing the final block as bytes and allows
|
||||
delayed passing of the authentication tag.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AEADEncryptionContext(object):
|
||||
@abc.abstractproperty
|
||||
|
|
@ -106,11 +123,6 @@ class Cipher(object):
|
|||
return self._wrap_ctx(ctx, encrypt=True)
|
||||
|
||||
def decryptor(self):
|
||||
if isinstance(self.mode, modes.ModeWithAuthenticationTag):
|
||||
if self.mode.tag is None:
|
||||
raise ValueError(
|
||||
"Authentication tag must be provided when decrypting."
|
||||
)
|
||||
ctx = self._backend.create_symmetric_decryption_ctx(
|
||||
self.algorithm, self.mode
|
||||
)
|
||||
|
|
@ -136,6 +148,11 @@ class _CipherContext(object):
|
|||
raise AlreadyFinalized("Context was already finalized.")
|
||||
return self._ctx.update(data)
|
||||
|
||||
def update_into(self, data, buf):
|
||||
if self._ctx is None:
|
||||
raise AlreadyFinalized("Context was already finalized.")
|
||||
return self._ctx.update_into(data, buf)
|
||||
|
||||
def finalize(self):
|
||||
if self._ctx is None:
|
||||
raise AlreadyFinalized("Context was already finalized.")
|
||||
|
|
@ -146,6 +163,7 @@ class _CipherContext(object):
|
|||
|
||||
@utils.register_interface(AEADCipherContext)
|
||||
@utils.register_interface(CipherContext)
|
||||
@utils.register_interface(AEADDecryptionContext)
|
||||
class _AEADCipherContext(object):
|
||||
def __init__(self, ctx):
|
||||
self._ctx = ctx
|
||||
|
|
@ -154,11 +172,11 @@ class _AEADCipherContext(object):
|
|||
self._tag = None
|
||||
self._updated = False
|
||||
|
||||
def update(self, data):
|
||||
def _check_limit(self, data_size):
|
||||
if self._ctx is None:
|
||||
raise AlreadyFinalized("Context was already finalized.")
|
||||
self._updated = True
|
||||
self._bytes_processed += len(data)
|
||||
self._bytes_processed += data_size
|
||||
if self._bytes_processed > self._ctx._mode._MAX_ENCRYPTED_BYTES:
|
||||
raise ValueError(
|
||||
"{0} has a maximum encrypted byte limit of {1}".format(
|
||||
|
|
@ -166,8 +184,14 @@ class _AEADCipherContext(object):
|
|||
)
|
||||
)
|
||||
|
||||
def update(self, data):
|
||||
self._check_limit(len(data))
|
||||
return self._ctx.update(data)
|
||||
|
||||
def update_into(self, data, buf):
|
||||
self._check_limit(len(data))
|
||||
return self._ctx.update_into(data, buf)
|
||||
|
||||
def finalize(self):
|
||||
if self._ctx is None:
|
||||
raise AlreadyFinalized("Context was already finalized.")
|
||||
|
|
@ -176,6 +200,14 @@ class _AEADCipherContext(object):
|
|||
self._ctx = None
|
||||
return data
|
||||
|
||||
def finalize_with_tag(self, tag):
|
||||
if self._ctx is None:
|
||||
raise AlreadyFinalized("Context was already finalized.")
|
||||
data = self._ctx.finalize_with_tag(tag)
|
||||
self._tag = self._ctx.tag
|
||||
self._ctx = None
|
||||
return data
|
||||
|
||||
def authenticate_additional_data(self, data):
|
||||
if self._ctx is None:
|
||||
raise AlreadyFinalized("Context was already finalized.")
|
||||
|
|
@ -185,7 +217,7 @@ class _AEADCipherContext(object):
|
|||
self._aad_bytes_processed += len(data)
|
||||
if self._aad_bytes_processed > self._ctx._mode._MAX_AAD_BYTES:
|
||||
raise ValueError(
|
||||
"{0} has a maximum AAD byte limit of {0}".format(
|
||||
"{0} has a maximum AAD byte limit of {1}".format(
|
||||
self._ctx._mode.name, self._ctx._mode._MAX_AAD_BYTES
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,15 @@ class ModeWithInitializationVector(object):
|
|||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ModeWithTweak(object):
|
||||
@abc.abstractproperty
|
||||
def tweak(self):
|
||||
"""
|
||||
The value of the tweak for this mode as bytes.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ModeWithNonce(object):
|
||||
@abc.abstractproperty
|
||||
|
|
@ -54,6 +63,13 @@ class ModeWithAuthenticationTag(object):
|
|||
"""
|
||||
|
||||
|
||||
def _check_aes_key_length(self, algorithm):
|
||||
if algorithm.key_size > 256 and algorithm.name == "AES":
|
||||
raise ValueError(
|
||||
"Only 128, 192, and 256 bit keys are allowed for this AES mode"
|
||||
)
|
||||
|
||||
|
||||
def _check_iv_length(self, algorithm):
|
||||
if len(self.initialization_vector) * 8 != algorithm.block_size:
|
||||
raise ValueError("Invalid IV size ({0}) for {1}.".format(
|
||||
|
|
@ -61,24 +77,55 @@ def _check_iv_length(self, algorithm):
|
|||
))
|
||||
|
||||
|
||||
def _check_iv_and_key_length(self, algorithm):
|
||||
_check_aes_key_length(self, algorithm)
|
||||
_check_iv_length(self, algorithm)
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
@utils.register_interface(ModeWithInitializationVector)
|
||||
class CBC(object):
|
||||
name = "CBC"
|
||||
|
||||
def __init__(self, initialization_vector):
|
||||
if not isinstance(initialization_vector, bytes):
|
||||
raise TypeError("initialization_vector must be bytes")
|
||||
|
||||
self._initialization_vector = initialization_vector
|
||||
|
||||
initialization_vector = utils.read_only_property("_initialization_vector")
|
||||
validate_for_algorithm = _check_iv_length
|
||||
validate_for_algorithm = _check_iv_and_key_length
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
@utils.register_interface(ModeWithTweak)
|
||||
class XTS(object):
|
||||
name = "XTS"
|
||||
|
||||
def __init__(self, tweak):
|
||||
if not isinstance(tweak, bytes):
|
||||
raise TypeError("tweak must be bytes")
|
||||
|
||||
if len(tweak) != 16:
|
||||
raise ValueError("tweak must be 128-bits (16 bytes)")
|
||||
|
||||
self._tweak = tweak
|
||||
|
||||
tweak = utils.read_only_property("_tweak")
|
||||
|
||||
def validate_for_algorithm(self, algorithm):
|
||||
if algorithm.key_size not in (256, 512):
|
||||
raise ValueError(
|
||||
"The XTS specification requires a 256-bit key for AES-128-XTS"
|
||||
" and 512-bit key for AES-256-XTS"
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
class ECB(object):
|
||||
name = "ECB"
|
||||
|
||||
def validate_for_algorithm(self, algorithm):
|
||||
pass
|
||||
validate_for_algorithm = _check_aes_key_length
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
|
|
@ -87,10 +134,13 @@ class OFB(object):
|
|||
name = "OFB"
|
||||
|
||||
def __init__(self, initialization_vector):
|
||||
if not isinstance(initialization_vector, bytes):
|
||||
raise TypeError("initialization_vector must be bytes")
|
||||
|
||||
self._initialization_vector = initialization_vector
|
||||
|
||||
initialization_vector = utils.read_only_property("_initialization_vector")
|
||||
validate_for_algorithm = _check_iv_length
|
||||
validate_for_algorithm = _check_iv_and_key_length
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
|
|
@ -99,10 +149,13 @@ class CFB(object):
|
|||
name = "CFB"
|
||||
|
||||
def __init__(self, initialization_vector):
|
||||
if not isinstance(initialization_vector, bytes):
|
||||
raise TypeError("initialization_vector must be bytes")
|
||||
|
||||
self._initialization_vector = initialization_vector
|
||||
|
||||
initialization_vector = utils.read_only_property("_initialization_vector")
|
||||
validate_for_algorithm = _check_iv_length
|
||||
validate_for_algorithm = _check_iv_and_key_length
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
|
|
@ -111,10 +164,13 @@ class CFB8(object):
|
|||
name = "CFB8"
|
||||
|
||||
def __init__(self, initialization_vector):
|
||||
if not isinstance(initialization_vector, bytes):
|
||||
raise TypeError("initialization_vector must be bytes")
|
||||
|
||||
self._initialization_vector = initialization_vector
|
||||
|
||||
initialization_vector = utils.read_only_property("_initialization_vector")
|
||||
validate_for_algorithm = _check_iv_length
|
||||
validate_for_algorithm = _check_iv_and_key_length
|
||||
|
||||
|
||||
@utils.register_interface(Mode)
|
||||
|
|
@ -123,11 +179,15 @@ class CTR(object):
|
|||
name = "CTR"
|
||||
|
||||
def __init__(self, nonce):
|
||||
if not isinstance(nonce, bytes):
|
||||
raise TypeError("nonce must be bytes")
|
||||
|
||||
self._nonce = nonce
|
||||
|
||||
nonce = utils.read_only_property("_nonce")
|
||||
|
||||
def validate_for_algorithm(self, algorithm):
|
||||
_check_aes_key_length(self, algorithm)
|
||||
if len(self.nonce) * 8 != algorithm.block_size:
|
||||
raise ValueError("Invalid nonce size ({0}) for {1}.".format(
|
||||
len(self.nonce), self.name
|
||||
|
|
@ -146,19 +206,26 @@ class GCM(object):
|
|||
# len(initialization_vector) must in [1, 2 ** 64), but it's impossible
|
||||
# to actually construct a bytes object that large, so we don't check
|
||||
# for it
|
||||
if min_tag_length < 4:
|
||||
raise ValueError("min_tag_length must be >= 4")
|
||||
if tag is not None and len(tag) < min_tag_length:
|
||||
raise ValueError(
|
||||
"Authentication tag must be {0} bytes or longer.".format(
|
||||
min_tag_length)
|
||||
)
|
||||
|
||||
if not isinstance(initialization_vector, bytes):
|
||||
raise TypeError("initialization_vector must be bytes")
|
||||
if len(initialization_vector) == 0:
|
||||
raise ValueError("initialization_vector must be at least 1 byte")
|
||||
self._initialization_vector = initialization_vector
|
||||
if tag is not None:
|
||||
if not isinstance(tag, bytes):
|
||||
raise TypeError("tag must be bytes or None")
|
||||
if min_tag_length < 4:
|
||||
raise ValueError("min_tag_length must be >= 4")
|
||||
if len(tag) < min_tag_length:
|
||||
raise ValueError(
|
||||
"Authentication tag must be {0} bytes or longer.".format(
|
||||
min_tag_length)
|
||||
)
|
||||
self._tag = tag
|
||||
self._min_tag_length = min_tag_length
|
||||
|
||||
tag = utils.read_only_property("_tag")
|
||||
initialization_vector = utils.read_only_property("_initialization_vector")
|
||||
|
||||
def validate_for_algorithm(self, algorithm):
|
||||
pass
|
||||
_check_aes_key_length(self, algorithm)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue