Example #1
0
    def delete(self, context, key_id):
        """Represents deleting the key."""

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = _("User is not authorized to use key manager.")
            raise exception.Forbidden(msg)

        if not key_id:
            raise exception.KeyManagerError('key identifier not provided')

        headers = {'X-Vault-Token': self._root_token_id}
        try:
            resource_url = self._get_url() + 'v1/secret/' + key_id
            resp = self._session.delete(resource_url,
                                        verify=self._verify_server,
                                        headers=headers)
        except requests.exceptions.Timeout as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except requests.exceptions.ConnectionError as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except Exception as ex:
            raise exception.KeyManagerError(six.text_type(ex))

        if resp.status_code in _EXCEPTIONS_BY_CODE:
            raise exception.KeyManagerError(resp.reason)
        if resp.status_code == requests.codes['forbidden']:
            raise exception.Forbidden()
        if resp.status_code == requests.codes['not_found']:
            raise exception.ManagedObjectNotFoundError(uuid=key_id)
Example #2
0
    def list(self, context, object_type=None, metadata_only=False):
        """Lists the managed objects given the criteria."""

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = _("User is not authorized to use key manager.")
            raise exception.Forbidden(msg)

        if object_type and object_type not in self._secret_type_dict:
            msg = _("Invalid secret type: %s") % object_type
            raise exception.KeyManagerError(reason=msg)

        resp = self._do_http_request(self._session.get,
                                     self._get_resource_url())

        if resp.status_code == requests.codes['not_found']:
            keys = []
        else:
            keys = resp.json()['data']['keys']

        objects = []
        for obj_id in keys:
            try:
                obj = self.get(context, obj_id, metadata_only=metadata_only)
                if object_type is None or isinstance(obj, object_type):
                    objects.append(obj)
            except exception.ManagedObjectNotFoundError as e:
                LOG.warning(
                    _("Error occurred while retrieving object "
                      "metadata, not adding it to the list: %s"), e)
                pass
        return objects
Example #3
0
    def _store_key_value(self, key_id, value):

        type_value = self._secret_type_dict.get(type(value))
        if type_value is None:
            raise exception.KeyManagerError("Unknown type for value : %r" %
                                            value)

        record = {
            'type':
            type_value,
            'value':
            binascii.hexlify(value.get_encoded()).decode('utf-8'),
            'algorithm':
            (value.algorithm if hasattr(value, 'algorithm') else None),
            'bit_length':
            (value.bit_length if hasattr(value, 'bit_length') else None),
            'name':
            value.name,
            'created':
            value.created
        }
        if self._get_api_version() != '1':
            record = {'data': record}

        self._do_http_request(self._session.post,
                              self._get_resource_url(key_id),
                              json=record)

        return key_id
Example #4
0
    def _create_base_url(self, auth, sess, endpoint):
        api_version = None
        if self.conf.barbican.barbican_api_version:
            api_version = self.conf.barbican.barbican_api_version
        elif getattr(auth, 'service_catalog', None):
            endpoint_data = auth.service_catalog.endpoint_data_for(
                service_type='key-manager')
            api_version = endpoint_data.api_version
        elif getattr(auth, 'get_discovery', None):
            discovery = auth.get_discovery(sess, url=endpoint)
            raw_data = discovery.raw_version_data()
            if len(raw_data) == 0:
                msg = _(
                    "Could not find discovery information for %s") % endpoint
                LOG.error(msg)
                raise exception.KeyManagerError(reason=msg)
            latest_version = raw_data[-1]
            api_version = latest_version.get('id')

        if endpoint[-1] != '/':
            endpoint += '/'

        base_url = urllib.parse.urljoin(
            endpoint, api_version)

        return base_url
Example #5
0
    def create_key(self, context, algorithm, length,
                   expiration=None, name=None):
        """Creates a symmetric key.

        :param context: contains information of the user and the environment
                        for the request (castellan/context.py)
        :param algorithm: the algorithm associated with the secret
        :param length: the bit length of the secret
        :param name: the name of the key
        :param expiration: the date the key will expire
        :return: the UUID of the new key
        :raises KeyManagerError: if key creation fails
        """
        barbican_client = self._get_barbican_client(context)

        try:
            key_order = barbican_client.orders.create_key(
                name=name,
                algorithm=algorithm,
                bit_length=length,
                expiration=expiration)
            order_ref = key_order.submit()
            order = self._get_active_order(barbican_client, order_ref)
            return self._retrieve_secret_uuid(order.secret_ref)
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error("Error creating key: %s", e)
            raise exception.KeyManagerError(reason=e)
Example #6
0
    def store(self, context, managed_object, expiration=None):
        """Stores (i.e., registers) an object with the key manager.

        :param context: contains information of the user and the environment
            for the request (castellan/context.py)
        :param managed_object: a secret object with unencrypted payload.
            Known as "secret" to the barbicanclient api
        :param expiration: the expiration time of the secret in ISO 8601
            format
        :returns: the UUID of the stored object
        :raises KeyManagerError: if object store fails
        """
        barbican_client = self._get_barbican_client(context)

        try:
            secret = self._get_barbican_object(barbican_client,
                                               managed_object)
            secret.expiration = expiration
            secret_ref = secret.store()
            return self._retrieve_secret_uuid(secret_ref)
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error("Error storing object: %s", e)
            raise exception.KeyManagerError(reason=e)
Example #7
0
def _encrypt_data(context, data):
    try:
        # TODO(pbourke): move auth construction into common area if it ends up
        # been required in other areas
        auth = identity.V3Password(
            auth_url=settings.KEY_MANAGER['auth_url'],
            username=settings.KEY_MANAGER['username'],
            user_domain_name=settings.KEY_MANAGER['user_domain_name'],
            password=settings.KEY_MANAGER['password'],
            project_name=settings.KEY_MANAGER['project_name'],
            project_domain_name=settings.KEY_MANAGER['project_domain_name']
        )
    except (KeyError, AttributeError) as e:
        LOG.exception(e)
        msg = ('Could not find valid key manager credentials in the '
               'murano-dashboard config. encryptData yaql function not '
               'available')
        raise castellan_exception.KeyManagerError(message_arg=msg)
    sess = session.Session(auth=auth)
    auth_context = _oslo_context.RequestContext(
        auth_token=auth.get_token(sess), tenant=auth.get_project_id(sess))
    options.set_defaults(cfg.CONF,
                         auth_endpoint=settings.KEY_MANAGER['auth_url'])

    manager = key_manager.API()
    try:
        # TODO(pbourke): while we feel opaque data should cover the most common
        # use case, we may want to add support for other secret types in the
        # future (see https://goo.gl/tZhfqe)
        stored_key_id = manager.store(auth_context,
                                      opaque_data.OpaqueData(data))
    except castellan_exception.KeyManagerError as e:
        LOG.exception(e)
        raise
    return stored_key_id
    def _get_active_order(self, barbican_client, order_ref):
        """Returns the order when it is active.

        Barbican key creation is done asynchronously, so this loop continues
        checking until the order is active or a timeout occurs.
        """
        active_status = u'ACTIVE'
        error_status = u'ERROR'
        number_of_retries = self.conf.barbican.number_of_retries
        retry_delay = self.conf.barbican.retry_delay
        order = barbican_client.orders.get(order_ref)
        time.sleep(.25)
        for n in range(number_of_retries):
            if order.status == error_status:
                kwargs = {
                    "status": error_status,
                    "code": order.error_status_code,
                    "reason": order.error_reason
                }
                msg = _("Order is in %(status)s status - status code: "
                        "%(code)s, status reason: %(reason)s") % kwargs
                LOG.error(msg)
                raise exception.KeyManagerError(reason=msg)
            if order.status != active_status:
                kwargs = {
                    'attempt': n,
                    'total': number_of_retries,
                    'status': order.status,
                    'active': active_status,
                    'delay': retry_delay
                }
                msg = _("Retry attempt #%(attempt)i out of %(total)i: "
                        "Order status is '%(status)s'. Waiting for "
                        "'%(active)s', will retry in %(delay)s "
                        "seconds")
                LOG.info(msg, kwargs)
                time.sleep(retry_delay)
                order = barbican_client.orders.get(order_ref)
            else:
                return order
        msg = _("Exceeded retries: Failed to find '%(active)s' status "
                "within %(num_retries)i retries") % {
                    'active': active_status,
                    'num_retries': number_of_retries
                }
        LOG.error(msg)
        raise exception.KeyManagerError(reason=msg)
Example #9
0
    def list(self, context, object_type=None, metadata_only=False):
        """Lists the managed objects given the criteria."""

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = _("User is not authorized to use key manager.")
            raise exception.Forbidden(msg)

        if object_type and object_type not in self._secret_type_dict:
            msg = _("Invalid secret type: %s") % object_type
            raise exception.KeyManagerError(reason=msg)

        headers = {'X-Vault-Token': self._root_token_id}
        try:
            resource_url = self._get_url() + 'v1/secret/?list=true'
            resp = self._session.get(resource_url,
                                     verify=self._verify_server,
                                     headers=headers)
            keys = resp.json()['data']['keys']
        except requests.exceptions.Timeout as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except requests.exceptions.ConnectionError as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except Exception as ex:
            raise exception.KeyManagerError(six.text_type(ex))

        if resp.status_code in _EXCEPTIONS_BY_CODE:
            raise exception.KeyManagerError(resp.reason)
        if resp.status_code == requests.codes['forbidden']:
            raise exception.Forbidden()
        if resp.status_code == requests.codes['not_found']:
            keys = []

        objects = []
        for obj_id in keys:
            try:
                obj = self.get(context, obj_id, metadata_only=metadata_only)
                if object_type is None or isinstance(obj, object_type):
                    objects.append(obj)
            except exception.ManagedObjectNotFoundError as e:
                LOG.warning(
                    _("Error occurred while retrieving object "
                      "metadata, not adding it to the list: %s"), e)
                pass
        return objects
Example #10
0
    def _do_http_request(self, method, resource, json=None):
        verify = self._verify_server
        headers = self._build_auth_headers()

        try:
            resp = method(resource, headers=headers, json=json, verify=verify)
        except requests.exceptions.Timeout as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except requests.exceptions.ConnectionError as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except Exception as ex:
            raise exception.KeyManagerError(six.text_type(ex))

        if resp.status_code in _EXCEPTIONS_BY_CODE:
            raise exception.KeyManagerError(resp.reason)
        if resp.status_code == requests.codes['forbidden']:
            raise exception.Forbidden()

        return resp
    def _get_barbican_client(self, context):
        """Creates a client to connect to the Barbican service.

        :param context: the user context for authentication
        :return: a Barbican Client object
        :raises Forbidden: if the context is None
        :raises KeyManagerError: if context is missing tenant or tenant is
                                 None or error occurs while creating client
        """

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = u._("User is not authorized to use key manager.")
            LOG.error(msg)
            raise exception.Forbidden(msg)

        if not hasattr(context, 'tenant') or context.tenant is None:
            msg = u._("Unable to create Barbican Client without tenant "
                      "attribute in context object.")
            LOG.error(msg)
            raise exception.KeyManagerError(reason=msg)

        if self._barbican_client and self._current_context == context:
            return self._barbican_client

        try:
            self._current_context = context
            auth = self._get_keystone_auth(context)
            sess = session.Session(auth=auth)

            self._barbican_endpoint = self._get_barbican_endpoint(auth, sess)
            self._barbican_client = barbican_client.Client(
                session=sess, endpoint=self._barbican_endpoint)

        except Exception as e:
            LOG.error(u._LE("Error creating Barbican client: %s"), e)
            raise exception.KeyManagerError(reason=e)

        self._base_url = self._create_base_url(auth, sess,
                                               self._barbican_endpoint)

        return self._barbican_client
Example #12
0
    def delete(self, context, key_id):
        """Represents deleting the key."""

        if not key_id:
            raise exception.KeyManagerError('key identifier not provided')

        resp = self._do_http_request(self._session.delete,
                                     self._get_resource_url(key_id))

        if resp.status_code == requests.codes['not_found']:
            raise exception.ManagedObjectNotFoundError(uuid=key_id)
Example #13
0
    def list(self, context, object_type=None, metadata_only=False):
        """Retrieves a list of managed objects that match the criteria.

        If no search criteria is given, all objects are returned.

        :param context: contains information of the user and the environment
                     for the request (castellan/context.py)
        :param object_type: the type of object to retrieve
        :param metadata_only: whether secret data should be included
        :raises KeyManagerError: if listing secrets fails
        """
        objects = []
        barbican_client = self._get_barbican_client(context)

        if object_type and object_type not in self._secret_type_dict:
            msg = _("Invalid secret type: %s") % object_type
            LOG.error(msg)
            raise exception.KeyManagerError(reason=msg)

        secret_type = self._secret_type_dict.get(object_type)

        try:
            secrets = barbican_client.secrets.list(secret_type=secret_type)
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error(_("Error listing objects: %s"), e)
            raise exception.KeyManagerError(reason=e)

        for secret in secrets:
            try:
                obj = self._get_castellan_object(secret, metadata_only)
                objects.append(obj)
            except (barbican_exceptions.HTTPAuthError,
                    barbican_exceptions.HTTPClientError,
                    barbican_exceptions.HTTPServerError) as e:
                LOG.warning(
                    _("Error occurred while retrieving object "
                      "metadata, not adding it to the list: %s"), e)

        return objects
Example #14
0
    def _store_key_value(self, key_id, value):

        type_value = self._secret_type_dict.get(type(value))
        if type_value is None:
            raise exception.KeyManagerError("Unknown type for value : %r" %
                                            value)

        headers = {'X-Vault-Token': self._root_token_id}
        try:
            resource_url = self._get_url() + 'v1/secret/' + key_id
            record = {
                'type':
                type_value,
                'value':
                binascii.hexlify(value.get_encoded()).decode('utf-8'),
                'algorithm':
                (value.algorithm if hasattr(value, 'algorithm') else None),
                'bit_length':
                (value.bit_length if hasattr(value, 'bit_length') else None),
                'name':
                value.name,
                'created':
                value.created
            }
            resp = self._session.post(resource_url,
                                      verify=self._verify_server,
                                      json=record,
                                      headers=headers)
        except requests.exceptions.Timeout as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except requests.exceptions.ConnectionError as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except Exception as ex:
            raise exception.KeyManagerError(six.text_type(ex))

        if resp.status_code in _EXCEPTIONS_BY_CODE:
            raise exception.KeyManagerError(resp.reason)
        if resp.status_code == requests.codes['forbidden']:
            raise exception.Forbidden()

        return key_id
Example #15
0
    def _build_auth_headers(self):
        if self._root_token_id:
            return {'X-Vault-Token': self._root_token_id}

        if self._approle_token_id:
            return {'X-Vault-Token': self._approle_token_id}

        if self._approle_role_id:
            params = {
                'role_id': self._approle_role_id
            }
            if self._approle_secret_id:
                params['secret_id'] = self._approle_secret_id
            approle_login_url = '{}v1/auth/approle/login'.format(
                self._get_url()
            )
            token_issue_utc = timeutils.utcnow()
            try:
                resp = self._session.post(url=approle_login_url,
                                          json=params,
                                          verify=self._verify_server)
            except requests.exceptions.Timeout as ex:
                raise exception.KeyManagerError(str(ex))
            except requests.exceptions.ConnectionError as ex:
                raise exception.KeyManagerError(str(ex))
            except Exception as ex:
                raise exception.KeyManagerError(str(ex))

            if resp.status_code in _EXCEPTIONS_BY_CODE:
                raise exception.KeyManagerError(resp.reason)
            if resp.status_code == requests.codes['forbidden']:
                raise exception.Forbidden()

            resp = resp.json()
            self._cached_approle_token_id = resp['auth']['client_token']
            self._approle_token_issue = token_issue_utc
            self._approle_token_ttl = resp['auth']['lease_duration']
            return {'X-Vault-Token': self._approle_token_id}

        return {}
Example #16
0
    def _create_secret_ref(self, object_id):
        """Creates the URL required for accessing a secret.

        :param object_id: the UUID of the key to copy
        :return: the URL of the requested secret
        """
        if not object_id:
            msg = _("Key ID is None")
            raise exception.KeyManagerError(reason=msg)
        base_url = self._base_url
        if base_url[-1] != '/':
            base_url += '/'
        return urllib.parse.urljoin(base_url, "secrets/" + object_id)
Example #17
0
    def get(self, context, key_id, metadata_only=False):
        """Retrieves the key identified by the specified id."""

        if not key_id:
            raise exception.KeyManagerError('key identifier not provided')

        resp = self._do_http_request(self._session.get,
                                     self._get_resource_url(key_id))

        if resp.status_code == requests.codes['not_found']:
            raise exception.ManagedObjectNotFoundError(uuid=key_id)

        record = resp.json()['data']
        if self._get_api_version() != '1':
            record = record['data']

        key = None if metadata_only else binascii.unhexlify(record['value'])

        clazz = None
        for type_clazz, type_name in self._secret_type_dict.items():
            if type_name == record['type']:
                clazz = type_clazz

        if clazz is None:
            raise exception.KeyManagerError(
                "Unknown type : %r" % record['type'])

        if hasattr(clazz, 'algorithm') and hasattr(clazz, 'bit_length'):
            return clazz(record['algorithm'],
                         record['bit_length'],
                         key,
                         record['name'],
                         record['created'],
                         key_id)
        else:
            return clazz(key,
                         record['name'],
                         record['created'],
                         key_id)
Example #18
0
    def delete(self, context, key_id):
        """Represents deleting the key."""

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = _("User is not authorized to use key manager.")
            raise exception.Forbidden(msg)

        if not key_id:
            raise exception.KeyManagerError('key identifier not provided')

        resp = self._do_http_request(self._session.delete,
                                     self._get_resource_url(key_id))

        if resp.status_code == requests.codes['not_found']:
            raise exception.ManagedObjectNotFoundError(uuid=key_id)
    def _create_base_url(self, auth, sess, endpoint):
        if self.conf.barbican.barbican_api_version:
            api_version = self.conf.barbican.barbican_api_version
        else:
            discovery = auth.get_discovery(sess, url=endpoint)
            raw_data = discovery.raw_version_data()
            if len(raw_data) == 0:
                msg = u._LE(
                    "Could not find discovery information for %s") % endpoint
                LOG.error(msg)
                raise exception.KeyManagerError(reason=msg)
            latest_version = raw_data[-1]
            api_version = latest_version.get('id')

        base_url = urllib.parse.urljoin(endpoint, api_version)
        return base_url
Example #20
0
    def _get_barbican_client(self, context):
        """Creates a client to connect to the Barbican service.

        :param context: the user context for authentication
        :return: a Barbican Client object
        :raises Forbidden: if the context is None
        :raises KeyManagerError: if context is missing tenant or tenant is
                                 None or error occurs while creating client
        """

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = _("User is not authorized to use key manager.")
            LOG.error(msg)
            raise exception.Forbidden(msg)

        if self._barbican_client and self._current_context == context:
            return self._barbican_client

        try:
            auth = self._get_keystone_auth(context)
            sess = session.Session(auth=auth,
                                   verify=self.conf.barbican.verify_ssl)

            self._barbican_endpoint = self._get_barbican_endpoint(auth, sess)
            self._barbican_client = barbican_client_import.Client(
                session=sess,
                endpoint=self._barbican_endpoint)
            self._current_context = context

        # TODO(pbourke): more fine grained exception handling - we are eating
        # tracebacks here
        except Exception as e:
            LOG.error("Error creating Barbican client: %s", e)
            raise exception.KeyManagerError(reason=e)

        self._base_url = self._create_base_url(auth,
                                               sess,
                                               self._barbican_endpoint)

        return self._barbican_client
Example #21
0
    def create_key_pair(self,
                        context,
                        algorithm,
                        length,
                        expiration=None,
                        name=None):
        """Creates an asymmetric key pair.

        :param context: contains information of the user and the environment
                        for the request (castellan/context.py)
        :param algorithm: the algorithm associated with the secret
        :param length: the bit length of the secret
        :param name: the name of the key
        :param expiration: the date the key will expire
        :return: the UUIDs of the new key, in the order (private, public)
        :raises NotImplementedError: until implemented
        :raises KeyManagerError: if key pair creation fails
        """
        barbican_client = self._get_barbican_client(context)

        try:
            key_pair_order = barbican_client.orders.create_asymmetric(
                algorithm=algorithm,
                bit_length=length,
                name=name,
                expiration=expiration)

            order_ref = key_pair_order.submit()
            order = self._get_active_order(barbican_client, order_ref)
            container = barbican_client.containers.get(order.container_ref)

            private_key_uuid = self._retrieve_secret_uuid(
                container.secret_refs['private_key'])
            public_key_uuid = self._retrieve_secret_uuid(
                container.secret_refs['public_key'])
            return private_key_uuid, public_key_uuid
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error("Error creating key pair: %s", e)
            raise exception.KeyManagerError(reason=e)
Example #22
0
    def get(self, context, key_id, metadata_only=False):
        """Retrieves the key identified by the specified id."""

        # Confirm context is provided, if not raise forbidden
        if not context:
            msg = _("User is not authorized to use key manager.")
            raise exception.Forbidden(msg)

        if not key_id:
            raise exception.KeyManagerError('key identifier not provided')

        headers = {'X-Vault-Token': self._root_token_id}
        try:
            resource_url = self._get_url() + 'v1/secret/' + key_id
            resp = self._session.get(resource_url,
                                     verify=self._verify_server,
                                     headers=headers)
        except requests.exceptions.Timeout as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except requests.exceptions.ConnectionError as ex:
            raise exception.KeyManagerError(six.text_type(ex))
        except Exception as ex:
            raise exception.KeyManagerError(six.text_type(ex))

        if resp.status_code in _EXCEPTIONS_BY_CODE:
            raise exception.KeyManagerError(resp.reason)
        if resp.status_code == requests.codes['forbidden']:
            raise exception.Forbidden()
        if resp.status_code == requests.codes['not_found']:
            raise exception.ManagedObjectNotFoundError(uuid=key_id)

        record = resp.json()['data']
        key = None if metadata_only else binascii.unhexlify(record['value'])

        clazz = None
        for type_clazz, type_name in self._secret_type_dict.items():
            if type_name == record['type']:
                clazz = type_clazz

        if clazz is None:
            raise exception.KeyManagerError("Unknown type : %r" %
                                            record['type'])

        if hasattr(clazz, 'algorithm') and hasattr(clazz, 'bit_length'):
            return clazz(record['algorithm'], record['bit_length'], key,
                         record['name'], record['created'], key_id)
        else:
            return clazz(key, record['name'], record['created'], key_id)
    def get(self, context, managed_object_id):
        """Retrieves the specified managed object.

        :param context: contains information of the user and the environment
                        for the request (castellan/context.py)
        :param managed_object_id: the UUID of the object to retrieve
        :return: ManagedObject representation of the managed object
        :raises KeyManagerError: if object retrieval fails
        :raises ManagedObjectNotFoundError: if object not found
        """
        try:
            secret = self._get_secret(context, managed_object_id)
            return self._get_castellan_object(secret)
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error(_LE("Error retrieving object: %s"), e)
            if self._is_secret_not_found_error(e):
                raise exception.ManagedObjectNotFoundError(
                    uuid=managed_object_id)
            else:
                raise exception.KeyManagerError(reason=e)
Example #24
0
    def delete(self, context, managed_object_id):
        """Deletes the specified managed object.

        :param context: contains information of the user and the environment
                     for the request (castellan/context.py)
        :param managed_object_id: the UUID of the object to delete
        :raises KeyManagerError: if object deletion fails
        :raises ManagedObjectNotFoundError: if the object could not be found
        """
        barbican_client = self._get_barbican_client(context)

        try:
            secret_ref = self._create_secret_ref(managed_object_id)
            barbican_client.secrets.delete(secret_ref)
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error("Error deleting object: %s", e)
            if self._is_secret_not_found_error(e):
                raise exception.ManagedObjectNotFoundError(
                    uuid=managed_object_id)
            else:
                raise exception.KeyManagerError(reason=e)
Example #25
0
    def get_latest_key(self,
                       context,
                       mode=None,
                       algorithm=None,
                       bits=0,
                       name=None):
        """
        Retrieve the user's latest root encryption secret from an external key
        management system using Castellan.

        :param context: the user context for authentication
        :param user_token: the mode of the key to look for
        :param algorithm: the algorithm of the key to look for
        :param bits: the bitlength of the key to look for
        :param name: the name of the key to look for

        :return: a tuple containing the id of the latest root key, and the
                 castellan object representation of the key
        :rtype: (string, castellan object)
        """
        barbican_client = self._get_barbican_client(context)
        latest_secret = None
        latest_secret_id = None
        offset = 0
        more = True

        try:
            while more:
                # List all keys that match the requirements
                found = barbican_client.secrets.list(limit=LIST_LIMIT,
                                                     offset=offset,
                                                     name=name,
                                                     algorithm=algorithm,
                                                     mode=mode,
                                                     bits=bits)
                # No (more) results
                if found is None:
                    break
                # At least one result
                if len(found) > 0:
                    for s in found:
                        secret = self._get_castellan_object(s)
                        secret_id = s.secret_ref.rpartition('/')[-1]
                        # Check if the key is the most latest one
                        if self._is_current_key_latest(latest_secret,
                                                       latest_secret_id,
                                                       secret, secret_id):
                            latest_secret = secret
                            latest_secret_id = secret_id
                # If there were less than LIST_LIMIT results, we have reached
                # the last page of results.
                if len(found) < LIST_LIMIT:
                    break
                # Otherwise, continue with the next page of results.
                offset += LIST_LIMIT

            return latest_secret_id, latest_secret
        except (barbican_exceptions.HTTPAuthError,
                barbican_exceptions.HTTPClientError,
                barbican_exceptions.HTTPServerError) as e:
            LOG.error("Error listing keys: %s", e)
            raise exception.KeyManagerError(reason=e)