Adding certificates to the Pie object hierarchy

This change adds certificate objects to the Pie object hierarchy,
specifically a generic Certificate class and an X509Certificate
subclass. Unit test suites covering both classes are included. The Pie
object factory is also updated to support Pie and core certificate
conversion.
This commit is contained in:
Peter Hamilton 2015-07-29 07:59:42 -04:00
parent 99d38fcd25
commit c9c58fb11b
5 changed files with 844 additions and 1 deletions

View File

@ -14,6 +14,7 @@
# under the License.
from kmip.core import attributes
from kmip.core import enums
from kmip.core import misc
from kmip.core import objects as cobjects
from kmip.core import secrets
@ -55,9 +56,22 @@ class ObjectFactory:
return self._build_core_key(obj, secrets.PrivateKey)
elif isinstance(obj, secrets.PrivateKey):
return self._build_pie_key(obj, pobjects.PrivateKey)
elif isinstance(obj, pobjects.Certificate):
return self._build_core_certificate(obj)
elif isinstance(obj, secrets.Certificate):
return self._build_pie_certificate(obj)
else:
raise TypeError("object type unsupported and cannot be converted")
def _build_pie_certificate(self, cert):
certificate_type = cert.certificate_type.enum
value = cert.certificate_value.value
if certificate_type == enums.CertificateTypeEnum.X_509:
return pobjects.X509Certificate(value)
else:
raise TypeError("core certificate type not supported")
def _build_pie_key(self, key, cls):
algorithm = key.key_block.cryptographic_algorithm.enum
length = key.key_block.cryptographic_length.value
@ -76,6 +90,9 @@ class ObjectFactory:
else:
return cls(algorithm, length, value, format_type)
def _build_core_certificate(self, cert):
return secrets.Certificate(cert.certificate_type, cert.value)
def _build_core_key(self, key, cls):
algorithm = key.cryptographic_algorithm
length = key.cryptographic_length

View File

@ -599,3 +599,157 @@ class PrivateKey(Key):
return not (self == other)
else:
return NotImplemented
class Certificate(CryptographicObject):
"""
The Certificate class of the simplified KMIP object hierarchy.
A Certificate is a core KMIP object that is the subject of key management
operations. For more information, see Section 2.2 of the KMIP 1.1
specification.
Attributes:
certificate_type: The type of the Certificate.
value: The bytes of the Certificate.
cryptographic_usage_masks: The list of usage mask flags for
Certificate application.
names: The list of string names of the Certificate.
"""
@abstractmethod
def __init__(self, certificate_type, value, masks=None,
name='Certificate'):
"""
Create a Certificate.
Args:
certificate_type(CertificateType): An enumeration defining the
type of the certificate.
value(bytes): The bytes representing the certificate.
masks(list): A list of CryptographicUsageMask enumerations
defining how the certificate will be used.
name(string): The string name of the certificate.
"""
super(Certificate, self).__init__()
self._object_type = enums.ObjectType.CERTIFICATE
self.value = value
self.certificate_type = certificate_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.
self._cryptographic_algorithm = None
self._cryptographic_length = None
self._certificate_length = None
# The following attributes are placeholders for attributes that are
# unsupported by kmip.core
self._cryptographic_parameters = list()
self._digital_signature_algorithm = list()
self.validate()
def validate(self):
"""
Verify that the contents of the Certificate object are valid.
Raises:
TypeError: if the types of any Certificate attributes are invalid.
"""
if not isinstance(self.value, bytes):
raise TypeError("certificate value must be bytes")
elif not isinstance(self.certificate_type,
enums.CertificateTypeEnum):
raise TypeError("certificate type must be a CertificateTypeEnum "
"enumeration")
elif not isinstance(self.cryptographic_usage_masks, list):
raise TypeError("certificate 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(
"certificate 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("certificate name {0} must be a string".format(
position))
def __str__(self):
return str(binascii.hexlify(self.value))
class X509Certificate(Certificate):
"""
The X509Certificate class of the simplified KMIP object hierarchy.
An X509Certificate is a core KMIP object that is the subject of key
management operations. For more information, see Section 2.2 of the KMIP
1.1 specification.
Attributes:
value: The bytes of the Certificate.
cryptographic_usage_masks: The list of usage mask flags for
Certificate application.
names: The list of string names of the Certificate.
"""
def __init__(self, value, masks=None, name='X.509 Certificate'):
"""
Create an X509Certificate.
Args:
value(bytes): The bytes representing the certificate.
masks(list): A list of CryptographicUsageMask enumerations
defining how the certificate will be used.
name(string): The string name of the certificate.
"""
super(X509Certificate, self).__init__(
enums.CertificateTypeEnum.X_509, value, masks, name)
# 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._x509_certificate_identifier = None
self._x509_certificate_subject = None
self._x509_certificate_issuer = None
self.validate()
def __repr__(self):
certificate_type = "certificate_type={0}".format(self.certificate_type)
value = "value={0}".format(binascii.hexlify(self.value))
return "X509Certificate({0}, {1})".format(certificate_type, value)
def __eq__(self, other):
if isinstance(other, X509Certificate):
if self.value != other.value:
return False
else:
return True
else:
return NotImplemented
def __ne__(self, other):
if isinstance(other, X509Certificate):
return not (self == other)
else:
return NotImplemented

View File

@ -0,0 +1,291 @@
# 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 testtools
from kmip.core import enums
from kmip.pie import objects
class DummyCertificate(objects.Certificate):
"""
A dummy Certificate subclass for testing purposes.
"""
def __init__(self, certificate_type, value, masks=None,
name='Certificate'):
"""
Create a DummyCertificate.
"""
super(DummyCertificate, self).__init__(
certificate_type, value, masks, name)
def validate(self):
super(DummyCertificate, self).validate()
def __repr__(self):
return ''
def __str__(self):
return ''
def __eq__(self, other):
return True
def __ne__(self, other):
return False
class TestCertificate(testtools.TestCase):
"""
Test suite for Certificate.
Since Certificate is an ABC abstract class, all tests are run against a
dummy subclass defined above, DummyCertificate.
"""
def setUp(self):
super(TestCertificate, self).setUp()
# Certificate values taken from Sections 13.2 and 13.4 of the KMIP 1.1
# testing documentation.
self.bytes_a = (
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.bytes_b = (
b'\x30\x82\x03\x26\x30\x82\x02\x0E\xA0\x03\x02\x01\x02\x02\x14\x6D'
b'\x0C\x0F\x4F\x2F\xEF\xEA\xF0\xD2\x3D\x3B\xA2\x5D\x2F\x70\xF5\xEA'
b'\x4A\xEF\xCB\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05'
b'\x05\x00\x30\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55'
b'\x53\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54'
b'\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53'
b'\x31\x0D\x30\x0B\x06\x03\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30'
b'\x1E\x17\x0D\x31\x32\x30\x34\x32\x37\x31\x30\x31\x34\x34\x31\x5A'
b'\x17\x0D\x31\x33\x30\x34\x32\x37\x31\x30\x31\x34\x34\x31\x5A\x30'
b'\x3C\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\x41\x43\x4D\x45\x31\x0D\x30'
b'\x0B\x06\x03\x55\x04\x0B\x13\x04\x4B\x4D\x49\x50\x31\x0F\x30\x0D'
b'\x06\x03\x55\x04\x03\x13\x06\x43\x6C\x69\x65\x6E\x74\x30\x82\x01'
b'\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00'
b'\x03\x82\x01\x0F\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F'
b'\x16\x1C\x00\x42\x49\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35'
b'\x35\x77\x76\x00\x3A\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A'
b'\x87\x55\xF8\x00\x2C\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7'
b'\x46\x48\x34\x6D\x75\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83'
b'\xBC\x4D\x7D\xC7\xEC\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0'
b'\x3F\xC6\x26\x7F\xA2\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8'
b'\x33\xE5\xA5\xF4\xBB\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA'
b'\x21\x49\x00\xDF\x8B\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67'
b'\x5A\xBD\xBC\x7D\x57\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B'
b'\x64\xE8\xA0\xEC\xC8\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4'
b'\x2E\x7B\xB8\xB7\xF4\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26'
b'\xEB\xA8\xDA\x7D\x0C\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09'
b'\xE9\xC1\xB7\xAE\x64\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06'
b'\xC5\xC8\xD7\xCC\xE8\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A'
b'\x29\xA8\x2D\x73\xA1\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E'
b'\xDA\x29\xC6\xFC\x41\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03'
b'\x01\x00\x01\xA3\x21\x30\x1F\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16'
b'\x04\x14\x04\xE5\x7B\xD2\xC4\x31\xB2\xE8\x16\xE1\x80\xA1\x98\x23'
b'\xFA\xC8\x58\x27\x3F\x6B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D'
b'\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x51\xE9\xCC\x2F\x09\x00'
b'\xCD\x9C\x71\xE7\xDD\x3E\x40\x79\x33\xCA\xCC\xA2\x99\xE6\xC4\x1F'
b'\xA0\x25\x16\x38\x6E\x92\x8F\x50\x6B\x04\x06\x2C\xCE\x90\x44\x4E'
b'\xDE\xC9\x33\xCA\xBA\x74\xB9\x90\xAB\x08\x47\xC7\xB7\x32\x78\xD3'
b'\x88\xA3\x49\xF9\x9F\x29\x6B\xF4\x58\xEC\x2C\x2C\x16\x3E\x8D\x87'
b'\xBB\xEE\x47\xD2\x33\xB9\x14\x96\x61\xDD\x9A\x4C\x0A\xE5\x59\x25'
b'\x2A\x5D\xE1\xDF\xEB\x69\xCF\xB7\x71\x38\xCB\xE0\xBB\x45\xB9\x11'
b'\xFC\x0E\xF6\x75\xC3\x7B\x74\x92\x75\x54\x58\x36\xE3\x3C\xF7\x38'
b'\x78\x23\x97\xAF\x4B\xC3\x70\x7A\xC1\x4A\xBA\x57\x24\xE0\x83\xBD'
b'\xB0\xD2\x8F\xD2\x74\x7C\xDD\x8B\xCA\x74\xCE\x92\x56\x92\xF4\xD0'
b'\x6C\x0D\x2B\x74\xD8\xD2\xB5\x40\xB7\xA1\x08\x31\x89\xE5\xE0\xF4'
b'\x9F\x0B\x74\x06\x54\xD7\xD9\xF3\xFA\xA9\xB4\xC0\xF9\x05\x6F\xE4'
b'\xF5\x2E\x4B\xEE\x81\x2F\xE4\x86\x19\x4C\xCD\x47\x8D\x65\x95\x7B'
b'\xA6\x3F\xBC\xB0\xC3\x1F\x87\x02\x83\xAB\x4E\x84\x9C\x20\x99\x3D'
b'\x6B\xEC\xB0\xF2\x70\x55\xB1\x03\xAF\x3B\x66\x75\xD1\x23\xCD\x3B'
b'\x71\x79\xA4\x6C\x77\xC7\x3A\xE0\x0F\xFD\xEF\xA9\xB1\x25\xDA\x07'
b'\x1E\xAD\x10\xD8\x5E\xAD\x0D\x0D\x44\x1F')
def tearDown(self):
super(TestCertificate, self).tearDown()
def test_init_certificate(self):
"""
Test that direct instantiation of a Certificate fails.
"""
args = (enums.CertificateTypeEnum.X_509, self.bytes_a)
self.assertRaises(TypeError, objects.Certificate, *args)
def test_init(self):
"""
Test that a complete subclass of Certificate can be instantiated.
"""
certificate = DummyCertificate(
enums.CertificateTypeEnum.X_509, self.bytes_a)
self.assertEqual(
certificate.certificate_type, enums.CertificateTypeEnum.X_509)
self.assertEqual(certificate.value, self.bytes_a)
self.assertEqual(certificate.cryptographic_usage_masks, list())
self.assertEqual(certificate.names, ['Certificate'])
def test_init_with_args(self):
"""
Test that a complete subclass of Certificate can be instantiated with
all arguments.
"""
cert = DummyCertificate(
enums.CertificateTypeEnum.X_509,
self.bytes_a,
masks=[enums.CryptographicUsageMask.ENCRYPT,
enums.CryptographicUsageMask.VERIFY],
name='Test Certificate')
self.assertEqual(
cert.certificate_type, enums.CertificateTypeEnum.X_509)
self.assertEqual(cert.value, self.bytes_a)
self.assertEqual(cert.cryptographic_usage_masks,
[enums.CryptographicUsageMask.ENCRYPT,
enums.CryptographicUsageMask.VERIFY])
self.assertEqual(cert.names, ['Test Certificate'])
def test_get_object_type(self):
"""
Test that the object type can be retrieved from a complete subclass
of Certificate.
"""
expected = enums.ObjectType.CERTIFICATE
cert = DummyCertificate(enums.CertificateTypeEnum.X_509, self.bytes_a)
observed = cert.object_type
self.assertEqual(expected, observed)
def test_validate_on_invalid_certificate_type(self):
"""
Test that a TypeError is raised when an invalid certificate type is
used to construct a complete subclass of Certificate.
"""
args = ('invalid', self.bytes_a)
self.assertRaises(TypeError, DummyCertificate, *args)
def test_validate_on_invalid_value(self):
"""
Test that a TypeError is raised when an invalid length value is used
to construct a complete subclass of Certificate.
"""
args = (enums.CertificateTypeEnum.X_509, 0)
self.assertRaises(TypeError, DummyCertificate, *args)
def test_validate_on_invalid_masks(self):
"""
Test that a TypeError is raised when an invalid masks value is used to
construct a complete subclass of Certificate.
"""
args = (enums.CertificateTypeEnum.X_509, self.bytes_a)
kwargs = {'masks': 'invalid'}
self.assertRaises(TypeError, DummyCertificate, *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 complete subclass of Certificate.
"""
args = (enums.CertificateTypeEnum.X_509, self.bytes_a)
kwargs = {'masks': ['invalid']}
self.assertRaises(TypeError, DummyCertificate, *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 complete subclass of Certificate.
"""
args = (enums.CertificateTypeEnum.X_509, self.bytes_a)
kwargs = {'name': 0}
self.assertRaises(TypeError, DummyCertificate, *args, **kwargs)
def test_repr(self):
"""
Test that repr can be applied to a complete subclass of Certificate.
"""
dummy = DummyCertificate(enums.CertificateTypeEnum.X_509, self.bytes_a)
repr(dummy)
def test_str(self):
"""
Test that str can be applied to a complete subclass of Certificate.
"""
dummy = DummyCertificate(enums.CertificateTypeEnum.X_509, self.bytes_a)
str(dummy)
def test_eq(self):
"""
Test that equality can be applied to a complete subclass of
Certificate.
"""
dummy = DummyCertificate(enums.CertificateTypeEnum.X_509, self.bytes_a)
self.assertTrue(dummy == dummy)
def test_ne(self):
"""
Test that inequality can be applied to a complete subclass of
Certificate.
"""
dummy = DummyCertificate(enums.CertificateTypeEnum.X_509, self.bytes_a)
self.assertFalse(dummy != dummy)

View File

@ -0,0 +1,293 @@
# 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 TestX509Certificate(testtools.TestCase):
"""
Test suite for X509Certificate.
"""
def setUp(self):
super(TestX509Certificate, self).setUp()
# Certificate values taken from Sections 13.2 and 13.4 of the KMIP 1.1
# testing documentation.
self.bytes_a = (
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.bytes_b = (
b'\x30\x82\x03\x26\x30\x82\x02\x0E\xA0\x03\x02\x01\x02\x02\x14\x6D'
b'\x0C\x0F\x4F\x2F\xEF\xEA\xF0\xD2\x3D\x3B\xA2\x5D\x2F\x70\xF5\xEA'
b'\x4A\xEF\xCB\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05'
b'\x05\x00\x30\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55'
b'\x53\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54'
b'\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53'
b'\x31\x0D\x30\x0B\x06\x03\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30'
b'\x1E\x17\x0D\x31\x32\x30\x34\x32\x37\x31\x30\x31\x34\x34\x31\x5A'
b'\x17\x0D\x31\x33\x30\x34\x32\x37\x31\x30\x31\x34\x34\x31\x5A\x30'
b'\x3C\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\x41\x43\x4D\x45\x31\x0D\x30'
b'\x0B\x06\x03\x55\x04\x0B\x13\x04\x4B\x4D\x49\x50\x31\x0F\x30\x0D'
b'\x06\x03\x55\x04\x03\x13\x06\x43\x6C\x69\x65\x6E\x74\x30\x82\x01'
b'\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00'
b'\x03\x82\x01\x0F\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F'
b'\x16\x1C\x00\x42\x49\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35'
b'\x35\x77\x76\x00\x3A\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A'
b'\x87\x55\xF8\x00\x2C\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7'
b'\x46\x48\x34\x6D\x75\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83'
b'\xBC\x4D\x7D\xC7\xEC\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0'
b'\x3F\xC6\x26\x7F\xA2\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8'
b'\x33\xE5\xA5\xF4\xBB\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA'
b'\x21\x49\x00\xDF\x8B\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67'
b'\x5A\xBD\xBC\x7D\x57\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B'
b'\x64\xE8\xA0\xEC\xC8\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4'
b'\x2E\x7B\xB8\xB7\xF4\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26'
b'\xEB\xA8\xDA\x7D\x0C\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09'
b'\xE9\xC1\xB7\xAE\x64\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06'
b'\xC5\xC8\xD7\xCC\xE8\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A'
b'\x29\xA8\x2D\x73\xA1\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E'
b'\xDA\x29\xC6\xFC\x41\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03'
b'\x01\x00\x01\xA3\x21\x30\x1F\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16'
b'\x04\x14\x04\xE5\x7B\xD2\xC4\x31\xB2\xE8\x16\xE1\x80\xA1\x98\x23'
b'\xFA\xC8\x58\x27\x3F\x6B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D'
b'\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x51\xE9\xCC\x2F\x09\x00'
b'\xCD\x9C\x71\xE7\xDD\x3E\x40\x79\x33\xCA\xCC\xA2\x99\xE6\xC4\x1F'
b'\xA0\x25\x16\x38\x6E\x92\x8F\x50\x6B\x04\x06\x2C\xCE\x90\x44\x4E'
b'\xDE\xC9\x33\xCA\xBA\x74\xB9\x90\xAB\x08\x47\xC7\xB7\x32\x78\xD3'
b'\x88\xA3\x49\xF9\x9F\x29\x6B\xF4\x58\xEC\x2C\x2C\x16\x3E\x8D\x87'
b'\xBB\xEE\x47\xD2\x33\xB9\x14\x96\x61\xDD\x9A\x4C\x0A\xE5\x59\x25'
b'\x2A\x5D\xE1\xDF\xEB\x69\xCF\xB7\x71\x38\xCB\xE0\xBB\x45\xB9\x11'
b'\xFC\x0E\xF6\x75\xC3\x7B\x74\x92\x75\x54\x58\x36\xE3\x3C\xF7\x38'
b'\x78\x23\x97\xAF\x4B\xC3\x70\x7A\xC1\x4A\xBA\x57\x24\xE0\x83\xBD'
b'\xB0\xD2\x8F\xD2\x74\x7C\xDD\x8B\xCA\x74\xCE\x92\x56\x92\xF4\xD0'
b'\x6C\x0D\x2B\x74\xD8\xD2\xB5\x40\xB7\xA1\x08\x31\x89\xE5\xE0\xF4'
b'\x9F\x0B\x74\x06\x54\xD7\xD9\xF3\xFA\xA9\xB4\xC0\xF9\x05\x6F\xE4'
b'\xF5\x2E\x4B\xEE\x81\x2F\xE4\x86\x19\x4C\xCD\x47\x8D\x65\x95\x7B'
b'\xA6\x3F\xBC\xB0\xC3\x1F\x87\x02\x83\xAB\x4E\x84\x9C\x20\x99\x3D'
b'\x6B\xEC\xB0\xF2\x70\x55\xB1\x03\xAF\x3B\x66\x75\xD1\x23\xCD\x3B'
b'\x71\x79\xA4\x6C\x77\xC7\x3A\xE0\x0F\xFD\xEF\xA9\xB1\x25\xDA\x07'
b'\x1E\xAD\x10\xD8\x5E\xAD\x0D\x0D\x44\x1F')
def tearDown(self):
super(TestX509Certificate, self).tearDown()
def test_init(self):
"""
Test that an X509Certificate object can be instantiated.
"""
certificate = objects.X509Certificate(self.bytes_a)
self.assertEqual(
certificate.certificate_type, enums.CertificateTypeEnum.X_509)
self.assertEqual(certificate.value, self.bytes_a)
self.assertEqual(certificate.cryptographic_usage_masks, list())
self.assertEqual(certificate.names, ['X.509 Certificate'])
def test_init_with_args(self):
"""
Test that an X509Certificate object can be instantiated with all
arguments.
"""
cert = objects.X509Certificate(
self.bytes_a,
masks=[enums.CryptographicUsageMask.ENCRYPT,
enums.CryptographicUsageMask.VERIFY],
name='Test X.509 Certificate')
self.assertEqual(
cert.certificate_type, enums.CertificateTypeEnum.X_509)
self.assertEqual(cert.value, self.bytes_a)
self.assertEqual(cert.cryptographic_usage_masks,
[enums.CryptographicUsageMask.ENCRYPT,
enums.CryptographicUsageMask.VERIFY])
self.assertEqual(cert.names, ['Test X.509 Certificate'])
def test_get_object_type(self):
"""
Test that the object type can be retrieved from the X509Certificate.
"""
expected = enums.ObjectType.CERTIFICATE
cert = objects.X509Certificate(self.bytes_a)
observed = cert.object_type
self.assertEqual(expected, observed)
def test_validate_on_invalid_value(self):
"""
Test that a TypeError is raised when an invalid length value is used
to construct a X509Certificate.
"""
args = (0, )
self.assertRaises(TypeError, objects.X509Certificate, *args)
def test_validate_on_invalid_masks(self):
"""
Test that a TypeError is raised when an invalid masks value is used to
construct a X509Certificate.
"""
args = (self.bytes_a, )
kwargs = {'masks': 'invalid'}
self.assertRaises(TypeError, objects.X509Certificate, *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 X509Certificate.
"""
args = (self.bytes_a, )
kwargs = {'masks': ['invalid']}
self.assertRaises(TypeError, objects.X509Certificate, *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 X509Certificate.
"""
args = (self.bytes_a, )
kwargs = {'name': 0}
self.assertRaises(TypeError, objects.X509Certificate, *args, **kwargs)
def test_repr(self):
"""
Test that repr can be applied to a X509Certificate.
"""
cert = objects.X509Certificate(self.bytes_a)
args = "certificate_type={0}, value={1}".format(
enums.CertificateTypeEnum.X_509, binascii.hexlify(self.bytes_a))
expected = "X509Certificate({0})".format(args)
observed = repr(cert)
self.assertEqual(expected, observed)
def test_str(self):
"""
Test that str can be applied to a X509Certificate.
"""
cert = objects.X509Certificate(self.bytes_a)
expected = str(binascii.hexlify(self.bytes_a))
observed = str(cert)
self.assertEqual(expected, observed)
def test_equal_on_equal(self):
"""
Test that the equality operator returns True when comparing two
X509Certificate objects with the same data.
"""
a = objects.X509Certificate(self.bytes_a)
b = objects.X509Certificate(self.bytes_a)
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
X509Certificate objects with different data.
"""
a = objects.X509Certificate(self.bytes_a)
b = objects.X509Certificate(self.bytes_b)
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
X509Certificate object to a non-PrivateKey object.
"""
a = objects.X509Certificate(self.bytes_a)
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 X509Certificate objects with the same internal data.
"""
a = objects.X509Certificate(self.bytes_a)
b = objects.X509Certificate(self.bytes_a)
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
X509Certificate objects with different data.
"""
a = objects.X509Certificate(self.bytes_a)
b = objects.X509Certificate(self.bytes_b)
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
X509Certificate object to a non-PrivateKey object.
"""
a = objects.X509Certificate(self.bytes_a)
b = "invalid"
self.assertTrue(a != b)
self.assertTrue(b != a)

View File

@ -34,8 +34,59 @@ class TestObjectFactory(testtools.TestCase):
super(TestObjectFactory, self).setUp()
self.factory = factory.ObjectFactory()
# Key encoding obtained from Sections 13.4 and 14.2 of the KMIP 1.1
# 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')
self.symmetric_bytes = (
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E'
b'\x0F')
@ -269,6 +320,43 @@ class TestObjectFactory(testtools.TestCase):
pie_key, algorithm.enum, length.value, self.private_bytes,
format_type.enum)
def test_convert_certificate_pie_to_core(self):
"""
Test that a Pie certificate can be converted into a core certificate.
"""
pie_cert = pobjects.X509Certificate(self.certificate_bytes)
core_cert = self.factory.convert(pie_cert)
self.assertIsInstance(core_cert, secrets.Certificate)
self.assertEqual(
pie_cert.certificate_type, core_cert.certificate_type.enum)
self.assertEqual(pie_cert.value, core_cert.certificate_value.value)
def test_convert_certificate_core_to_pie(self):
"""
Test that a core certificate can be converted into a Pie certificate.
"""
core_cert = secrets.Certificate(
enums.CertificateTypeEnum.X_509, self.certificate_bytes)
pie_cert = self.factory.convert(core_cert)
self.assertIsInstance(pie_cert, pobjects.X509Certificate)
self.assertEqual(
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):
"""
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_build_pie_symmetric_key(self):
"""
Test that a core SymmetricKey object can be converted into a Pie