zkey: Add key management system specific commands

Add command 'kms' and the following sub-commands of it to handle
key management system plugin binding and unbinding:
- plugins: List available/configured KMS plugins
- bind:    Binds a KMS plugin to the repository
- unbind:  Unbinds a KMS plugin from the repository
- info:    Displays information about the currently bound KMS plugin

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
2020-05-27 10:14:36 +02:00
committed by Jan Höppner
parent 1b0ab844b4
commit c6c4df9697
4 changed files with 346 additions and 2 deletions

View File

@@ -39,6 +39,13 @@
#define KMS_CONFIG_PROP_APQNS "apqns"
#define KMS_CONFIG_LOCAL "local"
static const char * const key_types[] = {
KEY_TYPE_CCA_AESDATA,
KEY_TYPE_CCA_AESCIPHER,
KEY_TYPE_EP11_AES,
NULL
};
typedef const struct kms_functions *(*kms_get_functions_t)(void);
#define pr_verbose(verbose, fmt...) do { \
@@ -739,3 +746,69 @@ out:
free(filename);
return rc;
}
/**
* Displays information about the KMS plugin and its configuration
*
* @param[in] kms_info information of the currently bound plugin.
*
* @returns 0 for success or a negative errno in case of an error.
*/
int print_kms_info(struct kms_info *kms_info)
{
bool first;
int rc = 0;
size_t i;
util_assert(kms_info != NULL, "Internal error: kms_info is NULL");
if (kms_info->plugin_lib == NULL) {
rc = -ENOENT;
warnx("The repository is not bound to a KMS plugin");
goto out;
}
printf("KMS-Plugin: %s\n", kms_info->plugin_name);
if (kms_info->funcs->kms_supports_key_type != NULL) {
for (i = 0, first = true; key_types[i] != NULL; i++) {
if (kms_info->funcs->kms_supports_key_type(
kms_info->handle, key_types[i])) {
printf(" %s %s\n", first ?
"Supported key types:" :
" ", key_types[i]);
first = false;
}
}
if (first)
printf(" Supported key types: (none)\n");
} else {
printf(" Supported key types: (unknown)\n");
}
if (kms_info->apqns == NULL || kms_info->num_apqns == 0) {
printf(" APQNs: (configuration required)\n");
goto kms_info;
}
for (i = 0; i < kms_info->num_apqns; i++)
printf(" %s %02x.%04x\n",
i == 0 ? "APQNs:" : " ",
kms_info->apqns[i].card,
kms_info->apqns[i].domain);
kms_info:
if (kms_info->funcs->kms_display_info == NULL)
goto out;
rc = kms_info->funcs->kms_display_info(kms_info->handle);
if (rc != 0) {
warnx("Failed to display information about the plugin: %s",
strerror(-rc));
print_last_kms_error(kms_info);
goto out;
}
out:
return rc;
}

View File

@@ -45,4 +45,6 @@ int bind_kms_plugin(struct keystore *keystore, const char *plugin,
int unbind_kms_plugin(struct kms_info *kms_info, struct keystore *keystore,
bool verbose);
int print_kms_info(struct kms_info *kms_info);
#endif

View File

@@ -15,6 +15,12 @@ zkey \- Manage secure AES keys
.
.PP
.B zkey
.I command sub-command
.RB [ OPTIONS ]
.
.
.PP
.B zkey
.BR \-\-help | \-h
.br
.B zkey
@@ -775,6 +781,85 @@ is 6.3.27 or later. For the supported environments and downloads, see:
\fIhttp://www.ibm.com/security/cryptocards\fP
.
.
.SH COMMANDS FOR KEY MANAGEMENT SYSTEM INTEGRATION
.
Use the \fBkms\fP command to control the integration into key management
systems. The \fBkms\fP command offers several subcommands for key management
specific operations. Use \fBzkey kms \-\-help\fP to show the available
subcommands.
.
.SS "List key management system plugins"
.
.B zkey kms
.BR plugins | pl
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B kms plugins
command to display a list of configured key management system plugins (KMS
plugins). It displays the key management system plugin name, and the shared
library that implements the plugin.
.
.P
Key management system plugins are configured in configuration file
\fB/etc/zkey/kms-plugins.conf\fP. This file contains the KMS plugin name and
its shared library. Set environment variable \fBZKEY_KMS_PLUGINS\fP to point to
a different file to use a different KMS plugin configuration file.
.
.SS "Bind the repository to a key management system"
.
.B zkey kms
.BR bind | bi
.I KMS\-plugin\-name
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B kms bind
command to bind the repository to a key management system (KMS).
The \fBkms plugins\fP command displays a list of configured key management
system plugins that can be used.
.
.PP
After binding a repository to a key management system, the KMS plugin must
first be configured. Use the \fBkms configure\fP command to
configure the plugin. As a minimum, you must associate APQNs with the key
management system plugin. The plugin may require additional configuration
before it is fully functioning. Use the \fBkms info\fP command to display
information about the key management system plugin and its configuration.
.
.PP
When a key repository is bound to a key management system, then all keys are
generated by this key management system per default, and are thus also bound to
the key management system. Any additional information associated with the keys
in the repository is also stored in the key management system.
.
.SS "Unbind the repository from a key management system"
.
.B zkey kms
.BR unbind | unb
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B kms unbind
command to unbind the repository from a key management system (KMS). All keys
that are currently bound to the key management system, are unbound and become
local keys. You are prompted to confirm the unbinding.
.
.SS "Display information about a key management system plugin"
.
.B zkey kms
.BR info | in
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B kms info
command to display information about the currently bound key management system
plugin (KMS plugin) and its configuration.
.
.
.
.SH OPTIONS
@@ -1440,4 +1525,11 @@ If
.B $ZKEY_REPOSITORY
is set, it specifies the location of the secure key repository.
If it is not set, then the the default location of the secure key
repository is \fB/etc/zkey/repository\fP.
repository is \fB/etc/zkey/repository\fP.
.TP
.BR ZKEY_KMS_PLUGINS
If
.B $ZKEY_KMS_PLUGINS
is set, it specifies the name of the KMS plugin configuration file.
If it is not set, then the default KMS plugin configuration file
\fB/etc/zkey/kms-plugins.conf\fP is used.

View File

@@ -33,6 +33,7 @@
#include "misc.h"
#include "pkey.h"
#include "utils.h"
#include "kms.h"
/*
* Program configuration
@@ -115,6 +116,11 @@ static struct zkey_globals {
#define COMMAND_CRYPTTAB "crypttab"
#define COMMAND_CRYPTSETUP "cryptsetup"
#define COMMAND_CONVERT "convert"
#define COMMAND_KMS "kms"
#define COMMAND_KMS_PLUGINS "plugins"
#define COMMAND_KMS_BIND "bind"
#define COMMAND_KMS_UNBIND "unbind"
#define COMMAND_KMS_INFO "info"
#define ZKEY_COMMAND_MAX_LEN 10
@@ -852,6 +858,7 @@ struct zkey_command {
char *pos_arg_alternate;
char **arg_alternate_value;
int need_keystore;
int use_kms_plugin;
struct zkey_command *sub_commands;
};
@@ -868,6 +875,60 @@ static int command_copy(void);
static int command_crypttab(void);
static int command_cryptsetup(void);
static int command_convert(void);
static int command_kms_plugins(void);
static int command_kms_bind(void);
static int command_kms_unbind(void);
static int command_kms_info(void);
static struct zkey_command zkey_kms_commands[] = {
{
.command = COMMAND_KMS_PLUGINS,
.abbrev_len = 2,
.function = command_kms_plugins,
.short_desc = "Lists key management system plugins",
.long_desc = "Lists available key management system (KMS) "
"plugins.",
.has_options = 1,
},
{
.command = COMMAND_KMS_BIND,
.abbrev_len = 2,
.function = command_kms_bind,
.short_desc = "Binds the repository to a key management system "
"plugin",
.long_desc = "Binds the repository to the specified key "
"management system (KMS) plugin.",
.need_keystore = 1,
.has_options = 1,
.pos_arg = "[KMS-PLUGIN]",
},
{
.command = COMMAND_KMS_UNBIND,
.abbrev_len = 3,
.function = command_kms_unbind,
.short_desc = "Unbinds the repository from a key management "
"system plugin",
.long_desc = "Unbinds the repository from the current key "
"management system (KMS) plugin, and turns all "
"KMS-bound keys into local keys",
.need_keystore = 1,
.has_options = 1,
.use_kms_plugin = 1,
},
{
.command = COMMAND_KMS_INFO,
.abbrev_len = 2,
.function = command_kms_info,
.short_desc = "Displays information about a key management "
"system plugin",
.long_desc = "Displays information about the current key "
"management system (KMS) plugin",
.need_keystore = 1,
.has_options = 1,
.use_kms_plugin = 1,
},
{ .command = NULL }
};
static struct zkey_command zkey_commands[] = {
{
@@ -1017,6 +1078,15 @@ static struct zkey_command zkey_commands[] = {
.pos_arg = "[SECURE-KEY-FILE]",
.pos_arg_optional = 1,
},
{
.command = COMMAND_KMS,
.abbrev_len = 2,
.short_desc = "key management system (KMS) support",
.long_desc = "Provides subcommands for key management system "
"(KMS) support.",
.has_options = 1,
.sub_commands = zkey_kms_commands,
},
{ .command = NULL }
};
@@ -2002,6 +2072,97 @@ static int command_convert(void)
return EXIT_SUCCESS;
}
/*
* Command handler for 'kms plugins'.
*
* List KMS plugins
*/
static int command_kms_plugins(void)
{
int rc;
rc = list_kms_plugins(g.verbose);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
/*
* Command handler for 'kms bind'.
*
* Bind repository to a KMS plugin
*/
static int command_kms_bind(void)
{
int rc;
rc = bind_kms_plugin(g.keystore, g.pos_arg, g.verbose);
if (rc == 0)
util_print_indented("The KMS plugin requires configuration, "
"run 'zkey kms configure [OPTIONS]' to "
"complete the KMS binding process", 0);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
/*
* Command handler for 'kms unbind'.
*
* Unbind repository from a KMS plugin
*/
static int command_kms_unbind(void)
{
char *msg;
int rc;
if (g.kms_info.plugin_lib == NULL) {
rc = -ENOENT;
warnx("The repository is not bound to a KMS plugin");
return EXIT_FAILURE;
}
util_asprintf(&msg, "%s: Unbind this repository from KMS plugin '%s' "
"and turn all KMS-bound keys into local keys [y/N]? ",
program_invocation_short_name, g.kms_info.plugin_name);
util_print_indented(msg, 0);
free(msg);
if (!prompt_for_yes(g.verbose)) {
warnx("Operation aborted");
return EXIT_FAILURE;
}
rc = keystore_kms_keys_unbind(g.keystore);
if (rc != 0) {
warnx("Failed to turn KMS-bound keys into local keys: %s",
strerror(-rc));
return EXIT_FAILURE;
}
rc = unbind_kms_plugin(&g.kms_info, g.keystore, g.verbose);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
/*
* Command handler for 'kms info'.
*
* Prints information about a KMS plugin
*/
static int command_kms_info(void)
{
int rc;
if (g.kms_info.plugin_lib == NULL) {
rc = -ENOENT;
warnx("The repository is not bound to a KMS plugin");
return EXIT_FAILURE;
}
rc = print_kms_info(&g.kms_info);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
/**
* Opens the keystore. The keystore directory is either the
* default directory or as specified in an environment variable
@@ -2140,6 +2301,12 @@ int main(int argc, char *argv[])
else
cmd = command;
if (cmd != NULL && cmd->use_kms_plugin) {
rc = check_for_kms_plugin(&g.kms_info, g.verbose);
if (rc != 0)
return EXIT_FAILURE;
}
while (1) {
c = util_opt_getopt_long(arg_count, args);
if (c == -1)
@@ -2314,7 +2481,8 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
if (cmd->need_keystore || g.pos_arg == NULL) {
if (cmd->need_keystore ||
(cmd->pos_arg_optional && g.pos_arg == NULL)) {
rc = open_keystore();
if (rc != EXIT_SUCCESS)
goto out;
@@ -2342,11 +2510,20 @@ int main(int argc, char *argv[])
}
}
if (g.kms_info.plugin_lib != NULL) {
rc = init_kms_plugin(&g.kms_info, g.verbose);
if (rc != 0) {
rc = EXIT_FAILURE;
goto out;
}
}
umask(0077);
rc = cmd->function();
out:
free_kms_plugin(&g.kms_info);
if (g.cca.lib_csulcca)
dlclose(g.cca.lib_csulcca);
if (g.ep11.lib_ep11)