zkey-kmip: Configure APQNs

The KMIP plugin supports CCA and EP11 APQNs, but only it can only be
configured with one type. Once configured with one type of APQN, it accepts
only APQNs of the same type.

It supports key types matching to the APQn type it is configured with.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Ingo Franzki
2021-05-21 11:04:01 +02:00
committed by Jan Höppner
parent 268dcebe23
commit e24629b977
3 changed files with 217 additions and 1 deletions

View File

@@ -604,6 +604,10 @@ int select_cca_adapter(struct cca_lib *cca, unsigned int card,
if (rc != 0)
return rc;
/* Deallocate any adapter first, in case one is already allocated */
for (adapter = 1; adapter <= adapters; adapter++)
deallocate_cca_adapter(cca, adapter, false);
/* Disable the AUTOSELECT option */
rc = deallocate_cca_adapter(cca, 0, verbose);
if (rc != 0)

View File

@@ -19,6 +19,7 @@
#include "lib/zt_common.h"
#include "lib/util_libc.h"
#include "lib/util_panic.h"
#include "lib/util_path.h"
#include "zkey-kmip.h"
#include "../kms-plugin.h"
@@ -44,6 +45,58 @@ int kms_bind(const char *UNUSED(config_path))
return 0;
}
/**
* Checks if the plugin configuration is complete. Sets the appropriate flags
* in the plugin handle
*
* @param ph the plugin handle
*/
static void _check_config_complete(struct plugin_handle *ph)
{
ph->apqns_configured =
plugin_check_property(&ph->pd, KMIP_CONFIG_APQNS) &&
plugin_check_property(&ph->pd, KMIP_CONFIG_APQN_TYPE) &&
ph->card_type != CARD_TYPE_ANY;
ph->config_complete = ph->apqns_configured;
}
/**
* Returns a textual name of the specified card type.
*
* @param card_type the card type
*
* @returns a constant string, or NULL if an invalid card type is specified
*/
static const char *_card_type_to_str(enum card_type card_type)
{
switch (card_type) {
case CARD_TYPE_CCA:
return KMIP_APQN_TYPE_CCA;
case CARD_TYPE_EP11:
return KMIP_APQN_TYPE_EP11;
default:
return NULL;
}
}
/**
* Returns the card type for the textual name of the card type.
*
* @param card_type the card type as string
*
* @returns the card type value, or CARD_TYPE_ANY if unknown
*/
static enum card_type _card_type_from_str(const char *card_type)
{
if (strcmp(card_type, KMIP_APQN_TYPE_CCA) == 0)
return CARD_TYPE_CCA;
if (strcmp(card_type, KMIP_APQN_TYPE_EP11) == 0)
return CARD_TYPE_EP11;
return CARD_TYPE_ANY;
}
/**
* Initializes a KMS plugin for usage by zkey. When a repository is bound to a
* KMS plugin, zkey calls this function when opening the repository.
@@ -58,6 +111,7 @@ int kms_bind(const char *UNUSED(config_path))
kms_handle_t kms_initialize(const char *config_path, bool verbose)
{
struct plugin_handle *ph;
char *apqn_type = NULL;
int rc;
util_assert(config_path != NULL, "Internal error: config_path is NULL");
@@ -70,6 +124,21 @@ kms_handle_t kms_initialize(const char *config_path, bool verbose)
if (rc != 0)
goto error;
_check_config_complete(ph);
pr_verbose(&ph->pd, "Plugin configuration is %scomplete",
ph->config_complete ? "" : "in");
ph->card_type = CARD_TYPE_ANY;
apqn_type = properties_get(ph->pd.properties, KMIP_CONFIG_APQN_TYPE);
if (apqn_type != NULL) {
ph->card_type = _card_type_from_str(apqn_type);
free(apqn_type);
if (ph->card_type == CARD_TYPE_ANY) {
pr_verbose(&ph->pd, "APQN type invalid: %s", apqn_type);
goto error;
}
}
return (kms_handle_t)ph;
error:
@@ -148,6 +217,27 @@ bool kms_supports_key_type(const kms_handle_t handle,
plugin_clear_error(&ph->pd);
switch (ph->card_type) {
case CARD_TYPE_CCA:
if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0)
return true;
if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0)
return true;
break;
case CARD_TYPE_EP11:
if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0)
return true;
break;
default:
if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0)
return true;
if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0)
return true;
if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0)
return true;
break;
}
return false;
}
@@ -203,6 +293,60 @@ const struct util_opt *kms_get_command_options(const char *command,
return NULL;
}
/**
* Check the specified APQns and assure that they are all of the right type.
*
* @param ph the plugin handle
* @param apqns a list of APQNs to associate with the KMS plugin, or
* NULL if no APQNs are specified.
* @param num_apqns number of APQNs in above array. 0 if no APQNs are
* specified.
*
* @returns 0 on success, a negative errno in case of an error.
*/
static int _check_apqns(struct plugin_handle *ph, const struct kms_apqn *apqns,
size_t num_apqns)
{
size_t i;
int rc;
if (num_apqns == 0)
return 0;
if (ph->card_type == CARD_TYPE_ANY) {
/*
* No APQNs configured yet, accept any APQN type, but all must
* be of the same type.
*/
ph->card_type = sysfs_get_card_type(apqns[0].card);
if (ph->card_type == CARD_TYPE_ANY) {
_set_error(ph, "The APQN %02x.%04x is not available or "
"has an unsupported type", apqns[0].card,
apqns[0].domain);
return -EINVAL;
}
}
pr_verbose(&ph->pd, "Check APQNs for card type %s",
_card_type_to_str(ph->card_type));
for (i = 0; i < num_apqns; i++) {
rc = sysfs_is_apqn_online(apqns[i].card, apqns[i].domain,
ph->card_type);
if (rc != 1) {
_set_error(ph, "APQN %02x.%04x is not of the right "
"type. The plugin is configured to use "
"APQNs of type %s", apqns[i].card,
apqns[i].domain,
_card_type_to_str(ph->card_type));
return -EINVAL;
}
}
return 0;
}
/**
* Configures (or re-configures) a KMS plugin. This function can be called
* several times to configure a KMS plugin is several steps (if supported by the
@@ -235,6 +379,9 @@ int kms_configure(const kms_handle_t handle,
const struct kms_option *options, size_t num_options)
{
struct plugin_handle *ph = handle;
bool config_changed = false;
char *apqn_str = NULL;
int rc = 0;
size_t i;
util_assert(handle != NULL, "Internal error: handle is NULL");
@@ -263,7 +410,63 @@ int kms_configure(const kms_handle_t handle,
plugin_clear_error(&ph->pd);
return 0;
if (apqns != NULL) {
rc = _check_apqns(ph, apqns, num_apqns);
if (rc != 0)
goto out;
if (num_apqns > 0 && ph->card_type == CARD_TYPE_CCA) {
rc = cross_check_cca_apka_apqns(&ph->pd, apqns,
num_apqns);
if (rc != 0) {
_set_error(ph, "Your CCA APKA master key setup "
"is improper");
goto out;
}
}
apqn_str = build_kms_apqn_string(apqns, num_apqns);
rc = properties_set(ph->pd.properties, KMIP_CONFIG_APQNS,
apqn_str);
if (rc != 0) {
_set_error(ph, "Failed to set APQNs property: %s",
strerror(-rc));
goto out;
}
rc = properties_set(ph->pd.properties, KMIP_CONFIG_APQN_TYPE,
_card_type_to_str(ph->card_type));
if (rc != 0) {
_set_error(ph, "Failed to set APQN-Type property: %s",
strerror(-rc));
goto out;
}
config_changed = true;
}
out:
if (apqn_str != NULL)
free(apqn_str);
if (rc == 0) {
if (config_changed) {
rc = plugin_save_config(&ph->pd);
if (rc != 0)
goto ret;
_check_config_complete(ph);
pr_verbose(&ph->pd,
"Plugin configuration is %scomplete",
ph->config_complete ? "" : "in");
}
if (!ph->config_complete)
rc = -EAGAIN;
}
ret:
return rc;
}
/**

View File

@@ -16,11 +16,20 @@
#include "kmipclient/kmipclient.h"
#include "../plugin-utils.h"
#include "../pkey.h"
struct plugin_handle {
struct plugin_data pd;
bool apqns_configured;
enum card_type card_type;
bool config_complete;
};
#define KMIP_CONFIG_FILE "kmip.conf"
#define KMIP_CONFIG_APQNS "apqns"
#define KMIP_CONFIG_APQN_TYPE "apqn-type"
#define KMIP_APQN_TYPE_CCA "CCA"
#define KMIP_APQN_TYPE_EP11 "EP11"
#endif