Add managed objects hierarchy
Castellan will support multiple objects, not just symmetric keys. The bytes of the managed object are returned as bytestrings. Change-Id: If75ff5d458604a8210980a4f50d1e4fc27d2b037
This commit is contained in:
parent
573235913f
commit
39e139f88e
0
castellan/common/objects/__init__.py
Normal file
0
castellan/common/objects/__init__.py
Normal file
31
castellan/common/objects/certificate.py
Normal file
31
castellan/common/objects/certificate.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Base Certificate Class
|
||||||
|
|
||||||
|
This module defines the Certificate class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import abc
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from castellan.common.objects import managed_object
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class Certificate(managed_object.ManagedObject):
|
||||||
|
"""Base class to represent all certificates."""
|
@ -21,17 +21,19 @@ represent all encryption keys. The basis for this class was copied
|
|||||||
from Java.
|
from Java.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from castellan.common.objects import managed_object
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
class Key(object):
|
class Key(managed_object.ManagedObject):
|
||||||
"""Base class to represent all keys."""
|
"""Base class to represent all keys."""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractproperty
|
||||||
def get_algorithm(self):
|
def algorithm(self):
|
||||||
"""Returns the key's algorithm.
|
"""Returns the key's algorithm.
|
||||||
|
|
||||||
Returns the key's algorithm. For example, "DSA" indicates that this key
|
Returns the key's algorithm. For example, "DSA" indicates that this key
|
||||||
@ -39,15 +41,12 @@ class Key(object):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractproperty
|
||||||
def get_format(self):
|
def bit_length(self):
|
||||||
"""Returns the encoding format.
|
"""Returns the key's bit length.
|
||||||
|
|
||||||
Returns the key's encoding format or None if this key is not encoded.
|
Returns the key's bit length. For example, for AES symmetric keys,
|
||||||
|
this refers to the length of the key, and for RSA keys, this refers to
|
||||||
|
the length of the modulus.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def get_encoded(self):
|
|
||||||
"""Returns the key in the format specified by its encoding."""
|
|
||||||
pass
|
|
48
castellan/common/objects/managed_object.py
Normal file
48
castellan/common/objects/managed_object.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Copyright (c) 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Base ManagedObject Class
|
||||||
|
|
||||||
|
This module defines the ManagedObject class. The ManagedObject class
|
||||||
|
is the base class to represent all objects managed by the key manager.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import abc
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class ManagedObject(object):
|
||||||
|
"""Base class to represent all managed objects."""
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def format(self):
|
||||||
|
"""Returns the encoding format.
|
||||||
|
|
||||||
|
Returns the object's encoding format or None if this object is not
|
||||||
|
encoded.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_encoded(self):
|
||||||
|
"""Returns the encoded object.
|
||||||
|
|
||||||
|
Returns a bytestring object in a format represented in the encoding
|
||||||
|
specified.
|
||||||
|
"""
|
||||||
|
pass
|
52
castellan/common/objects/opaque_data.py
Normal file
52
castellan/common/objects/opaque_data.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Base OpaqueData Class
|
||||||
|
|
||||||
|
This module defines the OpaqueData class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from castellan.common.objects import managed_object
|
||||||
|
|
||||||
|
|
||||||
|
class OpaqueData(managed_object.ManagedObject):
|
||||||
|
"""This class represents opaque data."""
|
||||||
|
|
||||||
|
def __init__(self, data):
|
||||||
|
"""Create a new OpaqueData object.
|
||||||
|
|
||||||
|
Expected type for data is a bytestring.
|
||||||
|
"""
|
||||||
|
self._data = data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def format(self):
|
||||||
|
"""This method returns 'Opaque'."""
|
||||||
|
return "Opaque"
|
||||||
|
|
||||||
|
def get_encoded(self):
|
||||||
|
"""Returns the data in its original format."""
|
||||||
|
return self._data
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, OpaqueData):
|
||||||
|
return self._data == other._data
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
result = self.__eq__(other)
|
||||||
|
return not result
|
52
castellan/common/objects/passphrase.py
Normal file
52
castellan/common/objects/passphrase.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Base Passphrase Class
|
||||||
|
|
||||||
|
This module defines the Passphrase class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from castellan.common.objects import managed_object
|
||||||
|
|
||||||
|
|
||||||
|
class Passphrase(managed_object.ManagedObject):
|
||||||
|
"""This class represents a passphrase."""
|
||||||
|
|
||||||
|
def __init__(self, passphrase):
|
||||||
|
"""Create a new Passphrase object.
|
||||||
|
|
||||||
|
The expected type for the passphrase is a bytestring.
|
||||||
|
"""
|
||||||
|
self._passphrase = passphrase
|
||||||
|
|
||||||
|
@property
|
||||||
|
def format(self):
|
||||||
|
"""This method returns 'RAW'."""
|
||||||
|
return "RAW"
|
||||||
|
|
||||||
|
def get_encoded(self):
|
||||||
|
"""Returns the data in a bytestring."""
|
||||||
|
return self._passphrase
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, Passphrase):
|
||||||
|
return self._passphrase == other._passphrase
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
result = self.__eq__(other)
|
||||||
|
return not result
|
66
castellan/common/objects/private_key.py
Normal file
66
castellan/common/objects/private_key.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Base PrivateKey Class
|
||||||
|
|
||||||
|
This module defines the PrivateKey class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from castellan.common.objects import key
|
||||||
|
|
||||||
|
|
||||||
|
class PrivateKey(key.Key):
|
||||||
|
"""This class represents private keys."""
|
||||||
|
|
||||||
|
def __init__(self, algorithm, bit_length, key):
|
||||||
|
"""Create a new PrivateKey object.
|
||||||
|
|
||||||
|
The arguments specify the algorithm and bit length for the asymmetric
|
||||||
|
encryption and the bytes for the key in a bytestring.
|
||||||
|
"""
|
||||||
|
self._alg = algorithm
|
||||||
|
self._bit_length = bit_length
|
||||||
|
self._key = key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def algorithm(self):
|
||||||
|
"""Returns the algorithm for asymmetric encryption."""
|
||||||
|
return self._alg
|
||||||
|
|
||||||
|
@property
|
||||||
|
def format(self):
|
||||||
|
"""This method returns 'PKCS8'."""
|
||||||
|
return "PKCS8"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bit_length(self):
|
||||||
|
"""Returns the key length."""
|
||||||
|
return self._bit_length
|
||||||
|
|
||||||
|
def get_encoded(self):
|
||||||
|
"""Returns the key in DER encoded format."""
|
||||||
|
return self._key
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, PrivateKey):
|
||||||
|
return (self._alg == other._alg and
|
||||||
|
self._key == other._key)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
result = self.__eq__(other)
|
||||||
|
return not result
|
67
castellan/common/objects/public_key.py
Normal file
67
castellan/common/objects/public_key.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Base PublicKey Class
|
||||||
|
|
||||||
|
This module defines the PublicKey class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from castellan.common.objects import key
|
||||||
|
|
||||||
|
|
||||||
|
class PublicKey(key.Key):
|
||||||
|
"""This class represents public keys."""
|
||||||
|
|
||||||
|
def __init__(self, algorithm, bit_length, key):
|
||||||
|
"""Create a new PublicKey object.
|
||||||
|
|
||||||
|
The arguments specify the algorithm and bit length for the asymmetric
|
||||||
|
encryption and the bytes for the key. The bytes should be in a
|
||||||
|
bytestring.
|
||||||
|
"""
|
||||||
|
self._alg = algorithm
|
||||||
|
self._bit_length = bit_length
|
||||||
|
self._key = key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def algorithm(self):
|
||||||
|
"""Returns the algorithm for asymmetric encryption."""
|
||||||
|
return self._alg
|
||||||
|
|
||||||
|
@property
|
||||||
|
def format(self):
|
||||||
|
"""This method returns 'SubjectPublicKeyInfo'."""
|
||||||
|
return "SubjectPublicKeyInfo"
|
||||||
|
|
||||||
|
def get_encoded(self):
|
||||||
|
"""Returns the key in its encoded format."""
|
||||||
|
return self._key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bit_length(self):
|
||||||
|
"""Returns the key length."""
|
||||||
|
return self._bit_length
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, PublicKey):
|
||||||
|
return (self._alg == other._alg and
|
||||||
|
self._key == other._key)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
result = self.__eq__(other)
|
||||||
|
return not result
|
@ -19,41 +19,49 @@ Base SymmetricKey Class
|
|||||||
This module defines the SymmetricKey class.
|
This module defines the SymmetricKey class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from castellan.key_manager import key
|
from castellan.common.objects import key
|
||||||
|
|
||||||
|
|
||||||
class SymmetricKey(key.Key):
|
class SymmetricKey(key.Key):
|
||||||
"""This class represents symmetric keys."""
|
"""This class represents symmetric keys."""
|
||||||
|
|
||||||
def __init__(self, alg, key):
|
def __init__(self, algorithm, bit_length, key):
|
||||||
"""Create a new SymmetricKey object.
|
"""Create a new SymmetricKey object.
|
||||||
|
|
||||||
The arguments specify the algorithm for the symmetric encryption and
|
The arguments specify the algorithm and bit length for the symmetric
|
||||||
the bytes for the key.
|
encryption and the bytes for the key in a bytestring.
|
||||||
"""
|
"""
|
||||||
self.alg = alg
|
self._alg = algorithm
|
||||||
self.key = key
|
self._bit_length = bit_length
|
||||||
|
self._key = key
|
||||||
|
|
||||||
def get_algorithm(self):
|
@property
|
||||||
|
def algorithm(self):
|
||||||
"""Returns the algorithm for symmetric encryption."""
|
"""Returns the algorithm for symmetric encryption."""
|
||||||
return self.alg
|
return self._alg
|
||||||
|
|
||||||
def get_format(self):
|
@property
|
||||||
|
def format(self):
|
||||||
"""This method returns 'RAW'."""
|
"""This method returns 'RAW'."""
|
||||||
return "RAW"
|
return "RAW"
|
||||||
|
|
||||||
def get_encoded(self):
|
def get_encoded(self):
|
||||||
"""Returns the key in its encoded format."""
|
"""Returns the key in its encoded format."""
|
||||||
return self.key
|
return self._key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bit_length(self):
|
||||||
|
"""Returns the key length."""
|
||||||
|
return self._bit_length
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, SymmetricKey):
|
if isinstance(other, SymmetricKey):
|
||||||
return (self.alg == other.alg and
|
return (self._alg == other._alg and
|
||||||
self.key == other.key)
|
self._bit_length == other._bit_length and
|
||||||
return NotImplemented
|
self._key == other._key)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
result = self.__eq__(other)
|
result = self.__eq__(other)
|
||||||
if result is NotImplemented:
|
|
||||||
return result
|
|
||||||
return not result
|
return not result
|
52
castellan/common/objects/x_509.py
Normal file
52
castellan/common/objects/x_509.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
X509 Class
|
||||||
|
|
||||||
|
This module defines the X509 class, used to represent X.509 certificates.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from castellan.common.objects import certificate
|
||||||
|
|
||||||
|
|
||||||
|
class X509(certificate.Certificate):
|
||||||
|
"""This class represents X.509 certificates."""
|
||||||
|
|
||||||
|
def __init__(self, data):
|
||||||
|
"""Create a new X509 object.
|
||||||
|
|
||||||
|
The data should be in a bytestring.
|
||||||
|
"""
|
||||||
|
self._data = data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def format(self):
|
||||||
|
"""This method returns 'X.509'."""
|
||||||
|
return "X.509"
|
||||||
|
|
||||||
|
def get_encoded(self):
|
||||||
|
"""Returns the data in its encoded format."""
|
||||||
|
return self._data
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, X509):
|
||||||
|
return (self._data == other._data)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
result = self.__eq__(other)
|
||||||
|
return not result
|
@ -25,8 +25,8 @@ from oslo_log import log as logging
|
|||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
|
|
||||||
from castellan.common import exception
|
from castellan.common import exception
|
||||||
|
from castellan.common.objects import symmetric_key as sym_key
|
||||||
from castellan.key_manager import key_manager
|
from castellan.key_manager import key_manager
|
||||||
from castellan.key_manager import symmetric_key as key_manager_key
|
|
||||||
from castellan.openstack.common import _i18n as u
|
from castellan.openstack.common import _i18n as u
|
||||||
|
|
||||||
from six.moves import urllib
|
from six.moves import urllib
|
||||||
@ -152,8 +152,8 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
barbican_client = self._get_barbican_client(context)
|
barbican_client = self._get_barbican_client(context)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if key.get_algorithm():
|
if key.algorithm:
|
||||||
algorithm = key.get_algorithm()
|
algorithm = key.algorithm
|
||||||
encoded_key = key.get_encoded()
|
encoded_key = key.get_encoded()
|
||||||
# TODO(kfarr) add support for objects other than symmetric keys
|
# TODO(kfarr) add support for objects other than symmetric keys
|
||||||
secret = barbican_client.secrets.create(payload=encoded_key,
|
secret = barbican_client.secrets.create(payload=encoded_key,
|
||||||
@ -183,7 +183,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
secret = self._get_secret(context, key_id)
|
secret = self._get_secret(context, key_id)
|
||||||
secret_data = self._get_secret_data(secret)
|
secret_data = self._get_secret_data(secret)
|
||||||
# TODO(kfarr) modify to support other types of keys
|
# TODO(kfarr) modify to support other types of keys
|
||||||
key = key_manager_key.SymmetricKey(secret.algorithm, secret_data)
|
key = sym_key.SymmetricKey(secret.algorithm, secret_data)
|
||||||
copy_uuid = self.store_key(context, key, secret.expiration)
|
copy_uuid = self.store_key(context, key, secret.expiration)
|
||||||
return copy_uuid
|
return copy_uuid
|
||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
@ -266,7 +266,9 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
secret = self._get_secret(context, key_id)
|
secret = self._get_secret(context, key_id)
|
||||||
secret_data = self._get_secret_data(secret)
|
secret_data = self._get_secret_data(secret)
|
||||||
# TODO(kfarr) add support for other objects
|
# TODO(kfarr) add support for other objects
|
||||||
key = key_manager_key.SymmetricKey(secret.algorithm, secret_data)
|
key = sym_key.SymmetricKey(secret.algorithm,
|
||||||
|
secret.bit_length,
|
||||||
|
secret_data)
|
||||||
return key
|
return key
|
||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
|
@ -26,8 +26,8 @@ from keystoneclient.v3 import client
|
|||||||
from oslo_context import context
|
from oslo_context import context
|
||||||
|
|
||||||
from castellan.common import exception
|
from castellan.common import exception
|
||||||
|
from castellan.common.objects import symmetric_key
|
||||||
from castellan.key_manager import barbican_key_manager
|
from castellan.key_manager import barbican_key_manager
|
||||||
from castellan.key_manager import symmetric_key
|
|
||||||
from castellan.tests.functional import config
|
from castellan.tests.functional import config
|
||||||
from castellan.tests.functional.key_manager import test_key_manager
|
from castellan.tests.functional.key_manager import test_key_manager
|
||||||
|
|
||||||
|
@ -26,14 +26,13 @@ Keys created in one instance will not be accessible from other instances of
|
|||||||
this class.
|
this class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import array
|
|
||||||
import binascii
|
import binascii
|
||||||
import random
|
import random
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from castellan.common import exception
|
from castellan.common import exception
|
||||||
|
from castellan.common.objects import symmetric_key as sym_key
|
||||||
from castellan.key_manager import key_manager
|
from castellan.key_manager import key_manager
|
||||||
from castellan.key_manager import symmetric_key as sym_key
|
|
||||||
|
|
||||||
|
|
||||||
class MockKeyManager(key_manager.KeyManager):
|
class MockKeyManager(key_manager.KeyManager):
|
||||||
@ -52,8 +51,7 @@ class MockKeyManager(key_manager.KeyManager):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.keys = {}
|
self.keys = {}
|
||||||
|
|
||||||
def _generate_hex_key(self, **kwargs):
|
def _generate_hex_key(self, key_length):
|
||||||
key_length = kwargs.get('key_length', 256)
|
|
||||||
# hex digit => 4 bits
|
# hex digit => 4 bits
|
||||||
length = int(key_length / 4)
|
length = int(key_length / 4)
|
||||||
hex_encoded = self._generate_password(length=length,
|
hex_encoded = self._generate_password(length=length,
|
||||||
@ -61,10 +59,12 @@ class MockKeyManager(key_manager.KeyManager):
|
|||||||
return hex_encoded
|
return hex_encoded
|
||||||
|
|
||||||
def _generate_key(self, **kwargs):
|
def _generate_key(self, **kwargs):
|
||||||
_hex = self._generate_hex_key(**kwargs)
|
key_length = kwargs.get('key_length', 256)
|
||||||
|
_hex = self._generate_hex_key(key_length)
|
||||||
return sym_key.SymmetricKey(
|
return sym_key.SymmetricKey(
|
||||||
'AES',
|
'AES',
|
||||||
array.array('B', binascii.unhexlify(_hex)).tolist())
|
key_length,
|
||||||
|
bytes(binascii.unhexlify(_hex)))
|
||||||
|
|
||||||
def create_key(self, context, **kwargs):
|
def create_key(self, context, **kwargs):
|
||||||
"""Creates a key.
|
"""Creates a key.
|
||||||
|
@ -17,13 +17,11 @@
|
|||||||
Test cases for the barbican key manager.
|
Test cases for the barbican key manager.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import array
|
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from castellan.common import exception
|
from castellan.common import exception
|
||||||
|
from castellan.common.objects import symmetric_key as key_manager_key
|
||||||
from castellan.key_manager import barbican_key_manager
|
from castellan.key_manager import barbican_key_manager
|
||||||
from castellan.key_manager import symmetric_key as key_manager_key
|
|
||||||
from castellan.tests.unit.key_manager import test_key_manager
|
from castellan.tests.unit.key_manager import test_key_manager
|
||||||
|
|
||||||
|
|
||||||
@ -75,7 +73,8 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase):
|
|||||||
|
|
||||||
def fake_sym_key(alg, key):
|
def fake_sym_key(alg, key):
|
||||||
self.mock_symKey.get_encoded.return_value = key
|
self.mock_symKey.get_encoded.return_value = key
|
||||||
self.mock_symKey.get_algorithm.return_value = alg
|
p = mock.PropertyMock(return_value=alg)
|
||||||
|
type(self.mock_symKey).algorithm = p
|
||||||
return self.mock_symKey
|
return self.mock_symKey
|
||||||
self.original_key = key_manager_key.SymmetricKey
|
self.original_key = key_manager_key.SymmetricKey
|
||||||
key_manager_key.SymmetricKey = fake_sym_key
|
key_manager_key.SymmetricKey = fake_sym_key
|
||||||
@ -184,8 +183,10 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase):
|
|||||||
|
|
||||||
def test_store_key_base64(self):
|
def test_store_key_base64(self):
|
||||||
# Create Key to store
|
# Create Key to store
|
||||||
secret_key = array.array('B', [0x01, 0x02, 0xA0, 0xB3]).tolist()
|
secret_key = bytes(b'\x01\x02\xA0\xB3')
|
||||||
_key = key_manager_key.SymmetricKey('AES', secret_key)
|
_key = key_manager_key.SymmetricKey('AES',
|
||||||
|
len(secret_key) * 8,
|
||||||
|
secret_key)
|
||||||
|
|
||||||
# Define the return values
|
# Define the return values
|
||||||
secret = mock.Mock()
|
secret = mock.Mock()
|
||||||
@ -203,7 +204,9 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase):
|
|||||||
def test_store_key_plaintext(self):
|
def test_store_key_plaintext(self):
|
||||||
# Create the plaintext key
|
# Create the plaintext key
|
||||||
secret_key_text = "This is a test text key."
|
secret_key_text = "This is a test text key."
|
||||||
_key = key_manager_key.SymmetricKey('AES', secret_key_text)
|
_key = key_manager_key.SymmetricKey('AES',
|
||||||
|
len(secret_key_text) * 8,
|
||||||
|
secret_key_text)
|
||||||
|
|
||||||
# Store the Key
|
# Store the Key
|
||||||
self.key_mgr.store_key(self.ctxt, _key)
|
self.key_mgr.store_key(self.ctxt, _key)
|
||||||
|
@ -14,13 +14,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Test cases for the key classes.
|
Test cases for the symmetric key class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import array
|
from castellan.common.objects import symmetric_key as sym_key
|
||||||
import binascii
|
|
||||||
|
|
||||||
from castellan.key_manager import symmetric_key as sym_key
|
|
||||||
from castellan.tests import base
|
from castellan.tests import base
|
||||||
|
|
||||||
|
|
||||||
@ -38,22 +35,28 @@ class KeyTestCase(base.TestCase):
|
|||||||
class SymmetricKeyTestCase(KeyTestCase):
|
class SymmetricKeyTestCase(KeyTestCase):
|
||||||
|
|
||||||
def _create_key(self):
|
def _create_key(self):
|
||||||
return sym_key.SymmetricKey(self.algorithm, self.encoded)
|
return sym_key.SymmetricKey(self.algorithm,
|
||||||
|
self.bit_length,
|
||||||
|
self.encoded)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.algorithm = 'AES'
|
self.algorithm = 'AES'
|
||||||
self.encoded = array.array('B', binascii.unhexlify('0' * 64)).tolist()
|
self.encoded = bytes(b'0' * 64)
|
||||||
|
self.bit_length = len(self.encoded) * 8
|
||||||
|
|
||||||
super(SymmetricKeyTestCase, self).setUp()
|
super(SymmetricKeyTestCase, self).setUp()
|
||||||
|
|
||||||
def test_get_algorithm(self):
|
|
||||||
self.assertEqual(self.key.get_algorithm(), self.algorithm)
|
|
||||||
|
|
||||||
def test_get_format(self):
|
def test_get_format(self):
|
||||||
self.assertEqual(self.key.get_format(), 'RAW')
|
self.assertEqual('RAW', self.key.format)
|
||||||
|
|
||||||
def test_get_encoded(self):
|
def test_get_encoded(self):
|
||||||
self.assertEqual(self.key.get_encoded(), self.encoded)
|
self.assertEqual(self.encoded, self.key.get_encoded())
|
||||||
|
|
||||||
|
def test_get_algorithm(self):
|
||||||
|
self.assertEqual(self.algorithm, self.key.algorithm)
|
||||||
|
|
||||||
|
def test_get_bit_length(self):
|
||||||
|
self.assertEqual(self.bit_length, self.key.bit_length)
|
||||||
|
|
||||||
def test___eq__(self):
|
def test___eq__(self):
|
||||||
self.assertTrue(self.key == self.key)
|
self.assertTrue(self.key == self.key)
|
||||||
|
@ -17,13 +17,10 @@
|
|||||||
Test cases for the mock key manager.
|
Test cases for the mock key manager.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import array
|
|
||||||
import binascii
|
|
||||||
|
|
||||||
from oslo_context import context
|
from oslo_context import context
|
||||||
|
|
||||||
from castellan.common import exception
|
from castellan.common import exception
|
||||||
from castellan.key_manager import symmetric_key as sym_key
|
from castellan.common.objects import symmetric_key as sym_key
|
||||||
from castellan.tests.unit.key_manager import mock_key_manager as mock_key_mgr
|
from castellan.tests.unit.key_manager import mock_key_manager as mock_key_mgr
|
||||||
from castellan.tests.unit.key_manager import test_key_manager as test_key_mgr
|
from castellan.tests.unit.key_manager import test_key_manager as test_key_mgr
|
||||||
|
|
||||||
@ -55,8 +52,8 @@ class MockKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
|
|||||||
self.key_mgr.create_key, None)
|
self.key_mgr.create_key, None)
|
||||||
|
|
||||||
def test_store_and_get_key(self):
|
def test_store_and_get_key(self):
|
||||||
secret_key = array.array('B', binascii.unhexlify('0' * 64)).tolist()
|
secret_key = bytes(b'0' * 64)
|
||||||
_key = sym_key.SymmetricKey('AES', secret_key)
|
_key = sym_key.SymmetricKey('AES', 64 * 8, secret_key)
|
||||||
key_id = self.key_mgr.store_key(self.context, _key)
|
key_id = self.key_mgr.store_key(self.context, _key)
|
||||||
|
|
||||||
actual_key = self.key_mgr.get_key(self.context, key_id)
|
actual_key = self.key_mgr.get_key(self.context, key_id)
|
||||||
|
Loading…
Reference in New Issue
Block a user