Add the DerivationParameters struct

This change adds support for the DerivationParameters struct,
which is needed for DeriveKey support. Unit tests are included to
cover all newly added code.
This commit is contained in:
Peter Hamilton 2017-06-21 11:14:07 -04:00
parent 7b8bd4769c
commit ed22fb15f9
2 changed files with 1055 additions and 0 deletions

View File

@ -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
})

View File

@ -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)