Adding secret data to the Pie object hierarchy

This change adds a SecretData class to the Pie object hierarchy. A unit
test suite covering the class is provided, as are updates to the Pie
object factory and associated tests.
This commit is contained in:
Peter Hamilton 2015-07-30 08:03:33 -04:00
parent ee7a6bc082
commit e497e1c37c
4 changed files with 463 additions and 62 deletions

View File

@ -60,6 +60,10 @@ class ObjectFactory:
return self._build_core_certificate(obj)
elif isinstance(obj, secrets.Certificate):
return self._build_pie_certificate(obj)
elif isinstance(obj, pobjects.SecretData):
return self._build_core_secret_data(obj)
elif isinstance(obj, secrets.SecretData):
return self._build_pie_secret_data(obj)
else:
raise TypeError("object type unsupported and cannot be converted")
@ -93,6 +97,12 @@ class ObjectFactory:
def _build_core_certificate(self, cert):
return secrets.Certificate(cert.certificate_type, cert.value)
def _build_pie_secret_data(self, secret):
secret_data_type = secret.secret_data_type.enum
value = secret.key_block.key_value.key_material.value
return pobjects.SecretData(value, secret_data_type)
def _build_core_key(self, key, cls):
algorithm = key.cryptographic_algorithm
length = key.cryptographic_length
@ -111,3 +121,20 @@ class ObjectFactory:
key_wrapping_data=None)
return cls(key_block)
def _build_core_secret_data(self, secret):
secret_data_type = secret.data_type
value = secret.value
key_material = cobjects.KeyMaterial(value)
key_value = cobjects.KeyValue(key_material)
key_block = cobjects.KeyBlock(
key_format_type=misc.KeyFormatType(enums.KeyFormatType.OPAQUE),
key_compression_type=None,
key_value=key_value,
cryptographic_algorithm=None,
cryptographic_length=None,
key_wrapping_data=None)
data_type = secrets.SecretData.SecretDataType(secret_data_type)
return secrets.SecretData(data_type, key_block)

View File

@ -753,3 +753,109 @@ class X509Certificate(Certificate):
return not (self == other)
else:
return NotImplemented
class SecretData(CryptographicObject):
"""
The SecretData class of the simplified KMIP object hierarchy.
SecretData is one of several CryptographicObjects and is one of the core
KMIP objects that are the subject of key management operations. For more
information, see Section 2.2 of the KMIP 1.1 specification.
Attributes:
cryptographic_usage_masks: A list of usage mask enumerations
describing how the CryptographicObject will be used.
data_type: The type of the secret value.
"""
def __init__(self, value, data_type, masks=None, name='Secret Data'):
"""
Create a SecretData object.
Args:
value(bytes): The bytes representing secret data.
data_type(SecretDataType): An enumeration defining the type of the
secret value.
masks(list): A list of CryptographicUsageMask enumerations
defining how the key will be used.
name(string): The string name of the key.
"""
super(SecretData, self).__init__()
self._object_type = enums.ObjectType.SECRET_DATA
self.value = value
self.data_type = data_type
self.names = [name]
if masks:
self.cryptographic_usage_masks = masks
else:
self.cryptographic_usage_masks = list()
# All remaining attributes are not considered part of the public API
# and are subject to change.
# The following attributes are placeholders for attributes that are
# unsupported by kmip.core
self.validate()
def validate(self):
"""
Verify that the contents of the SecretData object are valid.
Raises:
TypeError: if the types of any SecretData attributes are invalid.
"""
if not isinstance(self.value, bytes):
raise TypeError("secret value must be bytes")
elif not isinstance(self.data_type, enums.SecretDataType):
raise TypeError("secret data type must be a SecretDataType "
"enumeration")
elif not isinstance(self.cryptographic_usage_masks, list):
raise TypeError("secret data usage masks must be a list")
mask_count = len(self.cryptographic_usage_masks)
for i in range(mask_count):
mask = self.cryptographic_usage_masks[i]
if not isinstance(mask, enums.CryptographicUsageMask):
position = "({0} in list)".format(i)
raise TypeError(
"secret data mask {0} must be a CryptographicUsageMask "
"enumeration".format(position))
name_count = len(self.names)
for i in range(name_count):
name = self.names[i]
if not isinstance(name, six.string_types):
position = "({0} in list)".format(i)
raise TypeError("secret data name {0} must be a string".format(
position))
def __repr__(self):
value = "value={0}".format(binascii.hexlify(self.value))
data_type = "data_type={0}".format(self.data_type)
return "SecretData({0}, {1})".format(value, data_type)
def __str__(self):
return str(binascii.hexlify(self.value))
def __eq__(self, other):
if isinstance(other, SecretData):
if self.value != other.value:
return False
elif self.data_type != other.data_type:
return False
else:
return True
else:
return NotImplemented
def __ne__(self, other):
if isinstance(other, SecretData):
return not (self == other)
else:
return NotImplemented

View File

@ -0,0 +1,218 @@
# Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import binascii
import testtools
from kmip.core import enums
from kmip.pie import objects
class TestSecretData(testtools.TestCase):
"""
Test suite for SecretData.
"""
def setUp(self):
super(TestSecretData, self).setUp()
# Secret data taken from Sections 3.1.5 of the KMIP 1.1 testing
# documentation.
self.bytes_a = (
b'\x53\x65\x63\x72\x65\x74\x50\x61\x73\x73\x77\x6F\x72\x64')
self.bytes_b = (
b'\x53\x65\x63\x72\x65\x74\x50\x61\x73\x73\x77\x6F\x72\x65')
def tearDown(self):
super(TestSecretData, self).tearDown()
def test_init(self):
"""
Test that a SecretData object can be instantiated.
"""
secret = objects.SecretData(
self.bytes_a, enums.SecretDataType.PASSWORD)
self.assertEqual(secret.value, self.bytes_a)
self.assertEqual(secret.data_type, enums.SecretDataType.PASSWORD)
self.assertEqual(secret.cryptographic_usage_masks, list())
self.assertEqual(secret.names, ['Secret Data'])
def test_init_with_args(self):
"""
Test that a SecretData object can be instantiated with all arguments.
"""
key = objects.SecretData(
self.bytes_a,
enums.SecretDataType.PASSWORD,
masks=[enums.CryptographicUsageMask.VERIFY],
name='Test Secret Data')
self.assertEqual(key.value, self.bytes_a)
self.assertEqual(key.data_type, enums.SecretDataType.PASSWORD)
self.assertEqual(key.cryptographic_usage_masks,
[enums.CryptographicUsageMask.VERIFY])
self.assertEqual(key.names, ['Test Secret Data'])
def test_get_object_type(self):
"""
Test that the object type can be retrieved from the SecretData.
"""
expected = enums.ObjectType.SECRET_DATA
key = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
observed = key.object_type
self.assertEqual(expected, observed)
def test_validate_on_invalid_value(self):
"""
Test that a TypeError is raised when an invalid value is used to
construct a SecretData.
"""
args = (0, enums.SecretDataType.PASSWORD)
self.assertRaises(TypeError, objects.SecretData, *args)
def test_validate_on_invalid_data_type(self):
"""
Test that a TypeError is raised when an invalid data type is used to
construct a SecretData.
"""
args = (self.bytes_a, 'invalid')
self.assertRaises(TypeError, objects.SecretData, *args)
def test_validate_on_invalid_masks(self):
"""
Test that a TypeError is raised when an invalid masks value is used to
construct a SecretData.
"""
args = (self.bytes_a, enums.SecretDataType.PASSWORD)
kwargs = {'masks': 'invalid'}
self.assertRaises(TypeError, objects.SecretData, *args, **kwargs)
def test_validate_on_invalid_mask(self):
"""
Test that a TypeError is raised when an invalid mask value is used to
construct a SecretData.
"""
args = (self.bytes_a, enums.SecretDataType.PASSWORD)
kwargs = {'masks': ['invalid']}
self.assertRaises(TypeError, objects.SecretData, *args, **kwargs)
def test_validate_on_invalid_name(self):
"""
Test that a TypeError is raised when an invalid name value is used to
construct a SecretData.
"""
args = (self.bytes_a, enums.SecretDataType.PASSWORD)
kwargs = {'name': 0}
self.assertRaises(TypeError, objects.SecretData, *args, **kwargs)
def test_repr(self):
"""
Test that repr can be applied to a SecretData.
"""
key = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
args = "value={0}, data_type={1}".format(
binascii.hexlify(self.bytes_a), enums.SecretDataType.PASSWORD)
expected = "SecretData({0})".format(args)
observed = repr(key)
self.assertEqual(expected, observed)
def test_str(self):
"""
Test that str can be applied to a SecretData.
"""
key = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
expected = str(binascii.hexlify(self.bytes_a))
observed = str(key)
self.assertEqual(expected, observed)
def test_equal_on_equal(self):
"""
Test that the equality operator returns True when comparing two
SecretData objects with the same data.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
self.assertTrue(a == b)
self.assertTrue(b == a)
def test_equal_on_not_equal_value(self):
"""
Test that the equality operator returns False when comparing two
SecretData objects with different data.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = objects.SecretData(self.bytes_b, enums.SecretDataType.PASSWORD)
self.assertFalse(a == b)
self.assertFalse(b == a)
def test_equal_on_not_equal_data_type(self):
"""
Test that the equality operator returns False when comparing two
SecretData objects with different data.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = objects.SecretData(self.bytes_a, enums.SecretDataType.SEED)
self.assertFalse(a == b)
self.assertFalse(b == a)
def test_equal_on_type_mismatch(self):
"""
Test that the equality operator returns False when comparing a
SecretData object to a non-SecretData object.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
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 SecretData objects with the same internal data.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
self.assertFalse(a != b)
self.assertFalse(b != a)
def test_not_equal_on_not_equal_value(self):
"""
Test that the equality operator returns True when comparing two
SecretData objects with different data.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = objects.SecretData(self.bytes_b, enums.SecretDataType.PASSWORD)
self.assertTrue(a != b)
self.assertTrue(b != a)
def test_not_equal_on_not_equal_data_type(self):
"""
Test that the equality operator returns True when comparing two
SecretData objects with different data.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = objects.SecretData(self.bytes_a, enums.SecretDataType.SEED)
self.assertTrue(a != b)
self.assertTrue(b != a)
def test_not_equal_on_type_mismatch(self):
"""
Test that the equality operator returns True when comparing a
SecretData object to a non-SecretData object.
"""
a = objects.SecretData(self.bytes_a, enums.SecretDataType.PASSWORD)
b = "invalid"
self.assertTrue(a != b)
self.assertTrue(b != a)

View File

@ -34,59 +34,8 @@ class TestObjectFactory(testtools.TestCase):
super(TestObjectFactory, self).setUp()
self.factory = factory.ObjectFactory()
# Encodings obtained from Sections 13.2, 13.4 and 14.2 of the KMIP 1.1
# test documentation.
self.certificate_bytes = (
b'\x30\x82\x03\x12\x30\x82\x01\xFA\xA0\x03\x02\x01\x02\x02\x01\x01'
b'\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30'
b'\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D'
b'\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30'
b'\x0C\x06\x03\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30'
b'\x0B\x06\x03\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x1E\x17\x0D'
b'\x31\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x17\x0D\x32'
b'\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x30\x3B\x31\x0B'
b'\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D\x30\x0B\x06'
b'\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30\x0C\x06\x03'
b'\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30\x0B\x06\x03'
b'\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x82\x01\x22\x30\x0D\x06'
b'\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F'
b'\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F\x16\x1C\x00\x42'
b'\x49\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35\x35\x77\x76\x00'
b'\x3A\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A\x87\x55\xF8\x00'
b'\x2C\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7\x46\x48\x34\x6D'
b'\x75\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83\xBC\x4D\x7D\xC7'
b'\xEC\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0\x3F\xC6\x26\x7F'
b'\xA2\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8\x33\xE5\xA5\xF4'
b'\xBB\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA\x21\x49\x00\xDF'
b'\x8B\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67\x5A\xBD\xBC\x7D'
b'\x57\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B\x64\xE8\xA0\xEC'
b'\xC8\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4\x2E\x7B\xB8\xB7'
b'\xF4\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26\xEB\xA8\xDA\x7D'
b'\x0C\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09\xE9\xC1\xB7\xAE'
b'\x64\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06\xC5\xC8\xD7\xCC'
b'\xE8\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A\x29\xA8\x2D\x73'
b'\xA1\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E\xDA\x29\xC6\xFC'
b'\x41\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03\x01\x00\x01\xA3'
b'\x21\x30\x1F\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x04\xE5'
b'\x7B\xD2\xC4\x31\xB2\xE8\x16\xE1\x80\xA1\x98\x23\xFA\xC8\x58\x27'
b'\x3F\x6B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05'
b'\x00\x03\x82\x01\x01\x00\xA8\x76\xAD\xBC\x6C\x8E\x0F\xF0\x17\x21'
b'\x6E\x19\x5F\xEA\x76\xBF\xF6\x1A\x56\x7C\x9A\x13\xDC\x50\xD1\x3F'
b'\xEC\x12\xA4\x27\x3C\x44\x15\x47\xCF\xAB\xCB\x5D\x61\xD9\x91\xE9'
b'\x66\x31\x9D\xF7\x2C\x0D\x41\xBA\x82\x6A\x45\x11\x2F\xF2\x60\x89'
b'\xA2\x34\x4F\x4D\x71\xCF\x7C\x92\x1B\x4B\xDF\xAE\xF1\x60\x0D\x1B'
b'\xAA\xA1\x53\x36\x05\x7E\x01\x4B\x8B\x49\x6D\x4F\xAE\x9E\x8A\x6C'
b'\x1D\xA9\xAE\xB6\xCB\xC9\x60\xCB\xF2\xFA\xE7\x7F\x58\x7E\xC4\xBB'
b'\x28\x20\x45\x33\x88\x45\xB8\x8D\xD9\xAE\xEA\x53\xE4\x82\xA3\x6E'
b'\x73\x4E\x4F\x5F\x03\xB9\xD0\xDF\xC4\xCA\xFC\x6B\xB3\x4E\xA9\x05'
b'\x3E\x52\xBD\x60\x9E\xE0\x1E\x86\xD9\xB0\x9F\xB5\x11\x20\xC1\x98'
b'\x34\xA9\x97\xB0\x9C\xE0\x8D\x79\xE8\x13\x11\x76\x2F\x97\x4B\xB1'
b'\xC8\xC0\x91\x86\xC4\xD7\x89\x33\xE0\xDB\x38\xE9\x05\x08\x48\x77'
b'\xE1\x47\xC7\x8A\xF5\x2F\xAE\x07\x19\x2F\xF1\x66\xD1\x9F\xA9\x4A'
b'\x11\xCC\x11\xB2\x7E\xD0\x50\xF7\xA2\x7F\xAE\x13\xB2\x05\xA5\x74'
b'\xC4\xEE\x00\xAA\x8B\xD6\x5D\x0D\x70\x57\xC9\x85\xC8\x39\xEF\x33'
b'\x6A\x44\x1E\xD5\x3A\x53\xC6\xB6\xB6\x96\xF1\xBD\xEB\x5F\x7E\xA8'
b'\x11\xEB\xB2\x5A\x7F\x86')
# Key encoding obtained from Sections 3.1.5, 13.2, 13.4, and 14.2 of
# the KMIP 1.1 test documentation.
self.symmetric_bytes = (
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E'
b'\x0F')
@ -184,6 +133,59 @@ class TestObjectFactory(testtools.TestCase):
b'\x17\xE1\xF0\xC9\xB2\x3A\xFF\xA4\xD4\x96\x61\x8D\xBC\x02\x49\x86'
b'\xED\x69\x0B\xBB\x7B\x02\x57\x68\xFF\x9D\xF8\xAC\x15\x41\x6F\x48'
b'\x9F\x81\x29\xC3\x23\x41\xA8\xB4\x4F')
self.certificate_bytes = (
b'\x30\x82\x03\x12\x30\x82\x01\xFA\xA0\x03\x02\x01\x02\x02\x01\x01'
b'\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30'
b'\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D'
b'\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30'
b'\x0C\x06\x03\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30'
b'\x0B\x06\x03\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x1E\x17\x0D'
b'\x31\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x17\x0D\x32'
b'\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x30\x3B\x31\x0B'
b'\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D\x30\x0B\x06'
b'\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30\x0C\x06\x03'
b'\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30\x0B\x06\x03'
b'\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x82\x01\x22\x30\x0D\x06'
b'\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F'
b'\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F\x16\x1C\x00\x42'
b'\x49\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35\x35\x77\x76\x00'
b'\x3A\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A\x87\x55\xF8\x00'
b'\x2C\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7\x46\x48\x34\x6D'
b'\x75\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83\xBC\x4D\x7D\xC7'
b'\xEC\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0\x3F\xC6\x26\x7F'
b'\xA2\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8\x33\xE5\xA5\xF4'
b'\xBB\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA\x21\x49\x00\xDF'
b'\x8B\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67\x5A\xBD\xBC\x7D'
b'\x57\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B\x64\xE8\xA0\xEC'
b'\xC8\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4\x2E\x7B\xB8\xB7'
b'\xF4\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26\xEB\xA8\xDA\x7D'
b'\x0C\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09\xE9\xC1\xB7\xAE'
b'\x64\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06\xC5\xC8\xD7\xCC'
b'\xE8\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A\x29\xA8\x2D\x73'
b'\xA1\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E\xDA\x29\xC6\xFC'
b'\x41\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03\x01\x00\x01\xA3'
b'\x21\x30\x1F\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x04\xE5'
b'\x7B\xD2\xC4\x31\xB2\xE8\x16\xE1\x80\xA1\x98\x23\xFA\xC8\x58\x27'
b'\x3F\x6B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05'
b'\x00\x03\x82\x01\x01\x00\xA8\x76\xAD\xBC\x6C\x8E\x0F\xF0\x17\x21'
b'\x6E\x19\x5F\xEA\x76\xBF\xF6\x1A\x56\x7C\x9A\x13\xDC\x50\xD1\x3F'
b'\xEC\x12\xA4\x27\x3C\x44\x15\x47\xCF\xAB\xCB\x5D\x61\xD9\x91\xE9'
b'\x66\x31\x9D\xF7\x2C\x0D\x41\xBA\x82\x6A\x45\x11\x2F\xF2\x60\x89'
b'\xA2\x34\x4F\x4D\x71\xCF\x7C\x92\x1B\x4B\xDF\xAE\xF1\x60\x0D\x1B'
b'\xAA\xA1\x53\x36\x05\x7E\x01\x4B\x8B\x49\x6D\x4F\xAE\x9E\x8A\x6C'
b'\x1D\xA9\xAE\xB6\xCB\xC9\x60\xCB\xF2\xFA\xE7\x7F\x58\x7E\xC4\xBB'
b'\x28\x20\x45\x33\x88\x45\xB8\x8D\xD9\xAE\xEA\x53\xE4\x82\xA3\x6E'
b'\x73\x4E\x4F\x5F\x03\xB9\xD0\xDF\xC4\xCA\xFC\x6B\xB3\x4E\xA9\x05'
b'\x3E\x52\xBD\x60\x9E\xE0\x1E\x86\xD9\xB0\x9F\xB5\x11\x20\xC1\x98'
b'\x34\xA9\x97\xB0\x9C\xE0\x8D\x79\xE8\x13\x11\x76\x2F\x97\x4B\xB1'
b'\xC8\xC0\x91\x86\xC4\xD7\x89\x33\xE0\xDB\x38\xE9\x05\x08\x48\x77'
b'\xE1\x47\xC7\x8A\xF5\x2F\xAE\x07\x19\x2F\xF1\x66\xD1\x9F\xA9\x4A'
b'\x11\xCC\x11\xB2\x7E\xD0\x50\xF7\xA2\x7F\xAE\x13\xB2\x05\xA5\x74'
b'\xC4\xEE\x00\xAA\x8B\xD6\x5D\x0D\x70\x57\xC9\x85\xC8\x39\xEF\x33'
b'\x6A\x44\x1E\xD5\x3A\x53\xC6\xB6\xB6\x96\xF1\xBD\xEB\x5F\x7E\xA8'
b'\x11\xEB\xB2\x5A\x7F\x86')
self.secret_bytes = (
b'\x53\x65\x63\x72\x65\x74\x50\x61\x73\x73\x77\x6F\x72\x64')
def tearDown(self):
super(TestObjectFactory, self).tearDown()
@ -345,17 +347,53 @@ class TestObjectFactory(testtools.TestCase):
core_cert.certificate_type.enum, pie_cert.certificate_type)
self.assertEqual(core_cert.certificate_value.value, pie_cert.value)
def test_build_pie_certificate_on_invalid_type(self):
def test_convert_secret_data_pie_to_core(self):
"""
Test that a TypeError exception is raised when attempting to create a
Pie Certificate object from a core Certificate object with an
unsupported certificate type.
Test that a Pie secret data object can be converted into a core secret
data object.
"""
core_cert = secrets.Certificate(
enums.CertificateTypeEnum.PGP, self.certificate_bytes)
args = (core_cert, )
self.assertRaises(
TypeError, self.factory._build_pie_certificate, *args)
pie_secret = pobjects.SecretData(
self.secret_bytes, enums.SecretDataType.PASSWORD)
core_secret = self.factory.convert(pie_secret)
self.assertIsInstance(core_secret, secrets.SecretData)
data_type = core_secret.secret_data_type.enum
self.assertEqual(enums.SecretDataType.PASSWORD, data_type)
key_block = core_secret.key_block
self.assertIsInstance(key_block, cobjects.KeyBlock)
key_value = key_block.key_value
self.assertIsInstance(key_value, cobjects.KeyValue)
key_material = key_value.key_material
self.assertIsInstance(key_material, cobjects.KeyMaterial)
self.assertEqual(self.secret_bytes, key_material.value)
def test_convert_secret_data_core_to_pie(self):
"""
Test that a core secret data object can be converted into a Pie secret
data object.
"""
format_type = misc.KeyFormatType(enums.KeyFormatType.OPAQUE)
key_material = cobjects.KeyMaterial(self.secret_bytes)
key_value = cobjects.KeyValue(key_material)
key_block = cobjects.KeyBlock(
key_format_type=format_type,
key_compression_type=None,
key_value=key_value,
cryptographic_algorithm=None,
cryptographic_length=None,
key_wrapping_data=None)
data_type = secrets.SecretData.SecretDataType(
enums.SecretDataType.PASSWORD)
core_key = secrets.SecretData(data_type, key_block)
pie_key = self.factory.convert(core_key)
self.assertIsInstance(pie_key, pobjects.SecretData)
self.assertEqual(enums.SecretDataType.PASSWORD, pie_key.data_type)
self.assertEqual(self.secret_bytes, pie_key.value)
def test_build_pie_symmetric_key(self):
"""
@ -446,6 +484,18 @@ class TestObjectFactory(testtools.TestCase):
core_key, enums.CryptographicAlgorithm.AES, 128,
self.symmetric_bytes, enums.KeyFormatType.RAW)
def test_build_pie_certificate_on_invalid_type(self):
"""
Test that a TypeError exception is raised when attempting to create a
Pie Certificate object from a core Certificate object with an
unsupported certificate type.
"""
core_cert = secrets.Certificate(
enums.CertificateTypeEnum.PGP, self.certificate_bytes)
args = (core_cert, )
self.assertRaises(
TypeError, self.factory._build_pie_certificate, *args)
def _test_core_key(self, key, algorithm, length, value, format_type):
key_block = key.key_block
self.assertIsInstance(key_block, cobjects.KeyBlock)