mirror of https://github.com/OpenKMIP/PyKMIP.git
Adding support for the Certificate managed object
This change polishes and reorganizes the implementation of the Certificate managed object and its required subclasses. It adds in documentation and test suites for all modified classes and updates the SecretFactory to support creating default Certificate objects.
This commit is contained in:
parent
883a36f22a
commit
195671d4bf
|
@ -15,6 +15,7 @@
|
|||
|
||||
from kmip.core import enums
|
||||
|
||||
from kmip.core.enums import CertificateTypeEnum
|
||||
from kmip.core.enums import HashingAlgorithm as HashingAlgorithmEnum
|
||||
from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum
|
||||
from kmip.core.enums import Tags
|
||||
|
@ -283,16 +284,28 @@ class CryptographicParameters(Struct):
|
|||
pass
|
||||
|
||||
|
||||
# 3.8
|
||||
class CertificateType(Enumeration):
|
||||
ENUM_TYPE = enums.CertificateType
|
||||
"""
|
||||
An encodeable wrapper for the CertificateType enumeration.
|
||||
|
||||
def __init__(self, value=None):
|
||||
super(self.__class__, self).__init__(value,
|
||||
Tags.CERTIFICATE_TYPE)
|
||||
Used to specify the type of the encoded bytes of a Certificate Managed
|
||||
Object. See Sections 2.2.1 and 3.8 of the KMIP v1.1 specification for more
|
||||
information.
|
||||
"""
|
||||
ENUM_TYPE = enums.CertificateTypeEnum
|
||||
|
||||
def __init__(self, value=CertificateTypeEnum.X_509):
|
||||
"""
|
||||
Construct a CertificateType object.
|
||||
|
||||
Args:
|
||||
value (CertificateTypeEnum): A CertificateTypeEnum enumeration
|
||||
value, (e.g., CertificateTypeEnum.PGP). Optional, defaults to
|
||||
CertificateTypeEnum.X_509.
|
||||
"""
|
||||
super(CertificateType, self).__init__(value, Tags.CERTIFICATE_TYPE)
|
||||
|
||||
|
||||
# 3.17
|
||||
class DigestValue(ByteString):
|
||||
"""
|
||||
A byte string representing the hash value of a Digest.
|
||||
|
|
|
@ -349,7 +349,12 @@ class WrappingMethod(Enum):
|
|||
|
||||
|
||||
# 9.1.3.2.6
|
||||
class CertificateType(Enum):
|
||||
class CertificateTypeEnum(Enum):
|
||||
"""
|
||||
The type of a Certificate Managed Object.
|
||||
|
||||
For more information, see Section 2.2.1 of the KMIP 1.1 specification.
|
||||
"""
|
||||
X_509 = 0x00000001
|
||||
PGP = 0x00000002
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ from kmip.core.objects import KeyMaterial
|
|||
from kmip.core.objects import KeyWrappingData
|
||||
from kmip.core.objects import KeyValue
|
||||
|
||||
from kmip.core.secrets import Certificate
|
||||
from kmip.core.secrets import OpaqueObject
|
||||
from kmip.core.secrets import PrivateKey
|
||||
from kmip.core.secrets import PublicKey
|
||||
|
@ -68,7 +69,7 @@ class SecretFactory(object):
|
|||
SymmetricKey(...)
|
||||
"""
|
||||
if secret_type is ObjectType.CERTIFICATE:
|
||||
return self._create_certificate(value)
|
||||
return self._create_certificate()
|
||||
elif secret_type is ObjectType.SYMMETRIC_KEY:
|
||||
return self._create_symmetric_key(value)
|
||||
elif secret_type is ObjectType.PUBLIC_KEY:
|
||||
|
@ -87,8 +88,8 @@ class SecretFactory(object):
|
|||
raise TypeError("Unrecognized secret type: {0}".format(
|
||||
secret_type))
|
||||
|
||||
def _create_certificate(self, value):
|
||||
raise NotImplementedError()
|
||||
def _create_certificate(self):
|
||||
return Certificate()
|
||||
|
||||
def _create_symmetric_key(self, value):
|
||||
if value is None:
|
||||
|
|
|
@ -17,6 +17,7 @@ from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum
|
|||
from kmip.core.enums import Tags
|
||||
from kmip.core.enums import QueryFunction as QueryFunctionEnum
|
||||
|
||||
from kmip.core.primitives import ByteString
|
||||
from kmip.core.primitives import Enumeration
|
||||
from kmip.core.primitives import Interval
|
||||
from kmip.core.primitives import Struct
|
||||
|
@ -25,6 +26,27 @@ from kmip.core.primitives import TextString
|
|||
from kmip.core.utils import BytearrayStream
|
||||
|
||||
|
||||
class CertificateValue(ByteString):
|
||||
"""
|
||||
The bytes of a DER-encoded X.509 public key certificate.
|
||||
|
||||
Used by the Certificate Managed Object to store the bytes of the
|
||||
certificate. See Section 2.2.1 of the KMIP 1.1. specification for more
|
||||
information.
|
||||
"""
|
||||
|
||||
def __init__(self, value=b''):
|
||||
"""
|
||||
Construct a CertificateValue byte string.
|
||||
|
||||
Args:
|
||||
value (bytes): A byte string (e.g., b'\x00\x01...') containing the
|
||||
certificate bytes to store. Optional, defaults to the empty
|
||||
byte string.
|
||||
"""
|
||||
super(CertificateValue, self).__init__(value, Tags.CERTIFICATE_VALUE)
|
||||
|
||||
|
||||
class Offset(Interval):
|
||||
"""
|
||||
An integer representing a positive change in time.
|
||||
|
|
|
@ -420,8 +420,7 @@ class Enumeration(Integer):
|
|||
return "{0}(value={1})".format(type(self).__name__, self.enum)
|
||||
|
||||
def __str__(self):
|
||||
return "{0} - {1} - {2}".format(
|
||||
type(self.enum), self.enum.name, self.enum.value)
|
||||
return "{0}.{1}".format(type(self.enum).__name__, self.enum.name)
|
||||
|
||||
|
||||
class Boolean(Base):
|
||||
|
|
|
@ -18,6 +18,8 @@ from kmip.core.attributes import CertificateType
|
|||
from kmip.core import enums
|
||||
from kmip.core.enums import Tags
|
||||
|
||||
from kmip.core.misc import CertificateValue
|
||||
|
||||
from kmip.core.objects import Attribute
|
||||
from kmip.core.objects import KeyBlock
|
||||
|
||||
|
@ -33,52 +35,102 @@ from kmip.core.utils import BytearrayStream
|
|||
# 2.2
|
||||
# 2.2.1
|
||||
class Certificate(Struct):
|
||||
"""
|
||||
A structure representing a DER-encoded X.509 public key certificate.
|
||||
|
||||
class CertificateValue(ByteString):
|
||||
See Section 2.2.1 of the KMIP 1.1 specification for more information.
|
||||
|
||||
def __init__(self, value=None):
|
||||
super(self.__class__, self).__init__(value,
|
||||
Tags.CERTIFICATE_VALUE)
|
||||
Attributes:
|
||||
certificate_type: The type of the certificate.
|
||||
certificate_value: The bytes of the certificate.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
certificate_type=None,
|
||||
certificate_value=None):
|
||||
super(self.__class__, self).__init__(Tags.CERTIFICATE)
|
||||
self.certificate_type = certificate_type
|
||||
self.certificate_value = certificate_value
|
||||
self.validate()
|
||||
"""
|
||||
Construct a Certificate object.
|
||||
|
||||
Args:
|
||||
certificate_type (CertificateTypeEnum): The type of the
|
||||
certificate. Optional, defaults to None.
|
||||
certificate_value (bytes): The bytes of the certificate. Optional,
|
||||
defaults to None.
|
||||
"""
|
||||
super(Certificate, self).__init__(Tags.CERTIFICATE)
|
||||
|
||||
if certificate_type is None:
|
||||
self.certificate_type = CertificateType()
|
||||
else:
|
||||
self.certificate_type = CertificateType(certificate_type)
|
||||
|
||||
if certificate_value is None:
|
||||
self.certificate_value = CertificateValue()
|
||||
else:
|
||||
self.certificate_value = CertificateValue(certificate_value)
|
||||
|
||||
def read(self, istream):
|
||||
super(self.__class__, self).read(istream)
|
||||
"""
|
||||
Read the data encoding the Certificate object and decode it into its
|
||||
constituent parts.
|
||||
|
||||
Args:
|
||||
istream (Stream): A data stream containing encoded object data,
|
||||
supporting a read method; usually a BytearrayStream object.
|
||||
"""
|
||||
super(Certificate, self).read(istream)
|
||||
tstream = BytearrayStream(istream.read(self.length))
|
||||
|
||||
self.certificate_type = CertificateType()
|
||||
self.certificate_value = Certificate.CertificateValue()
|
||||
self.certificate_value = CertificateValue()
|
||||
|
||||
self.certificate_type.read(tstream)
|
||||
self.certificate_value.read(tstream)
|
||||
|
||||
self.is_oversized(tstream)
|
||||
self.validate()
|
||||
|
||||
def write(self, ostream):
|
||||
"""
|
||||
Write the data encoding the Certificate object to a stream.
|
||||
|
||||
Args:
|
||||
ostream (Stream): A data stream in which to encode object data,
|
||||
supporting a write method; usually a BytearrayStream object.
|
||||
"""
|
||||
tstream = BytearrayStream()
|
||||
|
||||
# Write the details of the certificate
|
||||
self.certificate_type.write(tstream)
|
||||
self.certificate_value.write(tstream)
|
||||
|
||||
# Write the length and value of the template attribute
|
||||
self.length = tstream.length()
|
||||
super(self.__class__, self).write(ostream)
|
||||
super(Certificate, self).write(ostream)
|
||||
ostream.write(tstream.buffer)
|
||||
|
||||
def validate(self):
|
||||
self.__validate()
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, Certificate):
|
||||
if self.certificate_type != other.certificate_type:
|
||||
return False
|
||||
elif self.certificate_value != other.certificate_value:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return NotImplemented
|
||||
|
||||
def __validate(self):
|
||||
# TODO (peter-hamilton) Finish implementation.
|
||||
pass
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, Certificate):
|
||||
return not (self == other)
|
||||
else:
|
||||
return NotImplemented
|
||||
|
||||
def __repr__(self):
|
||||
return "{0}(certificate_type={1}, certificate_value=b'{2}')".format(
|
||||
type(self).__name__,
|
||||
str(self.certificate_type),
|
||||
str(self.certificate_value))
|
||||
|
||||
def __str__(self):
|
||||
return "{0}".format(str(self.certificate_value))
|
||||
|
||||
|
||||
# 2.2.2
|
||||
|
|
|
@ -17,10 +17,12 @@ from testtools import TestCase
|
|||
|
||||
from kmip.core.attributes import ApplicationData
|
||||
from kmip.core.attributes import ApplicationNamespace
|
||||
from kmip.core.attributes import CertificateType
|
||||
from kmip.core.attributes import DigestValue
|
||||
from kmip.core.attributes import HashingAlgorithm
|
||||
from kmip.core.attributes import OperationPolicyName
|
||||
|
||||
from kmip.core.enums import CertificateTypeEnum
|
||||
from kmip.core.enums import HashingAlgorithm as HashingAlgorithmEnum
|
||||
|
||||
from kmip.core.utils import BytearrayStream
|
||||
|
@ -140,6 +142,50 @@ class TestHashingAlgorithm(TestCase):
|
|||
self._test_init("invalid")
|
||||
|
||||
|
||||
# TODO (peter-hamilton) Replace with generic Enumeration subclass test suite.
|
||||
class TestCertificateType(TestCase):
|
||||
"""
|
||||
A test suite for the CertificateType class.
|
||||
|
||||
Since CertificateType is a simple wrapper for the Enumeration primitive,
|
||||
only a few tests pertaining to construction are needed.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCertificateType, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestCertificateType, self).tearDown()
|
||||
|
||||
def _test_init(self, value):
|
||||
if (isinstance(value, CertificateTypeEnum)) or (value is None):
|
||||
if value is None:
|
||||
certificate_type = CertificateType()
|
||||
value = CertificateTypeEnum.X_509
|
||||
else:
|
||||
certificate_type = CertificateType(value)
|
||||
|
||||
msg = "expected {0}, observed {1}".format(
|
||||
value, certificate_type.enum)
|
||||
self.assertEqual(value, certificate_type.enum, msg)
|
||||
else:
|
||||
self.assertRaises(TypeError, CertificateType, value)
|
||||
|
||||
def test_init_with_none(self):
|
||||
"""
|
||||
Test that a CertificateType object can be constructed with no specified
|
||||
value.
|
||||
"""
|
||||
self._test_init(None)
|
||||
|
||||
def test_init_with_valid(self):
|
||||
"""
|
||||
Test that a CertificateType object can be constructed with valid byte
|
||||
data.
|
||||
"""
|
||||
self._test_init(CertificateTypeEnum.PGP)
|
||||
|
||||
|
||||
class TestDigestValue(TestCase):
|
||||
"""
|
||||
A test suite for the DigestValue class.
|
||||
|
|
|
@ -13,17 +13,63 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from six import binary_type
|
||||
from six import string_types
|
||||
|
||||
from testtools import TestCase
|
||||
|
||||
from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum
|
||||
from kmip.core.enums import QueryFunction as QueryFunctionEnum
|
||||
|
||||
from kmip.core.misc import CertificateValue
|
||||
from kmip.core.misc import KeyFormatType
|
||||
from kmip.core.misc import QueryFunction
|
||||
from kmip.core.misc import VendorIdentification
|
||||
|
||||
|
||||
# TODO (peter-hamilton) Replace with generic ByteString subclass test suite.
|
||||
class TestCertificateValue(TestCase):
|
||||
"""
|
||||
A test suite for the CertificateValue class.
|
||||
|
||||
Since CertificateValue is a simple wrapper for the ByteString primitive,
|
||||
only a few tests pertaining to construction are needed.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCertificateValue, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestCertificateValue, self).tearDown()
|
||||
|
||||
def _test_init(self, value):
|
||||
if (isinstance(value, binary_type)) or (value is None):
|
||||
certificate_value = CertificateValue(value)
|
||||
|
||||
if value is None:
|
||||
value = b''
|
||||
|
||||
msg = "expected {0}, observed {1}".format(
|
||||
value, certificate_value.value)
|
||||
self.assertEqual(value, certificate_value.value, msg)
|
||||
else:
|
||||
self.assertRaises(TypeError, CertificateValue, value)
|
||||
|
||||
def test_init_with_none(self):
|
||||
"""
|
||||
Test that a CertificateValue object can be constructed with no
|
||||
specified value.
|
||||
"""
|
||||
self._test_init(None)
|
||||
|
||||
def test_init_with_valid(self):
|
||||
"""
|
||||
Test that a CertificateValue object can be constructed with a valid,
|
||||
byte-string value.
|
||||
"""
|
||||
self._test_init(b'\x00\x01\x02')
|
||||
|
||||
|
||||
class TestQueryFunction(TestCase):
|
||||
"""
|
||||
A test suite for the QueryFunction class.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# 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.
|
|
@ -0,0 +1,378 @@
|
|||
# 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.
|
||||
|
||||
from testtools import TestCase
|
||||
|
||||
from kmip.core.attributes import CertificateType
|
||||
from kmip.core.enums import CertificateTypeEnum
|
||||
from kmip.core.misc import CertificateValue
|
||||
from kmip.core.secrets import Certificate
|
||||
from kmip.core.utils import BytearrayStream
|
||||
|
||||
|
||||
class TestCertificate(TestCase):
|
||||
"""
|
||||
A test suite for the Certificate class.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCertificate, self).setUp()
|
||||
|
||||
self.certificate_type_a = None
|
||||
self.certificate_type_b = CertificateTypeEnum.X_509
|
||||
|
||||
# Encodings obtained from Section 13.2 of KMIP 1.1 Test Cases document.
|
||||
self.certificate_value_a = None
|
||||
self.certificate_value_b = (
|
||||
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.encoding_a = BytearrayStream((
|
||||
b'\x42\x00\x13\x01\x00\x00\x00\x18\x42\x00\x1D\x05\x00\x00\x00\x04'
|
||||
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x1E\x08\x00\x00\x00'
|
||||
b'\x00'))
|
||||
self.encoding_b = BytearrayStream((
|
||||
b'\x42\x00\x13\x01\x00\x00\x03\x30\x42\x00\x1D\x05\x00\x00\x00\x04'
|
||||
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x1E\x08\x00\x00\x03\x16'
|
||||
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\x00\x00'))
|
||||
|
||||
def tearDown(self):
|
||||
super(TestCertificate, self).tearDown()
|
||||
|
||||
def test_init(self):
|
||||
pass
|
||||
|
||||
def _test_read(self, stream, certificate_type, certificate_value):
|
||||
certificate = Certificate()
|
||||
certificate.read(stream)
|
||||
|
||||
if certificate_type is None:
|
||||
expected = CertificateType()
|
||||
else:
|
||||
expected = CertificateType(certificate_type)
|
||||
|
||||
observed = certificate.certificate_type
|
||||
|
||||
msg = "certificate type encoding mismatch; "
|
||||
msg += "expected {0}, observed {1}".format(expected, observed)
|
||||
self.assertEqual(expected, observed)
|
||||
|
||||
if certificate_value is None:
|
||||
expected = CertificateValue()
|
||||
else:
|
||||
expected = CertificateValue(certificate_value)
|
||||
|
||||
observed = certificate.certificate_value
|
||||
|
||||
msg = "certificate value encoding mismatch; "
|
||||
msg += "expected {0}, observed {1}".format(expected, observed)
|
||||
self.assertEqual(expected, observed, msg)
|
||||
|
||||
def test_read_a(self):
|
||||
"""
|
||||
Test that a Certificate object with no data can be read from a data
|
||||
stream.
|
||||
"""
|
||||
self._test_read(self.encoding_a, self.certificate_type_a,
|
||||
self.certificate_value_a)
|
||||
|
||||
def test_read_b(self):
|
||||
"""
|
||||
Test that a Certificate object with data can be read from a data
|
||||
stream.
|
||||
"""
|
||||
self._test_read(self.encoding_b, self.certificate_type_b,
|
||||
self.certificate_value_b)
|
||||
|
||||
def _test_write(self, stream, certificate_type, certificate_value):
|
||||
certificate = Certificate(
|
||||
certificate_type=certificate_type,
|
||||
certificate_value=certificate_value)
|
||||
|
||||
expected = stream
|
||||
observed = BytearrayStream()
|
||||
|
||||
certificate.write(observed)
|
||||
|
||||
msg = "encoding mismatch;\nexpected:\n{0}\nobserved:\n{1}".format(
|
||||
expected, observed)
|
||||
self.assertEqual(expected, observed, msg)
|
||||
|
||||
def test_write_a(self):
|
||||
"""
|
||||
Test that a Certificate object with no data can be written to a data
|
||||
stream.
|
||||
"""
|
||||
self._test_write(self.encoding_a, self.certificate_type_a,
|
||||
self.certificate_value_a)
|
||||
|
||||
def test_write_b(self):
|
||||
"""
|
||||
Test that a Certificate object with data can be written to a data
|
||||
stream.
|
||||
"""
|
||||
self._test_write(self.encoding_b, self.certificate_type_b,
|
||||
self.certificate_value_b)
|
||||
|
||||
def test_equal_on_equal(self):
|
||||
"""
|
||||
Test that the equality operator returns True when comparing two
|
||||
Certificate objects with the same internal data.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
b = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
|
||||
self.assertTrue(a == b)
|
||||
self.assertTrue(b == a)
|
||||
|
||||
def test_equal_on_equal_and_empty(self):
|
||||
"""
|
||||
Test that the equality operator returns True when comparing two
|
||||
Certificate objects with no internal data.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
b = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
|
||||
self.assertTrue(a == b)
|
||||
self.assertTrue(b == a)
|
||||
|
||||
def test_equal_on_not_equal(self):
|
||||
"""
|
||||
Test that the equality operator returns False when comparing two
|
||||
Certificate objects with different sets of internal data.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
b = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_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
|
||||
Certificate object with a non-Certificate object.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_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
|
||||
Certificate objects with the same internal data.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
b = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
|
||||
self.assertFalse(a != b)
|
||||
self.assertFalse(b != a)
|
||||
|
||||
def test_not_equal_on_equal_and_empty(self):
|
||||
"""
|
||||
Test that the inequality operator returns False when comparing two
|
||||
Certificate objects with no internal data.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
b = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
|
||||
self.assertFalse(a != b)
|
||||
self.assertFalse(b != a)
|
||||
|
||||
def test_not_equal_on_not_equal(self):
|
||||
"""
|
||||
Test that the inequality operator returns True when comparing two
|
||||
Certificate objects with different sets of internal data.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
b = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
|
||||
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 a
|
||||
Certificate object with a non-Certificate object.
|
||||
"""
|
||||
a = Certificate(
|
||||
certificate_type=self.certificate_type_a,
|
||||
certificate_value=self.certificate_value_a)
|
||||
b = "invalid"
|
||||
|
||||
self.assertTrue(a != b)
|
||||
self.assertTrue(b != a)
|
||||
|
||||
def test_repr(self):
|
||||
"""
|
||||
Test that the representation of a Certificate object with data is
|
||||
formatted properly.
|
||||
"""
|
||||
certificate = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
|
||||
certificate_type = "certificate_type={0}".format(
|
||||
str(self.certificate_type_b))
|
||||
certificate_value = "certificate_value=b'{0}'".format(
|
||||
str(self.certificate_value_b))
|
||||
|
||||
expected = "Certificate({0}, {1})".format(
|
||||
certificate_type, certificate_value)
|
||||
observed = repr(certificate)
|
||||
|
||||
msg = "\nexpected:\n{0}\nobserved:\n{1}".format(expected, observed)
|
||||
self.assertEqual(expected, observed, msg)
|
||||
|
||||
# NOTE (peter-hamilton) Testing with eval won't work due to null bytes.
|
||||
|
||||
def test_str(self):
|
||||
"""
|
||||
Test that the string representation of a Certificate object is
|
||||
formatted properly.
|
||||
"""
|
||||
certificate = Certificate(
|
||||
certificate_type=self.certificate_type_b,
|
||||
certificate_value=self.certificate_value_b)
|
||||
|
||||
expected = str(self.certificate_value_b)
|
||||
observed = str(certificate)
|
||||
|
||||
msg = "expected:\n{0}\nobserved:\n{1}".format(expected, observed)
|
||||
self.assertEqual(expected, observed, msg)
|
Loading…
Reference in New Issue