Exemplo n.º 1
0
    def _get_passphrase_for_a_private_key(self, secret_type, secret_metadata,
                                          key_spec):
        """Retrieve the passphrase for the private key stored in the KRA."""
        if secret_type is None:
            return None
        if key_spec.alg is None:
            return None

        passphrase = None
        if DogtagKRAPlugin.PASSPHRASE_KEY_ID in secret_metadata:
            if key_spec.alg.upper() == key.KeyClient.RSA_ALGORITHM:
                passphrase = self.keyclient.retrieve_key(
                    secret_metadata.get(
                        DogtagKRAPlugin.PASSPHRASE_KEY_ID)).data
            else:
                if key_spec.alg.upper() == key.KeyClient.DSA_ALGORITHM:
                    raise sstore.SecretGeneralException(
                        u._("DSA keys should not have a passphrase in the"
                            " database, for being used during retrieval."))
                raise sstore.SecretGeneralException(
                    u._("Secrets of type {secret_type} should not have a "
                        "passphrase in the database, for being used during "
                        "retrieval.").format(secret_type=secret_type))

        # note that Barbican expects the passphrase to be base64 encoded when
        # stored, so we need to decode it.
        if passphrase:
            passphrase = base64.b64decode(passphrase)
        return passphrase
Exemplo n.º 2
0
    def generate_asymmetric_key(self, key_spec):
        if not self.generate_supports(key_spec):
            raise ss.SecretAlgorithmNotSupportedException(
                key_spec.alg)

        if key_spec.passphrase:
            raise ss.GeneratePassphraseNotSupportedException()

        try:
            private_id, public_id = self.key_manager.create_key_pair(
                self.context,
                key_spec.alg,
                key_spec.bit_length
            )

            private_key_metadata = self._meta_dict(
                private_id, key_spec.bit_length, key_spec.alg
            )

            public_key_metadata = self._meta_dict(
                public_id, key_spec.bit_length, key_spec.alg
            )

            return ss.AsymmetricKeyMetadataDTO(
                private_key_metadata,
                public_key_metadata,
                None
            )
        except Exception as e:
            LOG.exception("Error generating asymmetric key: {}".format(
                six.text_type(e)))
            raise ss.SecretGeneralException(e)
Exemplo n.º 3
0
    def generate_symmetric_key(self, key_spec):
        """Generate a symmetric key.

        Creates KMIP attribute objects based on the given KeySpec to send to
        the server.

        :param key_spec: KeySpec with symmetric algorithm and bit_length
        :returns: dictionary holding key_id returned by server
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting symmetric key generation with KMIP plugin")
        if not self.generate_supports(key_spec):
            raise ss.SecretAlgorithmNotSupportedException(key_spec.alg)

        if key_spec.alg.lower() not in ss.KeyAlgorithm.SYMMETRIC_ALGORITHMS:
            raise KMIPSecretStoreError(
                u._("An unsupported algorithm {algorithm} was passed to the "
                    "'generate_symmetric_key' method").format(
                        algorithm=key_spec.alg))

        algorithm = self._get_kmip_algorithm(key_spec.alg)
        try:
            with self.client:
                LOG.debug("Opened connection to KMIP client for secret " +
                          "generation")
                uuid = self.client.create(algorithm, key_spec.bit_length)
                LOG.debug("SUCCESS: Symmetric key generated with "
                          "uuid: %s", uuid)
                return {KMIPSecretStore.KEY_UUID: uuid}
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
Exemplo n.º 4
0
    def delete_secret(self, secret_metadata):
        """Deletes the secret whose metadata is included in the dictionary.

        Returns nothing if successful, raises an exception if an error occurs
        :param secret_metadata: Dictionary of key metadata, requires:
        {'key_uuid': <uuid of key>}
        :raises: SecretGeneralException
        """
        LOG.debug("Starting secret deletion with KMIP plugin")
        uuid = str(secret_metadata[KMIPSecretStore.KEY_UUID])

        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for secret deletion")
            result = self.client.destroy(uuid=uuid, credential=self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                LOG.debug("SUCCESS: Key with uuid %s deleted", uuid)
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for secret deletion")
Exemplo n.º 5
0
    def store_secret(self, secret_dto):
        """Stores a secret

        To store a secret in KMIP, the attributes must be known.

        :param secret_dto: SecretDTO of the secret to be stored
        :returns: Dictionary holding the key_uuid assigned by KMIP
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting secret storage with KMIP plugin")
        if not self.store_secret_supports(secret_dto.key_spec):
            raise ss.SecretAlgorithmNotSupportedException(
                secret_dto.key_spec.alg)

        secret_type = secret_dto.type
        object_type, key_format_type = (self._map_type_ss_to_kmip(secret_type))
        if object_type is None:
            raise KMIPSecretStoreError(
                u._('Secret object type {object_type} is '
                    'not supported').format(object_type=object_type))

        secret = self._get_kmip_secret(secret_dto)

        try:
            with self.client:
                LOG.debug("Opened connection to KMIP client")
                uuid = self.client.register(secret)
                LOG.debug("SUCCESS: Key stored with uuid: %s", uuid)
                return {KMIPSecretStore.KEY_UUID: uuid}
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
Exemplo n.º 6
0
 def _raise_secret_general_exception(self, result):
     msg = u._("Status: {status}, Reason: {reason}, "
               "Message: {message}").format(status=result.result_status,
                                            reason=result.result_reason,
                                            message=result.result_message)
     LOG.error(u._LE("ERROR from KMIP server: %s"), msg)
     raise ss.SecretGeneralException(msg)
Exemplo n.º 7
0
def convert_der_to_pem(der, secret_type):
    if secret_type == s.SecretType.PRIVATE:
        return _convert_private_der_to_pem(der)
    elif secret_type == s.SecretType.PUBLIC:
        return _convert_public_der_to_pem(der)
    elif secret_type == s.SecretType.CERTIFICATE:
        return _convert_certificate_der_to_pem(der)
    else:
        reason = u._("Secret type can not be converted to PEM")
        raise s.SecretGeneralException(reason=reason)
Exemplo n.º 8
0
    def generate_symmetric_key(self, key_spec):
        """Generate a symmetric key.

        Creates KMIP attribute objects based on the given KeySpec to send to
        the server.

        :param key_spec: KeySpec with symmetric algorithm and bit_length
        :returns: dictionary holding key_id returned by server
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting symmetric key generation with KMIP plugin")
        if not self.generate_supports(key_spec):
            raise ss.SecretAlgorithmNotSupportedException(key_spec.alg)

        if key_spec.alg.lower() not in ss.KeyAlgorithm.SYMMETRIC_ALGORITHMS:
            raise KMIPSecretStoreError(
                u._("An unsupported algorithm {algorithm} was passed to the "
                    "'generate_symmetric_key' method").format(
                        algorithm=key_spec.alg))

        object_type = enums.ObjectType.SYMMETRIC_KEY

        algorithm = self._create_cryptographic_algorithm_attribute(
            key_spec.alg)

        usage_mask = self._create_usage_mask_attribute(object_type)

        length = self._create_cryptographic_length_attribute(
            key_spec.bit_length)

        attribute_list = [algorithm, usage_mask, length]
        template_attribute = TemplateAttribute(attributes=attribute_list)

        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for secret " +
                      "generation")
            result = self.client.create(object_type=object_type,
                                        template_attribute=template_attribute,
                                        credential=self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                LOG.debug("SUCCESS: Symmetric key generated with "
                          "uuid: %s", result.uuid.value)
                return {KMIPSecretStore.KEY_UUID: result.uuid.value}
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for secret " +
                      "generation")
Exemplo n.º 9
0
 def delete_secret(self, secret_metadata):
     secret_ref = secret_metadata[CastellanSecretStore.KEY_ID]
     try:
         self.key_manager.delete(
             self.context,
             secret_ref)
     except KeyError:
         LOG.warning("Attempting to delete a non-existent secret {}".format(
             secret_ref))
     except Exception as e:
         LOG.exception("Error deleting secret: {}".format(
             six.text_type(e)))
         raise ss.SecretGeneralException(e)
Exemplo n.º 10
0
    def get_secret(self, secret_type, secret_metadata):
        secret_ref = secret_metadata[CastellanSecretStore.KEY_ID]
        try:
            secret = self.key_manager.get(
                self.context,
                secret_ref)

            return ss.SecretDTO(secret_type, secret.get_encoded(),
                                ss.KeySpec(), secret_metadata['content_type'])
        except Exception as e:
            LOG.exception("Error retrieving secret {}: {}".format(
                secret_ref, six.text_type(e)))
            raise ss.SecretGeneralException(e)
Exemplo n.º 11
0
    def _get_barbican_secret(self, result, secret_type):
        object_type = result.object_type.value
        if object_type == enums.ObjectType.CERTIFICATE.value:
            certificate = result.secret
            secret_value = certificate.certificate_value.value
            key_spec = ss.KeySpec()
        elif object_type == enums.ObjectType.OPAQUE_DATA.value:
            opaque_secret = result.secret
            secret_value = opaque_secret.opaque_data_value.value
            key_spec = ss.KeySpec()
        elif (object_type == enums.ObjectType.SYMMETRIC_KEY.value
              or object_type == enums.ObjectType.PRIVATE_KEY.value
              or object_type == enums.ObjectType.PUBLIC_KEY.value
              or object_type == enums.ObjectType.SECRET_DATA.value):

            secret_block = result.secret.key_block
            key_value_type = type(secret_block.key_value.key_material)
            if (key_value_type == KeyMaterialStruct
                    or key_value_type == KeyMaterial):
                secret_value = secret_block.key_value.key_material.value
            else:
                msg = u._(
                    "Unknown key value type received from KMIP "
                    "server, expected {key_value_struct} or "
                    "{key_value_string}, received: {key_value_type}").format(
                        key_value_struct=KeyValue,
                        key_value_string=KeyMaterial,
                        key_value_type=key_value_type)
                LOG.exception(msg)
                raise ss.SecretGeneralException(msg)

            if secret_block.cryptographic_algorithm:
                secret_alg = self._map_algorithm_kmip_to_ss(
                    secret_block.cryptographic_algorithm.value)
            else:
                secret_alg = None
            if secret_block.cryptographic_length:
                secret_bit_length = secret_block.cryptographic_length.value
            else:
                secret_bit_length = None
            key_spec = ss.KeySpec(secret_alg, secret_bit_length),

        secret_value = self._denormalize_secret(secret_value, secret_type)
        secret_dto = ss.SecretDTO(secret_type,
                                  secret_value,
                                  key_spec,
                                  content_type=None,
                                  transport_key=None)
        return secret_dto
Exemplo n.º 12
0
 def store_secret(self, secret_dto):
     if not self.store_secret_supports(secret_dto.key_spec):
         raise ss.SecretAlgorithmNotSupportedException(
             secret_dto.key_spec.alg)
     plaintext = base64.b64decode(secret_dto.secret)
     try:
         secret_id = self.key_manager.store(
             self.context,
             opaque_data.OpaqueData(plaintext)
         )
         return self._meta_dict(secret_id)
     except Exception as e:
         LOG.exception("Error storing secret: {}".format(
             six.text_type(e)))
         raise ss.SecretGeneralException(e)
Exemplo n.º 13
0
    def _get_passphrase_for_a_private_key(self, secret_metadata, key_spec):
        """Retrieve the passphrase for the private key stored in the KRA."""
        secret_type = secret_metadata.get(DogtagKRAPlugin.SECRET_TYPE, None)
        if secret_type is None:
            return None
        if key_spec.alg is None:
            return None

        passphrase = None
        if DogtagKRAPlugin.PASSPHRASE_KEY_ID in secret_metadata:
            if key_spec.alg.upper() == key.KeyClient.RSA_ALGORITHM:
                passphrase = self.keyclient.retrieve_key(
                    secret_metadata.get(
                        DogtagKRAPlugin.PASSPHRASE_KEY_ID)).data
            else:
                if key_spec.alg.upper() == key.KeyClient.DSA_ALGORITHM:
                    raise sstore.SecretGeneralException(
                        u._("DSA keys should not have a passphrase in the"
                            " database, for being used during retrieval."))
                raise sstore.SecretGeneralException(
                    u._("Secrets of type {secret_type} should not have a "
                        "passphrase in the database, for being used during "
                        "retrieval.").format(secret_type=secret_type))
        return passphrase
Exemplo n.º 14
0
 def generate_symmetric_key(self, key_spec):
     if not self.generate_supports(key_spec):
         raise ss.SecretAlgorithmNotSupportedException(
             key_spec.alg)
     try:
         secret_ref = self.key_manager.create_key(
             self.context,
             key_spec.alg,
             key_spec.bit_length
         )
         return {CastellanSecretStore.KEY_ID: secret_ref}
     except Exception as e:
         LOG.exception("Error generating symmetric key: {}".format(
             six.text_type(e)))
         raise ss.SecretGeneralException(e)
Exemplo n.º 15
0
    def store_secret(self, secret_dto):
        if not self.store_secret_supports(secret_dto.key_spec):
            raise ss.SecretAlgorithmNotSupportedException(
                secret_dto.key_spec.alg)

        try:
            secret_ref = self.key_manager.store(
                self.context,
                opaque_data.OpaqueData(secret_dto.secret)
            )
            return {CastellanSecretStore.KEY_ID: secret_ref}
        except Exception as e:
            LOG.exception("Error storing secret: {}".format(
                six.text_type(e)))
            raise ss.SecretGeneralException(e)
Exemplo n.º 16
0
    def generate_asymmetric_key(self, key_spec):
        """Generate an asymmetric key pair.

        Creates KMIP attribute objects based on the given KeySpec to send to
        the server. The KMIP Secret Store currently does not support
        protecting the private key with a passphrase.

        :param key_spec: KeySpec with asymmetric algorithm and bit_length
        :returns: AsymmetricKeyMetadataDTO with the key UUIDs
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting asymmetric key generation with KMIP plugin")
        if not self.generate_supports(key_spec):
            raise ss.SecretAlgorithmNotSupportedException(key_spec.alg)

        if key_spec.alg.lower() not in ss.KeyAlgorithm.ASYMMETRIC_ALGORITHMS:
            raise KMIPSecretStoreError(
                u._("An unsupported algorithm {algorithm} was passed to "
                    "the 'generate_asymmetric_key' method").format(
                        algorithm=key_spec.alg))

        if key_spec.passphrase:
            raise KMIPSecretStoreError(
                u._('KMIP plugin does not currently support protecting the '
                    'private key with a passphrase'))

        algorithm = self._get_kmip_algorithm(key_spec.alg)
        length = key_spec.bit_length

        try:
            with self.client:
                LOG.debug("Opened connection to KMIP client for asymmetric " +
                          "secret generation")
                public_uuid, private_uuid = self.client.create_key_pair(
                    algorithm, length)
                LOG.debug(
                    "SUCCESS: Asymmetric key pair generated with "
                    "public key uuid: %s and private key uuid: %s",
                    public_uuid, private_uuid)
                private_key_metadata = {KMIPSecretStore.KEY_UUID: private_uuid}
                public_key_metadata = {KMIPSecretStore.KEY_UUID: public_uuid}
                passphrase_metadata = None
                return ss.AsymmetricKeyMetadataDTO(private_key_metadata,
                                                   public_key_metadata,
                                                   passphrase_metadata)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
Exemplo n.º 17
0
    def store_secret(self, secret_dto):
        """Stores a secret

        To store a secret in KMIP, the attributes must be known.

        :param secret_dto: SecretDTO of the secret to be stored
        :returns: Dictionary holding the key_uuid assigned by KMIP
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting secret storage with KMIP plugin")
        if not self.store_secret_supports(secret_dto.key_spec):
            raise ss.SecretAlgorithmNotSupportedException(
                secret_dto.key_spec.alg)

        secret_type = secret_dto.type
        object_type, key_format_type = (self._map_type_ss_to_kmip(secret_type))
        if object_type is None:
            raise KMIPSecretStoreError(
                u._('Secret object type {object_type} is '
                    'not supported').format(object_type=object_type))

        usage_mask = self._create_usage_mask_attribute(object_type)
        attribute_list = [usage_mask]
        template_attribute = TemplateAttribute(attributes=attribute_list)
        secret = self._get_kmip_secret(secret_dto)

        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for secret storage")
            result = self.client.register(
                object_type=object_type,
                template_attribute=template_attribute,
                secret=secret,
                credential=self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                LOG.debug("SUCCESS: Key stored with uuid: %s",
                          result.uuid.value)
                return {KMIPSecretStore.KEY_UUID: result.uuid.value}
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for secret storage")
Exemplo n.º 18
0
    def delete_secret(self, secret_metadata):
        """Deletes the secret whose metadata is included in the dictionary.

        Returns nothing if successful, raises an exception if an error occurs
        :param secret_metadata: Dictionary of key metadata, requires:
        {'key_uuid': <uuid of key>}
        :raises: SecretGeneralException
        """
        LOG.debug("Starting secret deletion with KMIP plugin")
        uuid = str(secret_metadata[KMIPSecretStore.KEY_UUID])
        try:
            with self.client:
                LOG.debug("Opened connection to KMIP client")
                self.client.destroy(uuid)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
Exemplo n.º 19
0
    def get_secret(self, secret_type, secret_metadata):
        """Gets a secret

        :param secret_type: secret type
        :param secret_metadata: Dictionary of key metadata, requires:
        {'key_uuid': <uuid of key>}
        :returns: SecretDTO of the retrieved Secret
        :raises: SecretGeneralException
        """
        LOG.debug("Starting secret retrieval with KMIP plugin")
        uuid = str(secret_metadata[KMIPSecretStore.KEY_UUID])
        try:
            with self.client:
                LOG.debug("Opened connection to KMIP client for secret " +
                          "retrieval")
                managed_object = self.client.get(uuid)
                return self._get_barbican_secret(managed_object, secret_type)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
Exemplo n.º 20
0
 def get_secret(self, secret_type, secret_metadata):
     secret_ref = secret_metadata[CastellanSecretStore.KEY_ID]
     try:
         secret = self.key_manager.get(
             self.context,
             secret_ref)
         meta_version = secret_metadata.get(self.METADATA_VERSION)
         if meta_version is None:
             # Secrets without a metadata version were stored prior to fix
             # for Story 2008335.  They may or may not be base64-encoded.
             LOG.debug("Retrieving legacy secret")
             data = self._ensure_legacy_base64(secret)
         else:
             # Version 1 - secret payload data is stored in plaintext in
             #   the backend.  We need to base64 encode them for the DTO.
             data = base64.b64encode(secret.get_encoded())
         return ss.SecretDTO(secret_type, data, ss.KeySpec(), None)
     except Exception as e:
         LOG.exception("Error retrieving secret {}: {}".format(
             secret_ref, six.text_type(e)))
         raise ss.SecretGeneralException(e)
Exemplo n.º 21
0
    def get_secret(self, secret_type, secret_metadata):
        """Gets a secret

        :param secret_type: secret type
        :param secret_metadata: Dictionary of key metadata, requires:
        {'key_uuid': <uuid of key>}
        :returns: SecretDTO of the retrieved Secret
        :raises: SecretGeneralException
        """
        LOG.debug("Starting secret retrieval with KMIP plugin")
        uuid = str(secret_metadata[KMIPSecretStore.KEY_UUID])
        object_type, key_format_enum = self._map_type_ss_to_kmip(secret_type)
        if (key_format_enum is not None
                and object_type != enums.ObjectType.CERTIFICATE):
            key_format_type = misc.KeyFormatType(key_format_enum)
        else:
            key_format_type = None
        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for secret " +
                      "retrieval")
            result = self.client.get(uuid=uuid,
                                     key_format_type=key_format_type,
                                     credential=self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                ret_secret_dto = self._get_barbican_secret(result, secret_type)
                LOG.debug("SUCCESS: Key retrieved with uuid: %s", uuid)
                return ret_secret_dto
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for secret " +
                      "retrieval")
Exemplo n.º 22
0
    def generate_asymmetric_key(self, key_spec):
        if not self.generate_supports(key_spec):
            raise ss.SecretAlgorithmNotSupportedException(
                key_spec.alg)

        if key_spec.passphrase:
            raise ss.GeneratePassphraseNotSupportedException()

        try:
            private_ref, public_ref = self.key_manager.create_key_pair(
                self.context,
                key_spec.alg,
                key_spec.bit_length
            )

            private_key_metadata = {
                CastellanSecretStore.ALG: key_spec.alg,
                CastellanSecretStore.BIT_LENGTH: key_spec.bit_length,
                CastellanSecretStore.KEY_ID: private_ref
            }

            public_key_metadata = {
                CastellanSecretStore.ALG: key_spec.alg,
                CastellanSecretStore.BIT_LENGTH: key_spec.bit_length,
                CastellanSecretStore.KEY_ID: public_ref
            }

            return ss.AsymmetricKeyMetadataDTO(
                private_key_metadata,
                public_key_metadata,
                None
            )
        except Exception as e:
            LOG.exception("Error generating asymmetric key: {}".format(
                six.text_type(e)))
            raise ss.SecretGeneralException(e)
Exemplo n.º 23
0
    def store_secret(self, secret_dto):
        """Stores a secret

        To store a secret in KMIP, the attributes must be known.

        :param secret_dto: SecretDTO of the secret to be stored
        :returns: Dictionary holding the key_uuid assigned by KMIP
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting secret storage with KMIP plugin")
        if not self.store_secret_supports(secret_dto.key_spec):
            raise ss.SecretAlgorithmNotSupportedException(
                secret_dto.key_spec.alg)

        object_type = self._map_type_ss_to_kmip(secret_dto.type)

        algorithm_value = self._map_algorithm_ss_to_kmip(
            secret_dto.key_spec.alg)

        usage_mask = self._create_usage_mask_attribute()

        attribute_list = [usage_mask]
        template_attribute = kmip_objects.TemplateAttribute(
            attributes=attribute_list)

        secret_features = {
            'key_format_type': enums.KeyFormatType.RAW,
            'key_value': {
                'bytes': self._convert_base64_to_byte_array(secret_dto.secret)
            },
            'cryptographic_algorithm': algorithm_value,
            'cryptographic_length': secret_dto.key_spec.bit_length
        }

        secret = secrets.SecretFactory().create_secret(object_type,
                                                       secret_features)
        LOG.debug("Created secret object to be stored: %s, %s, %s",
                  secret_features.get('key_format_type'),
                  secret_features.get('cryptographic_algorithm'),
                  secret_features.get('cryptographic_length'))

        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for secret storage")
            result = self.client.register(object_type,
                                          template_attribute,
                                          secret,
                                          self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                LOG.debug("SUCCESS: Key stored with uuid: %s",
                          result.uuid.value)
                return {KMIPSecretStore.KEY_UUID: result.uuid.value}
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for secret storage")
Exemplo n.º 24
0
    def generate_asymmetric_key(self, key_spec):
        """Generate an asymmetric key pair.

        Creates KMIP attribute objects based on the given KeySpec to send to
        the server. The KMIP Secret Store currently does not support
        protecting the private key with a passphrase.

        :param key_spec: KeySpec with asymmetric algorithm and bit_length
        :returns: AsymmetricKeyMetadataDTO with the key UUIDs
        :raises: SecretGeneralException, SecretAlgorithmNotSupportedException
        """
        LOG.debug("Starting asymmetric key generation with KMIP plugin")
        if not self.generate_supports(key_spec):
            raise ss.SecretAlgorithmNotSupportedException(key_spec.alg)

        if key_spec.alg.lower() not in ss.KeyAlgorithm.ASYMMETRIC_ALGORITHMS:
            raise KMIPSecretStoreError(
                u._("An unsupported algorithm {algorithm} was passed to "
                    "the 'generate_asymmetric_key' method").format(
                        algorithm=key_spec.alg))

        if key_spec.passphrase:
            raise KMIPSecretStoreError(
                u._('KMIP plugin does not currently support protecting the '
                    'private key with a passphrase'))

        algorithm = self._create_cryptographic_algorithm_attribute(
            key_spec.alg)

        length = self._create_cryptographic_length_attribute(
            key_spec.bit_length)

        attributes = [algorithm, length]
        common = CommonTemplateAttribute(attributes=attributes)

        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for asymmetric " +
                      "secret generation")
            result = self.client.create_key_pair(
                common_template_attribute=common, credential=self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                LOG.debug(
                    "SUCCESS: Asymmetric key pair generated with "
                    "public key uuid: %s and private key uuid: %s",
                    result.public_key_uuid.value,
                    result.private_key_uuid.value)
                private_key_metadata = {
                    KMIPSecretStore.KEY_UUID: result.private_key_uuid.value
                }
                public_key_metadata = {
                    KMIPSecretStore.KEY_UUID: result.public_key_uuid.value
                }
                passphrase_metadata = None
                return ss.AsymmetricKeyMetadataDTO(private_key_metadata,
                                                   public_key_metadata,
                                                   passphrase_metadata)
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for asymmetric "
                      "secret generation")
Exemplo n.º 25
0
    def get_secret(self, secret_metadata):
        """Gets a secret

        :param secret_metadata: Dictionary of key metadata, requires:
        {'key_uuid': <uuid of key>}
        :returns: SecretDTO of the retrieved Secret
        :raises: SecretGeneralException
        """
        LOG.debug("Starting secret retrieval with KMIP plugin")
        uuid = str(secret_metadata[KMIPSecretStore.KEY_UUID])

        try:
            self.client.open()
            LOG.debug("Opened connection to KMIP client for secret " +
                      "retrieval")
            result = self.client.get(uuid, self.credential)
        except Exception as e:
            LOG.exception(u._LE("Error opening or writing to client"))
            raise ss.SecretGeneralException(str(e))
        else:
            if result.result_status.enum == enums.ResultStatus.SUCCESS:
                secret_block = result.secret.key_block

                secret_type = self._map_type_kmip_to_ss(
                    result.object_type.enum)

                key_value_type = type(secret_block.key_value.key_value)
                if key_value_type == kmip_objects.KeyValueStruct:
                    secret_value = self._convert_byte_array_to_base64(
                        secret_block.key_value.key_value.key_material.value)

                elif key_value_type == kmip_objects.KeyValueString:
                    secret_value = self._convert_byte_array_to_base64(
                        secret_block.key_value.key_value.value)

                else:
                    msg = u._(
                        "Unknown key value type received from KMIP "
                        "server, expected {key_value_struct} or "
                        "{key_value_string}, received: {key_value_type}"
                    ).format(
                        key_value_struct=kmip_objects.KeyValueStruct,
                        key_value_string=kmip_objects.KeyValueString,
                        key_value_type=key_value_type
                    )
                    LOG.exception(msg)
                    raise ss.SecretGeneralException(msg)

                secret_alg = self._map_algorithm_kmip_to_ss(
                    secret_block.cryptographic_algorithm.value)
                secret_bit_length = secret_block.cryptographic_length.value
                ret_secret_dto = ss.SecretDTO(
                    secret_type,
                    secret_value,
                    ss.KeySpec(secret_alg, secret_bit_length),
                    'content_type',
                    transport_key=None)
                # TODO(kaitlin-farr) remove 'content-type'
                LOG.debug("SUCCESS: Key retrieved with uuid: %s",
                          uuid)
                return ret_secret_dto
            else:
                self._raise_secret_general_exception(result)
        finally:
            self.client.close()
            LOG.debug("Closed connection to KMIP client for secret " +
                      "retreival")