Merge pull request #293 from OpenKMIP/feat/add-derivation-parameters
Add the DerivationParameters struct
This commit is contained in:
commit
38ee408b21
@ -1250,3 +1250,256 @@ class CustomAttribute(TextString):
|
||||
|
||||
def __init__(self, value=None):
|
||||
super(CustomAttribute, self).__init__(value, Tags.ATTRIBUTE_VALUE)
|
||||
|
||||
|
||||
class DerivationParameters(Struct):
|
||||
"""
|
||||
A set of values needed for key or secret derivation.
|
||||
|
||||
A structure containing optional fields describing certain cryptographic
|
||||
parameters to be used when performing key or secret derivation operations.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
cryptographic_parameters=None,
|
||||
initialization_vector=None,
|
||||
derivation_data=None,
|
||||
salt=None,
|
||||
iteration_count=None):
|
||||
"""
|
||||
Construct a DerivationParameters struct.
|
||||
|
||||
Args:
|
||||
cryptographic_parameters (CryptographicParameters): A
|
||||
CryptographicParameters struct containing the settings for
|
||||
the derivation process. Optional, defaults to None. If not
|
||||
included, the CryptographicParameters associated with the
|
||||
managed object will be used instead.
|
||||
initialization_vector (bytes): The IV value to be used with the
|
||||
pseudo-random derivation function (PRF). Optional depending
|
||||
on the PRF, defaults to None.
|
||||
derivation_data (bytes): A data component to be used instead of
|
||||
or with a derivation key to derive the new cryptographic
|
||||
object. Optional, defaults to None.
|
||||
salt (bytes): A salt value required by the PBKDF2 algorithm.
|
||||
Optional, defaults to None.
|
||||
iteration_count (bytes): An iteration count value required by
|
||||
the PBKDF2 algorithm. Optional, defaults to None.
|
||||
"""
|
||||
super(DerivationParameters, self).__init__(
|
||||
tag=Tags.DERIVATION_PARAMETERS
|
||||
)
|
||||
|
||||
self._cryptographic_parameters = None
|
||||
self._initialization_vector = None
|
||||
self._derivation_data = None
|
||||
self._salt = None
|
||||
self._iteration_count = None
|
||||
|
||||
self.cryptographic_parameters = cryptographic_parameters
|
||||
self.initialization_vector = initialization_vector
|
||||
self.derivation_data = derivation_data
|
||||
self.salt = salt
|
||||
self.iteration_count = iteration_count
|
||||
|
||||
@property
|
||||
def cryptographic_parameters(self):
|
||||
return self._cryptographic_parameters
|
||||
|
||||
@cryptographic_parameters.setter
|
||||
def cryptographic_parameters(self, value):
|
||||
if value is None:
|
||||
self._cryptographic_parameters = None
|
||||
elif isinstance(value, CryptographicParameters):
|
||||
self._cryptographic_parameters = value
|
||||
else:
|
||||
raise TypeError(
|
||||
"cryptographic parameters must be a CryptographicParameters "
|
||||
"struct"
|
||||
)
|
||||
|
||||
@property
|
||||
def initialization_vector(self):
|
||||
if self._initialization_vector:
|
||||
return self._initialization_vector.value
|
||||
else:
|
||||
return None
|
||||
|
||||
@initialization_vector.setter
|
||||
def initialization_vector(self, value):
|
||||
if value is None:
|
||||
self._initialization_vector = None
|
||||
elif isinstance(value, six.binary_type):
|
||||
self._initialization_vector = ByteString(
|
||||
value=value,
|
||||
tag=enums.Tags.INITIALIZATION_VECTOR
|
||||
)
|
||||
else:
|
||||
raise TypeError("initialization vector must be bytes")
|
||||
|
||||
@property
|
||||
def derivation_data(self):
|
||||
if self._derivation_data:
|
||||
return self._derivation_data.value
|
||||
else:
|
||||
return None
|
||||
|
||||
@derivation_data.setter
|
||||
def derivation_data(self, value):
|
||||
if value is None:
|
||||
self._derivation_data = None
|
||||
elif isinstance(value, six.binary_type):
|
||||
self._derivation_data = ByteString(
|
||||
value=value,
|
||||
tag=enums.Tags.DERIVATION_DATA
|
||||
)
|
||||
else:
|
||||
raise TypeError("derivation data must be bytes")
|
||||
|
||||
@property
|
||||
def salt(self):
|
||||
if self._salt:
|
||||
return self._salt.value
|
||||
else:
|
||||
return None
|
||||
|
||||
@salt.setter
|
||||
def salt(self, value):
|
||||
if value is None:
|
||||
self._salt = None
|
||||
elif isinstance(value, six.binary_type):
|
||||
self._salt = ByteString(
|
||||
value=value,
|
||||
tag=enums.Tags.SALT
|
||||
)
|
||||
else:
|
||||
raise TypeError("salt must be bytes")
|
||||
|
||||
@property
|
||||
def iteration_count(self):
|
||||
if self._iteration_count:
|
||||
return self._iteration_count.value
|
||||
else:
|
||||
return None
|
||||
|
||||
@iteration_count.setter
|
||||
def iteration_count(self, value):
|
||||
if value is None:
|
||||
self._iteration_count = None
|
||||
elif isinstance(value, six.integer_types):
|
||||
self._iteration_count = Integer(
|
||||
value=value,
|
||||
tag=Tags.ITERATION_COUNT
|
||||
)
|
||||
else:
|
||||
raise TypeError("iteration count must be an integer")
|
||||
|
||||
def read(self, input_stream):
|
||||
"""
|
||||
Read the data encoding the DerivationParameters struct and decode it
|
||||
into its constituent parts.
|
||||
|
||||
Args:
|
||||
input_stream (stream): A data stream containing encoded object
|
||||
data, supporting a read method; usually a BytearrayStream
|
||||
object.
|
||||
"""
|
||||
super(DerivationParameters, self).read(input_stream)
|
||||
local_stream = BytearrayStream(input_stream.read(self.length))
|
||||
|
||||
if self.is_tag_next(
|
||||
enums.Tags.CRYPTOGRAPHIC_PARAMETERS,
|
||||
local_stream
|
||||
):
|
||||
self._cryptographic_parameters = CryptographicParameters()
|
||||
self._cryptographic_parameters.read(local_stream)
|
||||
|
||||
if self.is_tag_next(enums.Tags.INITIALIZATION_VECTOR, local_stream):
|
||||
self._initialization_vector = ByteString(
|
||||
tag=enums.Tags.INITIALIZATION_VECTOR
|
||||
)
|
||||
self._initialization_vector.read(local_stream)
|
||||
|
||||
if self.is_tag_next(enums.Tags.DERIVATION_DATA, local_stream):
|
||||
self._derivation_data = ByteString(tag=enums.Tags.DERIVATION_DATA)
|
||||
self._derivation_data.read(local_stream)
|
||||
|
||||
if self.is_tag_next(enums.Tags.SALT, local_stream):
|
||||
self._salt = ByteString(tag=enums.Tags.SALT)
|
||||
self._salt.read(local_stream)
|
||||
|
||||
if self.is_tag_next(Tags.ITERATION_COUNT, local_stream):
|
||||
self._iteration_count = Integer(tag=Tags.ITERATION_COUNT)
|
||||
self._iteration_count.read(local_stream)
|
||||
|
||||
self.is_oversized(local_stream)
|
||||
|
||||
def write(self, output_stream):
|
||||
"""
|
||||
Write the data encoding the DerivationParameters struct to a stream.
|
||||
|
||||
Args:
|
||||
output_stream (stream): A data stream in which to encode object
|
||||
data, supporting a write method; usually a BytearrayStream
|
||||
object.
|
||||
"""
|
||||
local_stream = BytearrayStream()
|
||||
|
||||
if self._cryptographic_parameters:
|
||||
self._cryptographic_parameters.write(local_stream)
|
||||
if self._initialization_vector:
|
||||
self._initialization_vector.write(local_stream)
|
||||
if self._derivation_data:
|
||||
self._derivation_data.write(local_stream)
|
||||
if self._salt:
|
||||
self._salt.write(local_stream)
|
||||
if self._iteration_count:
|
||||
self._iteration_count.write(local_stream)
|
||||
|
||||
self.length = local_stream.length()
|
||||
super(DerivationParameters, self).write(output_stream)
|
||||
output_stream.write(local_stream.buffer)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, DerivationParameters):
|
||||
if self.cryptographic_parameters != other.cryptographic_parameters:
|
||||
return False
|
||||
elif self.initialization_vector != other.initialization_vector:
|
||||
return False
|
||||
elif self.derivation_data != other.derivation_data:
|
||||
return False
|
||||
elif self.salt != other.salt:
|
||||
return False
|
||||
elif self.iteration_count != other.iteration_count:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, DerivationParameters):
|
||||
return not self == other
|
||||
else:
|
||||
return NotImplemented
|
||||
|
||||
def __repr__(self):
|
||||
args = ", ".join([
|
||||
"cryptographic_parameters={0}".format(
|
||||
repr(self.cryptographic_parameters)
|
||||
),
|
||||
"initialization_vector={0}".format(self.initialization_vector),
|
||||
"derivation_data={0}".format(self.derivation_data),
|
||||
"salt={0}".format(self.salt),
|
||||
"iteration_count={0}".format(
|
||||
self.iteration_count
|
||||
)
|
||||
])
|
||||
return "DerivationParameters({0})".format(args)
|
||||
|
||||
def __str__(self):
|
||||
return str({
|
||||
'cryptographic_parameters': self.cryptographic_parameters,
|
||||
'initialization_vector': self.initialization_vector,
|
||||
'derivation_data': self.derivation_data,
|
||||
'salt': self.salt,
|
||||
'iteration_count': self.iteration_count
|
||||
})
|
||||
|
@ -19,6 +19,7 @@ from kmip.core.attributes import ApplicationData
|
||||
from kmip.core.attributes import ApplicationNamespace
|
||||
from kmip.core.attributes import CertificateType
|
||||
from kmip.core.attributes import CryptographicParameters
|
||||
from kmip.core.attributes import DerivationParameters
|
||||
from kmip.core.attributes import DigestValue
|
||||
from kmip.core.attributes import HashingAlgorithm
|
||||
from kmip.core.attributes import Name
|
||||
@ -1596,3 +1597,804 @@ class TestCryptographicParameters(TestCase):
|
||||
observed = str(cryptographic_parameters)
|
||||
|
||||
self.assertEqual(expected, observed)
|
||||
|
||||
|
||||
class TestDerivationParameters(TestCase):
|
||||
"""
|
||||
Test suite for the DerivationParameters struct.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestDerivationParameters, self).setUp()
|
||||
|
||||
# Encoding obtained in part from the KMIP 1.1 testing document,
|
||||
# Section 11.1. The rest of the encoding for KMIP 1.2+ features was
|
||||
# built by hand; later KMIP testing documents do not include the
|
||||
# encoding, so a manual construction is necessary.
|
||||
#
|
||||
# This encoding matches the following set of values:
|
||||
# Cryptographic Parameters
|
||||
# Block Cipher Mode - CBC
|
||||
# Padding Method - PKCS5
|
||||
# Hashing Algorithm - SHA-1
|
||||
# Key Role Type - KEK
|
||||
# Digital Signature Algorithm - SHA-256 with RSA
|
||||
# Cryptographic Algorithm - AES
|
||||
# Random IV - True
|
||||
# IV Length - 96
|
||||
# Tag Length - 128
|
||||
# Fixed Field Length - 32
|
||||
# Invocation Field Length - 64
|
||||
# Counter Length - 0
|
||||
# Initial Counter Value - 1
|
||||
# Initialization Vector - 0x39487432492834A3
|
||||
# Derivation Data - 0xFAD98B6ACA6D87DD
|
||||
# Salt - 0x8F99212AA15435CD
|
||||
# Iteration Count - 10000
|
||||
|
||||
self.full_encoding = BytearrayStream(
|
||||
b'\x42\x00\x32\x01\x00\x00\x01\x18'
|
||||
b'\x42\x00\x2B\x01\x00\x00\x00\xD0'
|
||||
b'\x42\x00\x11\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00'
|
||||
b'\x42\x00\x5F\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00'
|
||||
b'\x42\x00\x38\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00'
|
||||
b'\x42\x00\x83\x05\x00\x00\x00\x04\x00\x00\x00\x0B\x00\x00\x00\x00'
|
||||
b'\x42\x00\xAE\x05\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x00'
|
||||
b'\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00'
|
||||
b'\x42\x00\xC5\x06\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01'
|
||||
b'\x42\x00\xCD\x02\x00\x00\x00\x04\x00\x00\x00\x60\x00\x00\x00\x00'
|
||||
b'\x42\x00\xCE\x02\x00\x00\x00\x04\x00\x00\x00\x80\x00\x00\x00\x00'
|
||||
b'\x42\x00\xCF\x02\x00\x00\x00\x04\x00\x00\x00\x20\x00\x00\x00\x00'
|
||||
b'\x42\x00\xD2\x02\x00\x00\x00\x04\x00\x00\x00\x40\x00\x00\x00\x00'
|
||||
b'\x42\x00\xD0\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x42\x00\xD1\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00'
|
||||
b'\x42\x00\x3A\x08\x00\x00\x00\x08\x39\x48\x74\x32\x49\x28\x34\xA3'
|
||||
b'\x42\x00\x30\x08\x00\x00\x00\x08\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD'
|
||||
b'\x42\x00\x84\x08\x00\x00\x00\x08\x8F\x99\x21\x2A\xA1\x54\x35\xCD'
|
||||
b'\x42\x00\x3C\x02\x00\x00\x00\x04\x00\x00\x27\x10\x00\x00\x00\x00'
|
||||
)
|
||||
|
||||
# Adapted from the full encoding above. This encoding matches the
|
||||
# following set of values:
|
||||
# Initialization Vector - 0x39487432492834A3
|
||||
# Derivation Data - 0xFAD98B6ACA6D87DD
|
||||
|
||||
self.partial_encoding = BytearrayStream(
|
||||
b'\x42\x00\x32\x01\x00\x00\x00\x20'
|
||||
b'\x42\x00\x3A\x08\x00\x00\x00\x08\x39\x48\x74\x32\x49\x28\x34\xA3'
|
||||
b'\x42\x00\x30\x08\x00\x00\x00\x08\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD'
|
||||
)
|
||||
|
||||
self.empty_encoding = BytearrayStream(
|
||||
b'\x42\x00\x32\x01\x00\x00\x00\x00'
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
super(TestDerivationParameters, self).tearDown()
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Test that a DerivationParameters struct can be constructed with
|
||||
no arguments.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
|
||||
self.assertEqual(None, derivation_parameters.cryptographic_parameters)
|
||||
self.assertEqual(None, derivation_parameters.initialization_vector)
|
||||
self.assertEqual(None, derivation_parameters.derivation_data)
|
||||
self.assertEqual(None, derivation_parameters.salt)
|
||||
self.assertEqual(None, derivation_parameters.iteration_count)
|
||||
|
||||
def test_init_with_args(self):
|
||||
"""
|
||||
Test that a DerivationParameters struct can be constructed with
|
||||
valid values.
|
||||
"""
|
||||
cryptographic_parameters = CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CTR,
|
||||
padding_method=enums.PaddingMethod.NONE,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_256,
|
||||
key_role_type=enums.KeyRoleType.BDK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA1_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.TRIPLE_DES,
|
||||
random_iv=False,
|
||||
iv_length=128,
|
||||
tag_length=256,
|
||||
fixed_field_length=48,
|
||||
invocation_field_length=60,
|
||||
counter_length=20,
|
||||
initial_counter_value=2
|
||||
)
|
||||
derivation_parameters = DerivationParameters(
|
||||
cryptographic_parameters=cryptographic_parameters,
|
||||
initialization_vector=b'\x39\x48\x74\x32\x49\x28\x34\xA3',
|
||||
derivation_data=b'\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD',
|
||||
salt=b'\x8F\x99\x21\x2A\xA1\x54\x35\xCD',
|
||||
iteration_count=10000
|
||||
)
|
||||
|
||||
self.assertIsInstance(
|
||||
derivation_parameters.cryptographic_parameters,
|
||||
CryptographicParameters
|
||||
)
|
||||
parameters = derivation_parameters.cryptographic_parameters
|
||||
self.assertEqual(
|
||||
enums.BlockCipherMode.CTR,
|
||||
parameters.block_cipher_mode
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.PaddingMethod.NONE,
|
||||
parameters.padding_method
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.HashingAlgorithm.SHA_256,
|
||||
parameters.hashing_algorithm
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.KeyRoleType.BDK,
|
||||
parameters.key_role_type
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.DigitalSignatureAlgorithm.SHA1_WITH_RSA_ENCRYPTION,
|
||||
parameters.digital_signature_algorithm
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.CryptographicAlgorithm.TRIPLE_DES,
|
||||
parameters.cryptographic_algorithm
|
||||
)
|
||||
self.assertEqual(False, parameters.random_iv)
|
||||
self.assertEqual(128, parameters.iv_length)
|
||||
self.assertEqual(256, parameters.tag_length)
|
||||
self.assertEqual(48, parameters.fixed_field_length)
|
||||
self.assertEqual(60, parameters.invocation_field_length)
|
||||
self.assertEqual(20, parameters.counter_length)
|
||||
self.assertEqual(2, parameters.initial_counter_value)
|
||||
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\x39\x48\x74\x32\x49\x28\x34\xA3'
|
||||
),
|
||||
derivation_parameters.initialization_vector
|
||||
)
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD'
|
||||
),
|
||||
derivation_parameters.derivation_data
|
||||
)
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\x8F\x99\x21\x2A\xA1\x54\x35\xCD'
|
||||
),
|
||||
derivation_parameters.salt
|
||||
)
|
||||
self.assertEqual(10000, derivation_parameters.iteration_count)
|
||||
|
||||
def test_invalid_cryptographic_parameters(self):
|
||||
"""
|
||||
Test that a TypeError is raised when an invalid value is used to set
|
||||
the cryptographic parameters of a DerivationParameters struct.
|
||||
"""
|
||||
kwargs = {'cryptographic_parameters': 'invalid'}
|
||||
self.assertRaisesRegexp(
|
||||
TypeError,
|
||||
"cryptographic parameters must be a CryptographicParameters "
|
||||
"struct",
|
||||
DerivationParameters,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
derivation_parameters = DerivationParameters()
|
||||
args = (derivation_parameters, 'cryptographic_parameters', 'invalid')
|
||||
self.assertRaisesRegexp(
|
||||
TypeError,
|
||||
"cryptographic parameters must be a CryptographicParameters "
|
||||
"struct",
|
||||
setattr,
|
||||
*args
|
||||
)
|
||||
|
||||
def test_invalid_initialization_vector(self):
|
||||
"""
|
||||
Test that a TypeError is raised when an invalid value is used to set
|
||||
the initialization vector of a DerivationParameters struct.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
args = (derivation_parameters, 'initialization_vector', 0)
|
||||
self.assertRaisesRegexp(
|
||||
TypeError,
|
||||
"initialization vector must be bytes",
|
||||
setattr,
|
||||
*args
|
||||
)
|
||||
|
||||
def test_invalid_derivation_data(self):
|
||||
"""
|
||||
Test that a TypeError is raised when an invalid value is used to set
|
||||
the derivation data of a DerivationParameters struct.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
args = (derivation_parameters, 'derivation_data', 0)
|
||||
self.assertRaisesRegexp(
|
||||
TypeError,
|
||||
"derivation data must be bytes",
|
||||
setattr,
|
||||
*args
|
||||
)
|
||||
|
||||
def test_invalid_salt(self):
|
||||
"""
|
||||
Test that a TypeError is raised when an invalid value is used to set
|
||||
the salt of a DerivationParameters struct.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
args = (derivation_parameters, 'salt', 0)
|
||||
self.assertRaisesRegexp(
|
||||
TypeError,
|
||||
"salt must be bytes",
|
||||
setattr,
|
||||
*args
|
||||
)
|
||||
|
||||
def test_invalid_iteration_count(self):
|
||||
"""
|
||||
Test that a TypeError is raised when an invalid value is used to set
|
||||
the iteration count of a DerivationParameters struct.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
args = (derivation_parameters, 'iteration_count', 'invalid')
|
||||
self.assertRaisesRegexp(
|
||||
TypeError,
|
||||
"iteration count must be an integer",
|
||||
setattr,
|
||||
*args
|
||||
)
|
||||
|
||||
def test_read(self):
|
||||
"""
|
||||
Test that a DerivationParameters struct can be read from a data
|
||||
stream.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
|
||||
self.assertEqual(None, derivation_parameters.cryptographic_parameters)
|
||||
self.assertEqual(None, derivation_parameters.initialization_vector)
|
||||
self.assertEqual(None, derivation_parameters.derivation_data)
|
||||
self.assertEqual(None, derivation_parameters.salt)
|
||||
self.assertEqual(None, derivation_parameters.iteration_count)
|
||||
|
||||
derivation_parameters.read(self.full_encoding)
|
||||
|
||||
self.assertIsInstance(
|
||||
derivation_parameters.cryptographic_parameters,
|
||||
CryptographicParameters
|
||||
)
|
||||
cryptographic_parameters = \
|
||||
derivation_parameters.cryptographic_parameters
|
||||
self.assertEqual(
|
||||
enums.BlockCipherMode.CBC,
|
||||
cryptographic_parameters.block_cipher_mode
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.PaddingMethod.PKCS5,
|
||||
cryptographic_parameters.padding_method
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.HashingAlgorithm.SHA_1,
|
||||
cryptographic_parameters.hashing_algorithm
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.KeyRoleType.KEK,
|
||||
cryptographic_parameters.key_role_type
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.DigitalSignatureAlgorithm.SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_parameters.digital_signature_algorithm
|
||||
)
|
||||
self.assertEqual(
|
||||
enums.CryptographicAlgorithm.AES,
|
||||
cryptographic_parameters.cryptographic_algorithm
|
||||
)
|
||||
self.assertEqual(True, cryptographic_parameters.random_iv)
|
||||
self.assertEqual(96, cryptographic_parameters.iv_length)
|
||||
self.assertEqual(128, cryptographic_parameters.tag_length)
|
||||
self.assertEqual(32, cryptographic_parameters.fixed_field_length)
|
||||
self.assertEqual(64, cryptographic_parameters.invocation_field_length)
|
||||
self.assertEqual(0, cryptographic_parameters.counter_length)
|
||||
self.assertEqual(1, cryptographic_parameters.initial_counter_value)
|
||||
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\x39\x48\x74\x32\x49\x28\x34\xA3'
|
||||
),
|
||||
derivation_parameters.initialization_vector
|
||||
)
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD'
|
||||
),
|
||||
derivation_parameters.derivation_data
|
||||
)
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\x8F\x99\x21\x2A\xA1\x54\x35\xCD'
|
||||
),
|
||||
derivation_parameters.salt
|
||||
)
|
||||
self.assertEqual(10000, derivation_parameters.iteration_count)
|
||||
|
||||
def test_read_partial(self):
|
||||
"""
|
||||
Test that a DerivationParameters struct can be read from a partial
|
||||
data stream.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
|
||||
self.assertEqual(None, derivation_parameters.cryptographic_parameters)
|
||||
self.assertEqual(None, derivation_parameters.initialization_vector)
|
||||
self.assertEqual(None, derivation_parameters.derivation_data)
|
||||
self.assertEqual(None, derivation_parameters.salt)
|
||||
self.assertEqual(None, derivation_parameters.iteration_count)
|
||||
|
||||
derivation_parameters.read(self.partial_encoding)
|
||||
|
||||
self.assertEqual(None, derivation_parameters.cryptographic_parameters)
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\x39\x48\x74\x32\x49\x28\x34\xA3'
|
||||
),
|
||||
derivation_parameters.initialization_vector
|
||||
)
|
||||
self.assertEqual(
|
||||
(
|
||||
b'\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD'
|
||||
),
|
||||
derivation_parameters.derivation_data
|
||||
)
|
||||
self.assertEqual(None, derivation_parameters.salt)
|
||||
self.assertEqual(None, derivation_parameters.iteration_count)
|
||||
|
||||
def test_read_empty(self):
|
||||
"""
|
||||
Test that a DerivationParameters struct can be read from an empty
|
||||
data stream.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
|
||||
self.assertEqual(None, derivation_parameters.cryptographic_parameters)
|
||||
self.assertEqual(None, derivation_parameters.initialization_vector)
|
||||
self.assertEqual(None, derivation_parameters.derivation_data)
|
||||
self.assertEqual(None, derivation_parameters.salt)
|
||||
self.assertEqual(None, derivation_parameters.iteration_count)
|
||||
|
||||
derivation_parameters.read(self.empty_encoding)
|
||||
|
||||
self.assertEqual(None, derivation_parameters.cryptographic_parameters)
|
||||
self.assertEqual(None, derivation_parameters.initialization_vector)
|
||||
self.assertEqual(None, derivation_parameters.derivation_data)
|
||||
self.assertEqual(None, derivation_parameters.salt)
|
||||
self.assertEqual(None, derivation_parameters.iteration_count)
|
||||
|
||||
def test_write(self):
|
||||
"""
|
||||
Test that a DerivationParameters struct can be written to a data
|
||||
stream.
|
||||
"""
|
||||
cryptographic_parameters = CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
)
|
||||
derivation_parameters = DerivationParameters(
|
||||
cryptographic_parameters=cryptographic_parameters,
|
||||
initialization_vector=b'\x39\x48\x74\x32\x49\x28\x34\xA3',
|
||||
derivation_data=b'\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD',
|
||||
salt=b'\x8F\x99\x21\x2A\xA1\x54\x35\xCD',
|
||||
iteration_count=10000
|
||||
)
|
||||
stream = BytearrayStream()
|
||||
derivation_parameters.write(stream)
|
||||
|
||||
self.assertEqual(len(self.full_encoding), len(stream))
|
||||
self.assertEqual(str(self.full_encoding), str(stream))
|
||||
|
||||
def test_write_partial(self):
|
||||
"""
|
||||
Test that a partially defined DerivationParameters struct can be
|
||||
written to a data stream.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters(
|
||||
initialization_vector=b'\x39\x48\x74\x32\x49\x28\x34\xA3',
|
||||
derivation_data=b'\xFA\xD9\x8B\x6A\xCA\x6D\x87\xDD',
|
||||
)
|
||||
stream = BytearrayStream()
|
||||
derivation_parameters.write(stream)
|
||||
|
||||
self.assertEqual(len(self.partial_encoding), len(stream))
|
||||
self.assertEqual(str(self.partial_encoding), str(stream))
|
||||
|
||||
def test_write_empty(self):
|
||||
"""
|
||||
Test that an empty DerivationParameters struct can be written to a
|
||||
data stream.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters()
|
||||
stream = BytearrayStream()
|
||||
derivation_parameters.write(stream)
|
||||
|
||||
self.assertEqual(len(self.empty_encoding), len(stream))
|
||||
self.assertEqual(str(self.empty_encoding), str(stream))
|
||||
|
||||
def test_equal_on_equal(self):
|
||||
"""
|
||||
Test that the equality operator returns True when comparing two
|
||||
DerivationParameters structs with the same data.
|
||||
"""
|
||||
a = DerivationParameters()
|
||||
b = DerivationParameters()
|
||||
|
||||
self.assertTrue(a == b)
|
||||
self.assertTrue(b == a)
|
||||
|
||||
a = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
),
|
||||
initialization_vector=b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
derivation_data=b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
salt=b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
iteration_count=1000
|
||||
)
|
||||
b = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
),
|
||||
initialization_vector=b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
derivation_data=b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
salt=b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
iteration_count=1000
|
||||
)
|
||||
|
||||
self.assertTrue(a == b)
|
||||
self.assertTrue(b == a)
|
||||
|
||||
def test_equal_on_not_equal_cryptographic_parameters(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
DerivationParameters structs with different cryptographic parameters.
|
||||
"""
|
||||
a = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC
|
||||
)
|
||||
)
|
||||
b = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.GCM
|
||||
)
|
||||
)
|
||||
|
||||
self.assertFalse(a == b)
|
||||
self.assertFalse(b == a)
|
||||
|
||||
def test_equal_on_not_equal_initialization_vector(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
DerivationParameters structs with different initialization vectors.
|
||||
"""
|
||||
a = DerivationParameters(initialization_vector=b'\x01')
|
||||
b = DerivationParameters(initialization_vector=b'\x02')
|
||||
|
||||
self.assertFalse(a == b)
|
||||
self.assertFalse(b == a)
|
||||
|
||||
def test_equal_on_not_equal_derivation_data(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
DerivationParameters structs with different derivation data.
|
||||
"""
|
||||
a = DerivationParameters(derivation_data=b'\x01')
|
||||
b = DerivationParameters(derivation_data=b'\x02')
|
||||
|
||||
self.assertFalse(a == b)
|
||||
self.assertFalse(b == a)
|
||||
|
||||
def test_equal_on_not_equal_salt(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
DerivationParameters structs with different salts.
|
||||
"""
|
||||
a = DerivationParameters(salt=b'\x01')
|
||||
b = DerivationParameters(salt=b'\x02')
|
||||
|
||||
self.assertFalse(a == b)
|
||||
self.assertFalse(b == a)
|
||||
|
||||
def test_equal_on_not_equal_iteration_count(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
DerivationParameters structs with different iteration counts.
|
||||
"""
|
||||
a = DerivationParameters(iteration_count=1)
|
||||
b = DerivationParameters(iteration_count=2)
|
||||
|
||||
self.assertFalse(a == b)
|
||||
self.assertFalse(b == a)
|
||||
|
||||
def test_equal_on_type_mismatch(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
DerivationParameters structs with different types.
|
||||
"""
|
||||
a = DerivationParameters()
|
||||
b = 'invalid'
|
||||
|
||||
self.assertFalse(a == b)
|
||||
self.assertFalse(b == a)
|
||||
|
||||
def test_not_equal_on_equal(self):
|
||||
"""
|
||||
Test that the inequality operator returns False when comparing two
|
||||
DerivationParameters structs with the same data.
|
||||
"""
|
||||
a = DerivationParameters()
|
||||
b = DerivationParameters()
|
||||
|
||||
self.assertTrue(a == b)
|
||||
self.assertTrue(b == a)
|
||||
|
||||
a = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
),
|
||||
initialization_vector=b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
derivation_data=b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
salt=b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
iteration_count=1000
|
||||
)
|
||||
b = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
),
|
||||
initialization_vector=b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
derivation_data=b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
salt=b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
iteration_count=1000
|
||||
)
|
||||
|
||||
self.assertFalse(a != b)
|
||||
self.assertFalse(b != a)
|
||||
|
||||
def test_not_equal_on_not_equal_cryptographic_parameters(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
DerivationParameters structs with different cryptographic parameters.
|
||||
"""
|
||||
a = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC
|
||||
)
|
||||
)
|
||||
b = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.GCM
|
||||
)
|
||||
)
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_not_equal_on_not_equal_initialization_vectors(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
DerivationParameters structs with different initialization vectors.
|
||||
"""
|
||||
a = DerivationParameters(initialization_vector=b'\x01')
|
||||
b = DerivationParameters(initialization_vector=b'\x02')
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_not_equal_on_not_equal_derivation_data(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
DerivationParameters structs with different derivation data.
|
||||
"""
|
||||
a = DerivationParameters(derivation_data=b'\x01')
|
||||
b = DerivationParameters(derivation_data=b'\x02')
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_not_equal_on_not_equal_salt(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
DerivationParameters structs with different salts.
|
||||
"""
|
||||
a = DerivationParameters(salt=b'\x01')
|
||||
b = DerivationParameters(salt=b'\x02')
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_not_equal_on_not_equal_iteration_counts(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
DerivationParameters structs with different iteration counts.
|
||||
"""
|
||||
a = DerivationParameters(iteration_count=1)
|
||||
b = DerivationParameters(iteration_count=2)
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_not_equal_on_type_mismatch(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
DerivationParameters structs with different types.
|
||||
"""
|
||||
a = DerivationParameters()
|
||||
b = 'invalid'
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_repr(self):
|
||||
"""
|
||||
Test that repr can be applied to a DerivationParameters struct.
|
||||
"""
|
||||
derivation_parameters = DerivationParameters(
|
||||
cryptographic_parameters=CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
),
|
||||
initialization_vector=b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
derivation_data=b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
salt=b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
iteration_count=10000
|
||||
)
|
||||
|
||||
expected = (
|
||||
"DerivationParameters("
|
||||
"cryptographic_parameters=CryptographicParameters("
|
||||
"block_cipher_mode=BlockCipherMode.CBC, "
|
||||
"padding_method=PaddingMethod.PKCS5, "
|
||||
"hashing_algorithm=HashingAlgorithm.SHA_1, "
|
||||
"key_role_type=KeyRoleType.KEK, "
|
||||
"digital_signature_algorithm="
|
||||
"DigitalSignatureAlgorithm.SHA256_WITH_RSA_ENCRYPTION, "
|
||||
"cryptographic_algorithm=CryptographicAlgorithm.AES, "
|
||||
"random_iv=True, "
|
||||
"iv_length=96, "
|
||||
"tag_length=128, "
|
||||
"fixed_field_length=32, "
|
||||
"invocation_field_length=64, "
|
||||
"counter_length=0, "
|
||||
"initial_counter_value=1), "
|
||||
"initialization_vector=" + str(
|
||||
b'\x01\x02\x03\x04\x05\x06\x07\x08'
|
||||
) + ", "
|
||||
"derivation_data=" + str(
|
||||
b'\x11\x22\x33\x44\x55\x66\x77\x88'
|
||||
) + ", "
|
||||
"salt=" + str(b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0') + ", "
|
||||
"iteration_count=10000)"
|
||||
)
|
||||
observed = repr(derivation_parameters)
|
||||
|
||||
self.assertEqual(expected, observed)
|
||||
|
||||
def test_str(self):
|
||||
"""
|
||||
Test that str can be applied to a DerivationParameters struct.
|
||||
"""
|
||||
cryptographic_parameters = CryptographicParameters(
|
||||
block_cipher_mode=enums.BlockCipherMode.CBC,
|
||||
padding_method=enums.PaddingMethod.PKCS5,
|
||||
hashing_algorithm=enums.HashingAlgorithm.SHA_1,
|
||||
key_role_type=enums.KeyRoleType.KEK,
|
||||
digital_signature_algorithm=enums.DigitalSignatureAlgorithm.
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
|
||||
random_iv=True,
|
||||
iv_length=96,
|
||||
tag_length=128,
|
||||
fixed_field_length=32,
|
||||
invocation_field_length=64,
|
||||
counter_length=0,
|
||||
initial_counter_value=1
|
||||
)
|
||||
derivation_parameters = DerivationParameters(
|
||||
cryptographic_parameters=cryptographic_parameters,
|
||||
initialization_vector=b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
derivation_data=b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
salt=b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
iteration_count=10000
|
||||
)
|
||||
|
||||
expected = str({
|
||||
'cryptographic_parameters': cryptographic_parameters,
|
||||
'initialization_vector': b'\x01\x02\x03\x04\x05\x06\x07\x08',
|
||||
'derivation_data': b'\x11\x22\x33\x44\x55\x66\x77\x88',
|
||||
'salt': b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0',
|
||||
'iteration_count': 10000
|
||||
})
|
||||
observed = str(derivation_parameters)
|
||||
|
||||
self.assertEqual(expected, observed)
|
||||
|
Loading…
Reference in New Issue
Block a user