# Path: castellan/common/exception.py
# _FATAL_EXCEPTION_FORMAT_ERRORS = False
# class RedirectException(Exception):
# class CastellanException(Exception):
# class Forbidden(CastellanException):
# class KeyManagerError(CastellanException):
# class ManagedObjectNotFoundError(CastellanException):
# class InvalidManagedObjectDictError(CastellanException):
# class UnknownManagedObjectTypeError(CastellanException):
# class AuthTypeInvalidError(CastellanException):
# class InsufficientCredentialDataError(CastellanException):
#     def __init__(self, url):
#     def __init__(self, message_arg=None, *args, **kwargs):
# 
# Path: castellan/common/objects/private_key.py
# class PrivateKey(key.Key):
#     def __init__(self, algorithm, bit_length, key,
#                  name=None, created=None, id=None):
#     def managed_type(cls):
#     def algorithm(self):
#     def format(self):
#     def bit_length(self):
#     def get_encoded(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
# 
# Path: castellan/common/objects/public_key.py
# class PublicKey(key.Key):
#     def __init__(self, algorithm, bit_length, key,
#                  name=None, created=None, id=None):
#     def managed_type(cls):
#     def algorithm(self):
#     def format(self):
#     def get_encoded(self):
#     def bit_length(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
# 
# Path: castellan/common/objects/symmetric_key.py
# class SymmetricKey(key.Key):
#     def __init__(self, algorithm, bit_length, key,
#                  name=None, created=None, id=None):
#     def managed_type(cls):
#     def algorithm(self):
#     def format(self):
#     def get_encoded(self):
#     def bit_length(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
# 
# Path: castellan/key_manager/key_manager.py
# class KeyManager(object, metaclass=abc.ABCMeta):
#     def __init__(self, configuration):
#     def create_key(self, context, algorithm, length,
#                    expiration=None, name=None):
#     def create_key_pair(self, context, algorithm, length,
#                         expiration=None, name=None):
#     def store(self, context, managed_object, expiration=None):
#     def get(self, context, managed_object_id, metadata_only=False):
#     def delete(self, context, managed_object_id):
#     def list(self, context, object_type=None, metadata_only=False):
#     def list_options_for_discovery(self):


import binascii
import copy
import random
from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from oslo_utils import uuidutils
from castellan.common import exception
from castellan.common.objects import private_key as pri_key
from castellan.common.objects import public_key as pub_key
from castellan.common.objects import symmetric_key as sym_key
from castellan.key_manager import key_manager


class MockKeyManager(key_manager.KeyManager):
    """Mocking manager for integration tests.

    This mock key manager implementation supports all the methods specified
    by the key manager interface. This implementation stores keys within a
    dictionary, and as a result, it is not acceptable for use across different
    services. Side effects (e.g., raising exceptions) for each method are
    handled as specified by the key manager interface.

    This key manager is not suitable for use in production deployments.
    """

    def __init__(self, configuration=None):
        self.conf = configuration
        self.keys = {}

    def _generate_hex_key(self, key_length):
        # hex digit => 4 bits
        length = int(key_length / 4)
        hex_encoded = self._generate_password(length=length,
                                              symbolgroups='0123456789ABCDEF')
        return hex_encoded

    def _generate_key(self, **kwargs):
        name = kwargs.get('name', None)
        algorithm = kwargs.get('algorithm', 'AES')
        key_length = kwargs.get('length', 256)
        _hex = self._generate_hex_key(key_length)

# Path: castellan/common/exception.py
# _FATAL_EXCEPTION_FORMAT_ERRORS = False
# class RedirectException(Exception):
# class CastellanException(Exception):
# class Forbidden(CastellanException):
# class KeyManagerError(CastellanException):
# class ManagedObjectNotFoundError(CastellanException):
# class InvalidManagedObjectDictError(CastellanException):
# class UnknownManagedObjectTypeError(CastellanException):
# class AuthTypeInvalidError(CastellanException):
# class InsufficientCredentialDataError(CastellanException):
#     def __init__(self, url):
#     def __init__(self, message_arg=None, *args, **kwargs):
# 
# Path: castellan/common/objects/private_key.py
# class PrivateKey(key.Key):
#     def __init__(self, algorithm, bit_length, key,
#                  name=None, created=None, id=None):
#     def managed_type(cls):
#     def algorithm(self):
#     def format(self):
#     def bit_length(self):
#     def get_encoded(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
# 
# Path: castellan/common/objects/public_key.py
# class PublicKey(key.Key):
#     def __init__(self, algorithm, bit_length, key,
#                  name=None, created=None, id=None):
#     def managed_type(cls):
#     def algorithm(self):
#     def format(self):
#     def get_encoded(self):
#     def bit_length(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
# 
# Path: castellan/common/objects/symmetric_key.py
# class SymmetricKey(key.Key):
#     def __init__(self, algorithm, bit_length, key,
#                  name=None, created=None, id=None):
#     def managed_type(cls):
#     def algorithm(self):
#     def format(self):
#     def get_encoded(self):
#     def bit_length(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
# 
# Path: castellan/key_manager/key_manager.py
# class KeyManager(object, metaclass=abc.ABCMeta):
#     def __init__(self, configuration):
#     def create_key(self, context, algorithm, length,
#                    expiration=None, name=None):
#     def create_key_pair(self, context, algorithm, length,
#                         expiration=None, name=None):
#     def store(self, context, managed_object, expiration=None):
#     def get(self, context, managed_object_id, metadata_only=False):
#     def delete(self, context, managed_object_id):
#     def list(self, context, object_type=None, metadata_only=False):
#     def list_options_for_discovery(self):


# Path: castellan/tests/unit/key_manager/mock_key_manager.py
import binascii
import copy
import random
from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from oslo_utils import uuidutils
from castellan.common import exception
from castellan.common.objects import private_key as pri_key
from castellan.common.objects import public_key as pub_key
from castellan.common.objects import symmetric_key as sym_key
from castellan.key_manager import key_manager



class MockKeyManager(key_manager.KeyManager):
    """Mocking manager for integration tests.

    This mock key manager implementation supports all the methods specified
    by the key manager interface. This implementation stores keys within a
    dictionary, and as a result, it is not acceptable for use across different
    services. Side effects (e.g., raising exceptions) for each method are
    handled as specified by the key manager interface.

    This key manager is not suitable for use in production deployments.
    """

    def __init__(self, configuration=None):
        self.conf = configuration
        self.keys = {}

    def _generate_hex_key(self, key_length):
        # hex digit => 4 bits
        length = int(key_length / 4)
        hex_encoded = self._generate_password(length=length,
                                              symbolgroups='0123456789ABCDEF')
        return hex_encoded

    def _generate_key(self, **kwargs):
        name = kwargs.get('name', None)
        algorithm = kwargs.get('algorithm', 'AES')
        key_length = kwargs.get('length', 256)
        _hex = self._generate_hex_key(key_length)

        return sym_key.SymmetricKey(