mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zkey: Add more key management system specific commands
Add the following sub-commands for key management system plugin handling: - configure: Configure a KMS plugin - reencipher: Re-encipher secure keys used by a 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:
committed by
Jan Höppner
parent
3fa511cfb9
commit
35dd59d04c
@@ -73,7 +73,7 @@ properties.o: check-dep-zkey properties.c properties.h
|
||||
keystore.o: keystore.c keystore.h properties.h pkey.h cca.h ep11.h utils.h
|
||||
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h \
|
||||
ep11.h misc.h utils.h
|
||||
kms.o: kms.c kms.h kms-plugin.h
|
||||
kms.o: kms.c kms.h kms-plugin.h utils.h pkey.h
|
||||
|
||||
zkey: LDLIBS = -ldl -lcrypto
|
||||
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o kms.o $(libs)
|
||||
|
||||
916
zkey/kms.c
916
zkey/kms.c
@@ -11,6 +11,7 @@
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -24,8 +25,11 @@
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_rec.h"
|
||||
#include "lib/util_panic.h"
|
||||
#include "lib/util_prg.h"
|
||||
|
||||
#include "kms.h"
|
||||
#include "utils.h"
|
||||
#include "pkey.h"
|
||||
|
||||
#define ENVVAR_ZKEY_REPOSITORY "ZKEY_REPOSITORY"
|
||||
#define DEFAULT_KEYSTORE "/etc/zkey/repository"
|
||||
@@ -37,6 +41,8 @@
|
||||
#define KMS_CONFIG_PROP_KMS "kms"
|
||||
#define KMS_CONFIG_PROP_KMS_CONFIG "config"
|
||||
#define KMS_CONFIG_PROP_APQNS "apqns"
|
||||
#define KMS_CONFIG_PROP_CCA_APQNS "ep11_apqns"
|
||||
#define KMS_CONFIG_PROP_EP11_APQNS "cca_apqns"
|
||||
#define KMS_CONFIG_LOCAL "local"
|
||||
|
||||
static const char * const key_types[] = {
|
||||
@@ -981,3 +987,913 @@ int handle_kms_option(struct kms_info *kms_info, struct util_opt *opt_vec,
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
struct card_info {
|
||||
enum card_type type;
|
||||
int min_level;
|
||||
struct fw_version min_fw_version;
|
||||
struct kms_apqn *apqns;
|
||||
size_t num_apqns;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses an APQN and checks if it is online.
|
||||
*
|
||||
* @param[in] apqn the APQN to parse
|
||||
* @param[out] kms_apqn the parse APQN is filled in
|
||||
* @param{in] check if true, the APQN is checked to be online
|
||||
* @param[in] cards An array of cards types with its requirements
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _parse_and_check_apqn(const char *apqn, struct kms_apqn *kms_apqn,
|
||||
bool check, struct card_info *cards,
|
||||
size_t num_cards)
|
||||
{
|
||||
struct card_info *card_info = NULL;
|
||||
struct fw_version fw_version;
|
||||
int rc, card, domain, level;
|
||||
enum card_type type;
|
||||
regmatch_t pmatch[1];
|
||||
regex_t reg_buf;
|
||||
unsigned int num;
|
||||
size_t i;
|
||||
|
||||
rc = regcomp(®_buf, "[[:xdigit:]]+\\.[[:xdigit:]]", REG_EXTENDED);
|
||||
if (rc != 0)
|
||||
return -EIO;
|
||||
|
||||
rc = regexec(®_buf, apqn, (size_t)1, pmatch, 0);
|
||||
if (rc != 0) {
|
||||
warnx("The APQN '%s' is not valid", apqn);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sscanf(apqn, "%x.%x%n", &card, &domain, &num) != 2 ||
|
||||
num != strlen(apqn) || card < 0 || card > 0xff ||
|
||||
domain < 0 || domain > 0xFFFF) {
|
||||
warnx("The APQN '%s' is not valid", apqn);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
kms_apqn->card = card;
|
||||
kms_apqn->domain = domain;
|
||||
|
||||
if (!check) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
type = sysfs_get_card_type(card);
|
||||
if (type == -1) {
|
||||
warnx("The APQN %02x.%04x is not available or has an "
|
||||
"unsupported type", card, domain);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = sysfs_is_apqn_online(card, domain, CARD_TYPE_ANY);
|
||||
if (rc != 1) {
|
||||
warnx("The APQN %02x.%04x is not available or not online",
|
||||
card, domain);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0, card_info = NULL; i < num_cards; i++) {
|
||||
if (cards[i].type == type) {
|
||||
card_info = &cards[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (card_info == NULL) {
|
||||
warnx("APQN %02x.%04x: The card type is not supported by the "
|
||||
"KMS plugin", card, domain);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
level = sysfs_get_card_level(card);
|
||||
if (level < card_info->min_level) {
|
||||
warnx("APQN %02x.%04x: The card level is less than CEX%dn.",
|
||||
card, domain, card_info->min_level);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = sysfs_get_firmware_version(card, &fw_version, false);
|
||||
if (rc == 0) {
|
||||
if (fw_version.api_ordinal <
|
||||
card_info->min_fw_version.api_ordinal) {
|
||||
warnx("APQN %02x.%04x: The firmware version is too "
|
||||
"less", card, domain);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
if (card_info->min_level > 0 && card_info->min_level == level &&
|
||||
(fw_version.major < card_info->min_fw_version.major ||
|
||||
(fw_version.major == card_info->min_fw_version.major &&
|
||||
fw_version.minor < card_info->min_fw_version.minor))) {
|
||||
warnx("APQN %02x.%04x: The firmware version is too "
|
||||
"less", card, domain);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
regfree(®_buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add APQNs to the current APQN association of the KMS plugin
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] apqns the APQNs specification from --apqns option
|
||||
* @param[in] cards An array of card types with its requirements
|
||||
* @param[in] num_cardsqs The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _add_kms_apqns(struct kms_info *kms_info, const char *apqns,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
struct kms_apqn kms_apqn;
|
||||
char **new_apqns;
|
||||
int i, rc = 0;
|
||||
size_t k;
|
||||
|
||||
new_apqns = str_list_split(apqns);
|
||||
|
||||
for (i = 0; new_apqns[i] != NULL; i++) {
|
||||
rc = _parse_and_check_apqn(new_apqns[i], &kms_apqn, true,
|
||||
cards, num_cards);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
for (k = 0; k < kms_info->num_apqns; k++) {
|
||||
if (kms_apqn.card == kms_info->apqns[k].card &&
|
||||
kms_apqn.domain == kms_info->apqns[k].domain) {
|
||||
warnx("APQN %02x.%04x is already associated "
|
||||
"with the KMS plugin", kms_apqn.card,
|
||||
kms_apqn.domain);
|
||||
rc = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ARRAY_ADD(kms_info->apqns, kms_info->num_apqns,
|
||||
sizeof(struct kms_apqn), &kms_apqn);
|
||||
}
|
||||
|
||||
out:
|
||||
str_list_free_string_array(new_apqns);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove APQNs from the current APQN association of the KMS plugin
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] apqns the APQNs specification from --apqns option
|
||||
* @param[in] cards An array of card types with its requirements
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _remove_kms_apqns(struct kms_info *kms_info, const char *apqns,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
struct kms_apqn kms_apqn;
|
||||
char **rem_apqns;
|
||||
int i, rc = 0;
|
||||
size_t k;
|
||||
|
||||
rem_apqns = str_list_split(apqns);
|
||||
|
||||
for (i = 0; rem_apqns[i] != NULL; i++) {
|
||||
rc = _parse_and_check_apqn(rem_apqns[i], &kms_apqn, false,
|
||||
cards, num_cards);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
for (k = 0; k < kms_info->num_apqns; k++) {
|
||||
if (kms_apqn.card == kms_info->apqns[k].card &&
|
||||
kms_apqn.domain == kms_info->apqns[k].domain) {
|
||||
ARRAY_REMOVE(kms_info->apqns,
|
||||
kms_info->num_apqns,
|
||||
sizeof(struct kms_apqn), k);
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
warnx("APQN %02x.%04x is not associated with the KMS plugin",
|
||||
kms_apqn.card, kms_apqn.domain);
|
||||
rc = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
free(rem_apqns);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the APQN association of the KMS plugin
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] apqns the APQNs specification from --apqns option
|
||||
* @param[in] cards An array of card types with its requirements
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _set_kms_apqns(struct kms_info *kms_info, const char *apqns,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
if (kms_info->apqns != NULL)
|
||||
free(kms_info->apqns);
|
||||
kms_info->apqns = NULL;
|
||||
kms_info->num_apqns = 0;
|
||||
|
||||
if (strlen(apqns) == 0) {
|
||||
/* Indicate empty list specified */
|
||||
kms_info->apqns = util_malloc(sizeof(struct kms_apqn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _add_kms_apqns(kms_info, apqns, cards, num_cards);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the APQN association of the KMS plugin
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] apqns the APQNs specification from --apqns option
|
||||
* @param[in] cards An array of card types with its requirements
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _change_kms_apqns(struct kms_info *kms_info, const char *apqns,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
switch (*apqns) {
|
||||
case '+':
|
||||
if (kms_info->apqns != NULL && kms_info->num_apqns > 0)
|
||||
return _add_kms_apqns(kms_info, &apqns[1], cards,
|
||||
num_cards);
|
||||
else
|
||||
return _set_kms_apqns(kms_info, &apqns[1], cards,
|
||||
num_cards);
|
||||
case '-':
|
||||
if (kms_info->apqns != NULL && kms_info->num_apqns > 0)
|
||||
return _remove_kms_apqns(kms_info, &apqns[1], cards,
|
||||
num_cards);
|
||||
|
||||
warnx("No APQNs are currently associated with the KMS plugin");
|
||||
return -ENOENT;
|
||||
default:
|
||||
return _set_kms_apqns(kms_info, apqns, cards, num_cards);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the crypto card requirements per card type base on the key types that
|
||||
* the KMS plugin supports.
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[out] cards on return: An array of card types with its
|
||||
* requirements. The caller must free this array if
|
||||
* no longer used.
|
||||
* @param[out] num_cards on return: The number of elements in above array
|
||||
* @param[in] verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns the card type
|
||||
*/
|
||||
static int _get_supported_card_types(struct kms_info *kms_info,
|
||||
struct card_info **cards,
|
||||
size_t *num_cards, bool verbose)
|
||||
{
|
||||
struct card_info new_card = { 0 };
|
||||
const struct fw_version *fw_ver;
|
||||
struct card_info *req;
|
||||
enum card_type type;
|
||||
int i, level;
|
||||
size_t k;
|
||||
|
||||
util_assert(kms_info != NULL, "Internal error: kms_info is NULL");
|
||||
util_assert(cards != NULL, "Internal error: reqs is NULL");
|
||||
util_assert(num_cards != NULL, "Internal error: num_reqs is NULL");
|
||||
|
||||
*cards = NULL;
|
||||
*num_cards = 0;
|
||||
|
||||
if (kms_info->funcs->kms_supports_key_type == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; key_types[i] != NULL; i++) {
|
||||
if (kms_info->funcs->kms_supports_key_type(kms_info->handle,
|
||||
key_types[i])) {
|
||||
pr_verbose(verbose, "KMS plugin supports key type %s",
|
||||
key_types[i]);
|
||||
|
||||
type = get_card_type_for_keytype(key_types[i]);
|
||||
level = get_min_card_level_for_keytype(key_types[i]);
|
||||
fw_ver = get_min_fw_version_for_keytype(key_types[i]);
|
||||
|
||||
for (req = NULL, k = 0; k < *num_cards; k++) {
|
||||
if ((*cards)[k].type == type)
|
||||
req = &(*cards)[k];
|
||||
}
|
||||
|
||||
if (req == NULL) {
|
||||
new_card.type = type;
|
||||
new_card.min_level = level;
|
||||
if (fw_ver != NULL)
|
||||
new_card.min_fw_version = *fw_ver;
|
||||
|
||||
ARRAY_ADD(*cards, *num_cards,
|
||||
sizeof(struct card_info),
|
||||
&new_card);
|
||||
req = &(*cards)[*num_cards - 1];
|
||||
}
|
||||
|
||||
if (req->min_level < level) {
|
||||
req->min_level = level;
|
||||
|
||||
if (fw_ver != NULL) {
|
||||
if (req->min_fw_version.api_ordinal <
|
||||
fw_ver->api_ordinal ||
|
||||
req->min_fw_version.major <
|
||||
fw_ver->major ||
|
||||
(req->min_fw_version.major ==
|
||||
fw_ver->major &&
|
||||
req->min_fw_version.minor <
|
||||
fw_ver->minor))
|
||||
req->min_fw_version = *fw_ver;
|
||||
}
|
||||
}
|
||||
|
||||
pr_verbose(verbose, "Card type: %d", req->type);
|
||||
pr_verbose(verbose, "Card level: %d", req->min_level);
|
||||
pr_verbose(verbose, "Fw version: %d.%d (API: %d)",
|
||||
req->min_fw_version.major,
|
||||
req->min_fw_version.minor,
|
||||
req->min_fw_version.api_ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
pr_verbose(verbose, "%lu card type are supported", *num_cards);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an APQN list per card type.
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] cards An array of card types to build APQNs lists for
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _get_apqns_per_card_type(struct kms_info *kms_info,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
enum card_type type;
|
||||
size_t i, k;
|
||||
bool found;
|
||||
|
||||
for (i = 0; i < kms_info->num_apqns; i++) {
|
||||
if (!sysfs_is_apqn_online(kms_info->apqns[i].card,
|
||||
kms_info->apqns[i].domain, 0)) {
|
||||
warnx("The APQN %02x.%04x is not online",
|
||||
kms_info->apqns[i].card,
|
||||
kms_info->apqns[i].domain);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
type = sysfs_get_card_type(kms_info->apqns[i].card);
|
||||
for (k = 0, found = false; k < num_cards; k++) {
|
||||
if (cards[k].type == type) {
|
||||
ARRAY_ADD(cards[k].apqns, cards[k].num_apqns,
|
||||
sizeof(struct kms_apqn),
|
||||
&kms_info->apqns[i]);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
warnx("The APQN %02x.%04x is not available of has an "
|
||||
"unsupported type", kms_info->apqns[i].card,
|
||||
kms_info->apqns[i].domain);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an APQN string from an APQN array
|
||||
*
|
||||
* @param[in] apqns An array of APQNs
|
||||
* @param[in] num_apqns The number of elements in above array
|
||||
*
|
||||
* @return an allocated string with the APQNs
|
||||
*/
|
||||
static char *_build_apqn_string(struct kms_apqn *apqns, size_t num_apqns)
|
||||
{
|
||||
char *apqn_str, *str;
|
||||
size_t size, i;
|
||||
|
||||
if (num_apqns == 0) {
|
||||
apqn_str = util_malloc(1);
|
||||
*apqn_str = '\0';
|
||||
return apqn_str;
|
||||
}
|
||||
|
||||
size = num_apqns * 8; /* 'cc.dddd' plus ',' or '\0' */
|
||||
apqn_str = util_malloc(size);
|
||||
|
||||
str = apqn_str;
|
||||
for (i = 0; i < num_apqns; i++) {
|
||||
if (i != 0) {
|
||||
*str = ',';
|
||||
str++;
|
||||
}
|
||||
|
||||
sprintf(str, "%02x.%04x", apqns[i].card, apqns[i].domain);
|
||||
str += 7;
|
||||
}
|
||||
|
||||
return apqn_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the APQNS properties in the KMS properties to reflect the list of
|
||||
* APQNs contained in kms_info and supported card types.
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] cards An array of card types supported
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
* @param[in] verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _update_apqns_properties(struct kms_info *kms_info,
|
||||
struct card_info *cards, size_t num_cards,
|
||||
bool verbose)
|
||||
{
|
||||
char *apqns = NULL;
|
||||
char *prop;
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
rc = properties_remove(kms_info->props,
|
||||
KMS_CONFIG_PROP_CCA_APQNS);
|
||||
if (rc != 0 && rc != -ENOENT) {
|
||||
pr_verbose(verbose, "Failed to remove the APQNS "
|
||||
"property: %s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = properties_remove(kms_info->props,
|
||||
KMS_CONFIG_PROP_EP11_APQNS);
|
||||
if (rc != 0 && rc != -ENOENT) {
|
||||
pr_verbose(verbose, "Failed to remove the APQNS "
|
||||
"property: %s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (kms_info->num_apqns == 0) {
|
||||
rc = properties_remove(kms_info->props, KMS_CONFIG_PROP_APQNS);
|
||||
if (rc != 0 && rc != -ENOENT) {
|
||||
pr_verbose(verbose, "Failed to remove the APQNS "
|
||||
"property: %s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
pr_verbose(verbose, "APQNs: none");
|
||||
return 0;
|
||||
}
|
||||
|
||||
apqns = _build_apqn_string(kms_info->apqns, kms_info->num_apqns);
|
||||
pr_verbose(verbose, "APQNs: '%s'", apqns);
|
||||
|
||||
rc = properties_set(kms_info->props, KMS_CONFIG_PROP_APQNS, apqns);
|
||||
free(apqns);
|
||||
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to set the APQNS property: %s",
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_cards; i++) {
|
||||
switch (cards[i].type) {
|
||||
case CARD_TYPE_CCA:
|
||||
prop = KMS_CONFIG_PROP_CCA_APQNS;
|
||||
break;
|
||||
case CARD_TYPE_EP11:
|
||||
prop = KMS_CONFIG_PROP_EP11_APQNS;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
apqns = _build_apqn_string(cards[i].apqns, cards[i].num_apqns);
|
||||
pr_verbose(verbose, "%s: '%s'", prop, apqns);
|
||||
|
||||
rc = properties_set(kms_info->props, prop, apqns);
|
||||
free(apqns);
|
||||
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to set the %s property: %s",
|
||||
prop, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross checks the APQNs per card type
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] cards An array of card types to build APQNs lists for
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
* @param[in] verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _cross_check_apqns(struct card_info *cards, size_t num_cards,
|
||||
bool verbose)
|
||||
{
|
||||
char *apqns;
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
for (i = 0; i < num_cards; i++) {
|
||||
if (cards[i].num_apqns == 0)
|
||||
continue;
|
||||
|
||||
apqns = _build_apqn_string(cards[i].apqns, cards[i].num_apqns);
|
||||
|
||||
rc = cross_check_apqns(apqns, NULL, cards[i].min_level,
|
||||
&cards[i].min_fw_version, cards[i].type,
|
||||
true, verbose);
|
||||
free(apqns);
|
||||
|
||||
if (rc == -ENOTSUP)
|
||||
continue;
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks existing KMS-bound keys in the keystore of the new set of APQNs
|
||||
* would make them unusable. The user is prompted if so.
|
||||
*
|
||||
* @param[in] keystore the keystore
|
||||
* @param[in] cards An array of card types
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _check_keystore_keys(struct keystore *keystore,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
struct kms_info *kms_info = keystore->kms_info;
|
||||
struct card_info *card = NULL;
|
||||
enum card_type type;
|
||||
size_t i, k;
|
||||
char *msg;
|
||||
int rc;
|
||||
|
||||
for (i = 0; key_types[i] != NULL; i++) {
|
||||
type = get_card_type_for_keytype(key_types[i]);
|
||||
if (type <= 0)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < num_cards; k++) {
|
||||
if (cards[k].type == type) {
|
||||
card = &cards[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (card == NULL)
|
||||
continue;
|
||||
|
||||
pr_verbose(keystore->verbose, "Checking repository for "
|
||||
"KMS-bound keys of type %s", key_types[i]);
|
||||
|
||||
if (card->num_apqns > 0) {
|
||||
pr_verbose(keystore->verbose, "Set of APQNs for key "
|
||||
"type %s is not empty", key_types[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
util_asprintf(&msg, "The following keys of type '%s' are bound "
|
||||
"to KMS plugin '%s', and may become unusable "
|
||||
"with this set of APQNs:", key_types[i],
|
||||
kms_info->plugin_name);
|
||||
rc = keystore_msg_for_kms_key(keystore, key_types[i], msg);
|
||||
free(msg);
|
||||
|
||||
if (rc == -ENOENT) {
|
||||
pr_verbose(keystore->verbose, "No keys of type %s "
|
||||
"found", key_types[i]);
|
||||
continue;
|
||||
}
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
printf("Do you want to continue [y/N]? ");
|
||||
if (!prompt_for_yes(keystore->verbose)) {
|
||||
warnx("Operation aborted");
|
||||
return -ECANCELED;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates existing KMS-bound keys in the keystore with the set of APQNs that
|
||||
* match the key type.
|
||||
*
|
||||
* @param[in] keystore the keystore
|
||||
* @param[in] cards An array of card types
|
||||
* @param[in] num_cards The number of elements in above array
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
static int _update_keystore_keys(struct keystore *keystore,
|
||||
struct card_info *cards, size_t num_cards)
|
||||
{
|
||||
struct card_info *card = NULL;
|
||||
enum card_type type;
|
||||
size_t i, k;
|
||||
char *apqns;
|
||||
int rc;
|
||||
|
||||
for (i = 0; key_types[i] != NULL; i++) {
|
||||
type = get_card_type_for_keytype(key_types[i]);
|
||||
if (type <= 0)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < num_cards; k++) {
|
||||
if (cards[k].type == type) {
|
||||
card = &cards[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (card == NULL)
|
||||
continue;
|
||||
|
||||
apqns = _build_apqn_string(card->apqns, card->num_apqns);
|
||||
|
||||
pr_verbose(keystore->verbose, "Changing KMS-bound keys of "
|
||||
"type %s to: '%s'", key_types[i], apqns);
|
||||
|
||||
rc = keystore_kms_keys_set_property(keystore, key_types[i],
|
||||
PROP_NAME_APQNS, apqns);
|
||||
free(apqns);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to update APQNs for KMS-bound keys of "
|
||||
"type %s: %s", key_types[i], strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs configuration of the KMS plugin.
|
||||
*
|
||||
* @param[in] keystore the keystore
|
||||
* @param[in] apqns the APQNs specification from --apqns option, or
|
||||
* NULL if the option was not specified
|
||||
* @param[in] kms_options an array of KMS options specified, or NULL if no
|
||||
* KMS options have been specified
|
||||
* @param[in] num_kms_options the number of options in above array
|
||||
* @param[in] has_plugin_optins if true, then the KMS plugin uses KMS specific
|
||||
* options, false of no options are supported
|
||||
* @param[in] verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
* -EAGAIN to indicate that the specified configuration was accepted so far, but
|
||||
* the configuration is still incomplete, and needs to be completed.
|
||||
*/
|
||||
int configure_kms_plugin(struct keystore *keystore, const char *apqns,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool has_plugin_optins, bool verbose)
|
||||
{
|
||||
struct card_info *cards = NULL;
|
||||
struct kms_info *kms_info;
|
||||
bool incomplete = false;
|
||||
size_t i, num_cards = 0;
|
||||
int rc = 0;
|
||||
|
||||
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
||||
|
||||
kms_info = keystore->kms_info;
|
||||
if (kms_info->plugin_lib == NULL) {
|
||||
rc = -ENOENT;
|
||||
warnx("The repository is not bound to a KMS plugin");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (apqns == NULL) {
|
||||
if (kms_info->apqns == NULL || kms_info->num_apqns == 0) {
|
||||
warnx("Option '--apqns|-a' is required when no APQNS "
|
||||
"are associated with the KMS plugin");
|
||||
util_prg_print_parse_error();
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (has_plugin_optins && num_kms_options == 0) {
|
||||
warnx("At least one option is required");
|
||||
util_prg_print_parse_error();
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (apqns != NULL) {
|
||||
rc = _get_supported_card_types(kms_info, &cards, &num_cards,
|
||||
verbose);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
if (num_cards == 0) {
|
||||
warnx("The KMS plugin does not support any key type");
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _change_kms_apqns(kms_info, apqns, cards, num_cards);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = _get_apqns_per_card_type(kms_info, cards, num_cards);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = _cross_check_apqns(cards, num_cards, verbose);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = _check_keystore_keys(keystore, cards, num_cards);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = _update_apqns_properties(kms_info, cards, num_cards,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to update the APQNs: %s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (kms_info->funcs->kms_configure != NULL) {
|
||||
rc = kms_info->funcs->kms_configure(kms_info->handle,
|
||||
apqns != NULL ?
|
||||
kms_info->apqns : NULL,
|
||||
apqns != NULL ?
|
||||
kms_info->num_apqns : 0,
|
||||
kms_options,
|
||||
num_kms_options);
|
||||
|
||||
if (rc == -EAGAIN) {
|
||||
incomplete = true;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
warnx("Failed to configure the KMS plugin: '%s'",
|
||||
strerror(-rc));
|
||||
print_last_kms_error(kms_info);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (apqns != NULL) {
|
||||
rc = _save_kms_properties(keystore, kms_info->props, verbose);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = _update_keystore_keys(keystore, cards, num_cards);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
if (kms_info->num_apqns == 0)
|
||||
incomplete = true;
|
||||
}
|
||||
|
||||
out:
|
||||
if (cards != NULL) {
|
||||
for (i = 0; i < num_cards; i++)
|
||||
if (cards[i].apqns != NULL)
|
||||
free(cards[i].apqns);
|
||||
free(cards);
|
||||
}
|
||||
|
||||
if (rc == 0 && incomplete)
|
||||
rc = -EAGAIN;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs re-enciphering of secure keys internally used by the KMS plugin
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] from_old If true the keys are reenciphered from the OLD to
|
||||
* the CURRENT master key.
|
||||
* @param[in] to_new If true the keys are reenciphered from the CURRENT
|
||||
* to the OLD master key.
|
||||
* @param[in] inplace if true, the key will be re-enciphere in-place
|
||||
* @param[in] staged if true, the key will be re-enciphere not in-place
|
||||
* @param[in] complete if true, a pending re-encipherment is completed
|
||||
* @param[in] kms_options an array of KMS options specified, or NULL if no
|
||||
* KMS options have been specified
|
||||
* @param[in] num_kms_options the number of options in above array
|
||||
* @param[in] verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
* -EAGAIN to indicate that the specified configuration was accepted so far, but
|
||||
* the configuration is still incomplete, and needs to be completed.
|
||||
*/
|
||||
int reencipher_kms(struct kms_info *kms_info, bool from_old, bool to_new,
|
||||
bool inplace, bool staged, bool complete,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool verbose)
|
||||
{
|
||||
enum kms_reencipher_mode mode = KMS_REENC_MODE_AUTO;
|
||||
enum kms_reenc_mkreg mkreg = KMS_REENC_MKREG_AUTO;
|
||||
int rc = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (kms_info->funcs->kms_reenciper == NULL) {
|
||||
pr_verbose(verbose, "The KMS plugin does not support "
|
||||
"reencipher");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (inplace)
|
||||
mode = KMS_REENC_MODE_IN_PLACE;
|
||||
else if (staged)
|
||||
mode = KMS_REENC_MODE_STAGED;
|
||||
else if (complete)
|
||||
mode = KMS_REENC_MODE_STAGED_COMPLETE;
|
||||
|
||||
if (from_old && !to_new) {
|
||||
mkreg = KMS_REENC_MKREG_FROM_OLD;
|
||||
if (mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_IN_PLACE;
|
||||
} else if (to_new && !from_old) {
|
||||
mkreg = KMS_REENC_MKREG_TO_NEW;
|
||||
if (mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_STAGED;
|
||||
} else if (from_old && to_new) {
|
||||
mkreg = KMS_REENC_MKREG_FROM_OLD_TO_NEW;
|
||||
if (mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_STAGED;
|
||||
}
|
||||
|
||||
rc = kms_info->funcs->kms_reenciper(kms_info->handle, mode, mkreg,
|
||||
kms_options, num_kms_options);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to reencipher KMS plugin internal keys: %s",
|
||||
strerror(-rc));
|
||||
print_last_kms_error(kms_info);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -57,4 +57,13 @@ int handle_kms_option(struct kms_info *kms_info, struct util_opt *opt_vec,
|
||||
const char *optarg, struct kms_option **kms_options,
|
||||
size_t *num_kms_options, bool verbose);
|
||||
|
||||
int configure_kms_plugin(struct keystore *keystore, const char *apqns,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool has_plugin_optins, bool verbose);
|
||||
|
||||
int reencipher_kms(struct kms_info *kms_info, bool from_old, bool to_new,
|
||||
bool inplace, bool staged, bool complete,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool verbose);
|
||||
|
||||
#endif
|
||||
|
||||
193
zkey/zkey.1
193
zkey/zkey.1
@@ -860,6 +860,137 @@ Use the
|
||||
command to display information about the currently bound key management system
|
||||
plugin (KMS plugin) and its configuration.
|
||||
.
|
||||
.SS "Configure or re\-configure a key management system plugin"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR configure | con
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IR [+|-]card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms configure
|
||||
command to configure or re\-configure the currently bound key management system
|
||||
plugin (KMS plugin). As a minimum, you must associate APQNs with the key
|
||||
management system plugin. The plugin may require an initial configuration
|
||||
before it is fully functioning. Once configured, a plugin may allow you to
|
||||
change some configuration settings.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBkms configure\fP command. Use \fBkms configure
|
||||
\-\-help\fP to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
Configuring a key management system plugin may be a multi-step task. You can
|
||||
supply all configuration options at once or use the \fBkms configure\fP
|
||||
command several times supplying only one or a few configuration options each
|
||||
time, dependent on what the plugin supports. A plugin may also require to
|
||||
perform additional intermediate steps between two configuration attempts,
|
||||
e.g. perform tasks in the key management system user interface, or elsewhere.
|
||||
.PP
|
||||
Use the \fBkms info\fP command to display information about the key management
|
||||
system plugin and its current configuration.
|
||||
.
|
||||
.SS "Re-encipher secure keys used by a key management system plugin"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR reencipher | re
|
||||
.RB [ \-\-to\-new | \-n ]
|
||||
.RB [ \-\-from\-old | \-o ]
|
||||
.RB [ \-\-in-place | \-i ]
|
||||
.RB [ \-\-staged | \-s ]
|
||||
.RB [ \-\-complete | \-c ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms reencipher
|
||||
command to re-encipher secure keys internally used by the currently bound
|
||||
key management system plugin (KMS plugin) with a new master key. This command
|
||||
must be run when the master keys of the CCA or EP11 cryptographic adapter,
|
||||
that are associated with the plugin have been changed. Dependent on what key
|
||||
types the key management system plugin supports, it may internally use secure
|
||||
keys with CCA or EP11 cryptographic adapters, or both.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBkms reencipher\fP command. Use \fBkms reencipher
|
||||
\-\-help\fP to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
.B Note:
|
||||
The \fBkms reencipher\fP command does \fBnot\fP re-encipher secure keys that
|
||||
have been generated by or have been imported from the key management system
|
||||
plugin and are stored in the repository. Use the regular \fBreencipher\fP
|
||||
command to re-encipher those secure keys.
|
||||
.PP
|
||||
The CCA cryptographic adapter has three different registers to store
|
||||
master keys:
|
||||
.RS 2
|
||||
.IP "\(bu" 2
|
||||
The \fBCURRENT\fP register contains the current master key.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBOLD\fP register contains the previously used master key.
|
||||
Secure keys enciphered with the master key contained in the \fBOLD\fP
|
||||
register can still be used until the master key is changed again.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBNEW\fP register contains the new master key to be set.
|
||||
The master key in the \fBNEW\fP register cannot be used until it is made
|
||||
the current master key. You can pro-actively re-encipher a secure key with the
|
||||
\fBNEW\fP master key before this key is made the \fBCURRENT\fP key. Use the
|
||||
.B \-\-to-new
|
||||
option to do this.
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP An EP11 cryptographic adapter has only two registers to store master
|
||||
keys, \fBCURRENT\fP and \fBNEW\fP.
|
||||
.PP
|
||||
Use the
|
||||
.B \-\-from\-old
|
||||
option to re-encipher a secure key that is currently enciphered with
|
||||
the master key in the \fBOLD\fP register with the master key in the
|
||||
\fBCURRENT\fP register. This option is only available for CCA-type secure keys.
|
||||
.PP
|
||||
.PP
|
||||
If both the
|
||||
.B \-\-from-old
|
||||
and
|
||||
.B \-\-to-new
|
||||
options are specified, a secure key that is currently enciphered
|
||||
with the master key in the \fBOLD\fP register is re-enciphered with the
|
||||
master key in the \fBNEW\fP register.
|
||||
.PP
|
||||
If both options are omitted, the key management system plugin may
|
||||
automatically detect whether the secure key is currently enciphered with the
|
||||
master key in the \fBOLD\fP register or with the master key in the \fBCURRENT\fP
|
||||
register. If currently enciphered with the master key in the \fBOLD\fP register,
|
||||
it is re-enciphered with the master key in the \fBCURRENT\fP register.
|
||||
If currently enciphered with the master key in the \fBCURRENT\fP
|
||||
register, it is re-enciphered with the master key in the \fBNEW\fP register.
|
||||
If for this case the \fBNEW\fP register does not contain a valid master key,
|
||||
then the re-encipher operation fails.
|
||||
.PP
|
||||
Re-enciphering a secure key used by a key management system plugin can be
|
||||
performed \fBin-place\fP, or in \fBstaged\fP mode.
|
||||
.PP
|
||||
\fB"In-place"\fP immediately replaces the secure key with the re-enciphered
|
||||
secure key. Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed
|
||||
in-place per default. You can use option \fB\-\-in-place\fP to force an
|
||||
in-place re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case.
|
||||
A secure key that was re-enciphered in-place from \fBCURRENT\fP to \fBNEW\fP
|
||||
is no longer valid, until the new CCA or EP11 master key has been made the
|
||||
current one.
|
||||
.PP
|
||||
\fBStaged\fP mode means that the re-enciphered secure key is stored separately.
|
||||
Thus the current secure key is still valid at this point. Once the new CCA or
|
||||
EP11 master key has been set (made active), you must rerun the \fBkms
|
||||
reencipher\fP command with option \fB\-\-complete\fP to complete the staged
|
||||
re-enciphering. Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is performed in
|
||||
staged mode per default. You can use option \fB\-\-staged\fP to force a staged
|
||||
re-enciphering for the \fBOLD\fP to \fBCURRENT\fP case.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
@@ -1426,6 +1557,68 @@ to convert a secure key without prompting for a confirmation.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms configure command"
|
||||
.TP
|
||||
.BR \-a ", " \-\-apqns\~\fI[+|-]card1.domain1[,card2.domain2[,...]]\fP
|
||||
Specifies a comma-separated list of cryptographic adapters in CCA or EP11
|
||||
coprocessor mode (APQN) which are associated with the key management system
|
||||
plugin. Each APQN association specifies a card and domain number separated
|
||||
by a period (like lszcrypt displays it).
|
||||
To add an APQN to the associated APQNs, prefix the APQN with a \fI+\fP.
|
||||
To remove an APQN from the associated APQNs, prefix the APQN with a \fI-\fP.
|
||||
To set (replace) the APQN association do not specify a prefix.
|
||||
You cannot mix \fI+\fP and \fI-\fP in one specification. You can either add or
|
||||
remove (or set) the associations with one command.
|
||||
All APQNs being added or set (replaced) must be online.
|
||||
.TP
|
||||
.B KMS-plugin specific options
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the kms configure command. Use \fBkms configure \-\-help\fP to
|
||||
display the plugin specific options and their meaning.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms reencipher command"
|
||||
.TP
|
||||
.BR \-n ", " \-\-to\-new
|
||||
Re-enciphers key management system plugin internal secure keys that are
|
||||
currently enciphered with the master key in the CURRENT register with the
|
||||
master key in the NEW register.
|
||||
.TP
|
||||
.BR \-o ", " \-\-from\-old
|
||||
Re-enciphers key management system plugin internal secure keys that are
|
||||
currently enciphered with the master key in the OLD register with the master
|
||||
key in the CURRENT register.
|
||||
This option is only available for CCA-type secure keys.
|
||||
.TP
|
||||
.BR \-i ", " \-\-in-place
|
||||
Forces an in-place re-enciphering of key management system plugin internal
|
||||
secure keys. "In-place" immediately replaces the secure key with the
|
||||
re-enciphered secure key. Re-enciphering from OLD to CURRENT is performed
|
||||
in-place per default.
|
||||
.TP
|
||||
.BR \-s ", " \-\-staged
|
||||
Forces that the re-enciphering of key management system plugin internal secure
|
||||
keys is performed in staged mode. Staged mode means that the re-enciphered
|
||||
secure keys are stored separately. Thus the current secure keys are still valid
|
||||
at this point. Once the new CCA or EP11 master keys have been set (made active),
|
||||
you must rerun the \fBkms reencipher\fP command with option \fB\-\-complete\fP
|
||||
to complete the staged re-enciphering.
|
||||
Re-enciphering from CURRENT to NEW is performed in staged mode per default.
|
||||
.TP
|
||||
.BR \-p ", " \-\-complete
|
||||
Completes a staged re-enciphering. Use this option after the new CCA or EP11
|
||||
master keys have been set (made active). This option replaces the secure keys by
|
||||
their re-enciphered versions.
|
||||
.TP
|
||||
.B KMS-plugin specific options
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the kms reencipher command. Use \fBkms reencipher \-\-help\fP to
|
||||
display the plugin specific options and their meaning.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
.SS "General options"
|
||||
.TP
|
||||
.BR \-V ", " \-\-verbose
|
||||
|
||||
166
zkey/zkey.c
166
zkey/zkey.c
@@ -124,6 +124,8 @@ static struct zkey_globals {
|
||||
#define COMMAND_KMS_BIND "bind"
|
||||
#define COMMAND_KMS_UNBIND "unbind"
|
||||
#define COMMAND_KMS_INFO "info"
|
||||
#define COMMAND_KMS_CONFIGURE "configure"
|
||||
#define COMMAND_KMS_REENCIPHER "reencipher"
|
||||
|
||||
#define OPT_COMMAND_PLACEHOLDER "PLACEHOLDER"
|
||||
|
||||
@@ -836,6 +838,67 @@ static struct util_opt opt_vec[] = {
|
||||
.command = COMMAND_CONVERT,
|
||||
},
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
.desc = "OPTIONS",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_CONFIGURE,
|
||||
},
|
||||
{
|
||||
.option = { "apqns", required_argument, NULL, 'a'},
|
||||
.argument = "[+|-]CARD.DOMAIN[,...]",
|
||||
.desc = "Comma-separated pairs of crypto cards and domains "
|
||||
"that are associated with the key management system "
|
||||
"(KMS) plugin that the repository is bound to, and all "
|
||||
"keys generated with the KMS. To add pairs of crypto "
|
||||
"cards and domains to the key, specify "
|
||||
"'+CARD.DOMAIN[,...]'. To remove pairs of crypto cards "
|
||||
"and domains from the key specify '-CARD.DOMAIN[,...]'",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_CONFIGURE,
|
||||
},
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
.desc = "OPTIONS",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"to-new", 0, NULL, 'n'},
|
||||
.desc = "Re-enciphers KMS plugin internal secure keys that are "
|
||||
"currently enciphered with the master key in the "
|
||||
"CURRENT register with the master key in the NEW "
|
||||
"register.",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"from-old", 0, NULL, 'o'},
|
||||
.desc = "Re-enciphers KMS plugin internal secure keys that are "
|
||||
"currently enciphered with the master key in the OLD "
|
||||
"register with the master key in the CURRENT register.",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"complete", 0, NULL, 'p'},
|
||||
.desc = "Completes a staged re-enciphering. Use this option "
|
||||
"after the new master key has been set (made "
|
||||
"active).",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"in-place", 0, NULL, 'i'},
|
||||
.desc = "Forces an in-place re-enchipering of the KMS plugin "
|
||||
"internal secure keys. Re-enciphering from OLD to "
|
||||
"CURRENT is performed in-place per default.",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"staged", 0, NULL, 's'},
|
||||
.desc = "Forces that the re-enciphering of the KMS plugin "
|
||||
"internal secure keys is performed in staged mode. "
|
||||
"Re-enciphering from CURRENT to NEW is performed in "
|
||||
"staged mode per default.",
|
||||
.command = COMMAND_KMS " " COMMAND_KMS_REENCIPHER,
|
||||
},
|
||||
/***********************************************************/
|
||||
OPT_PLACEHOLDER,
|
||||
OPT_PLACEHOLDER,
|
||||
OPT_PLACEHOLDER,
|
||||
@@ -933,6 +996,8 @@ 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 int command_kms_configure(void);
|
||||
static int command_kms_reencipher(void);
|
||||
|
||||
static struct zkey_command zkey_kms_commands[] = {
|
||||
{
|
||||
@@ -981,6 +1046,31 @@ static struct zkey_command zkey_kms_commands[] = {
|
||||
.has_options = 1,
|
||||
.use_kms_plugin = 1,
|
||||
},
|
||||
{
|
||||
.command = COMMAND_KMS_CONFIGURE,
|
||||
.abbrev_len = 3,
|
||||
.function = command_kms_configure,
|
||||
.short_desc = "Configures a key management system plugin",
|
||||
.long_desc = "Configures or re-configures the current key "
|
||||
"management system (KMS) plugin",
|
||||
.need_keystore = 1,
|
||||
.has_options = 1,
|
||||
.use_kms_plugin = 1,
|
||||
.kms_plugin_opts_cmd = KMS_COMMAND_CONFIGURE,
|
||||
},
|
||||
{
|
||||
.command = COMMAND_KMS_REENCIPHER,
|
||||
.abbrev_len = 2,
|
||||
.function = command_kms_reencipher,
|
||||
.short_desc = "Re-enciphers secure keys used by a key "
|
||||
"management system plugin",
|
||||
.long_desc = "Re-enciphers secure keys internally used by a "
|
||||
"key management system (KMS) plugin",
|
||||
.need_keystore = 1,
|
||||
.has_options = 1,
|
||||
.use_kms_plugin = 1,
|
||||
.kms_plugin_opts_cmd = KMS_COMMAND_REENCIPHER,
|
||||
},
|
||||
{ .command = NULL }
|
||||
};
|
||||
|
||||
@@ -2217,6 +2307,82 @@ static int command_kms_info(void)
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Command handler for 'kms configure'.
|
||||
*
|
||||
* Configures or re-configures a KMS plugin
|
||||
*/
|
||||
static int command_kms_configure(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 = configure_kms_plugin(g.keystore, g.apqns, g.kms_options,
|
||||
g.num_kms_options, g.first_kms_option >= 0,
|
||||
g.verbose);
|
||||
if (rc == -EAGAIN) {
|
||||
util_print_indented("The KMS plugin has accepted the "
|
||||
"configuration so far, but requires further"
|
||||
" configuration. Run 'zkey kms info' to "
|
||||
"find out which KMS plugin settings still "
|
||||
"require configuration, and run 'zkey kms "
|
||||
"configure' again with the appropriate "
|
||||
"options to complete the KMS "
|
||||
"configuration process", 0);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Command handler for 'kms reencipher'.
|
||||
*
|
||||
* Reenciphers secure keys internally used by a KMS plugin
|
||||
*/
|
||||
static int command_kms_reencipher(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;
|
||||
}
|
||||
|
||||
if (g.inplace && g.staged) {
|
||||
warnx("Either '--in-place|-i' or '--staged|-s' can be "
|
||||
"specified, but not both");
|
||||
util_prg_print_parse_error();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (g.complete) {
|
||||
if (g.inplace) {
|
||||
warnx("Option '--in-place|-i' is not valid together "
|
||||
"with '--complete|-p'");
|
||||
util_prg_print_parse_error();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (g.staged) {
|
||||
warnx("Option '--staged|-s' is not valid together "
|
||||
"with '--complete|-p'");
|
||||
util_prg_print_parse_error();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
rc = reencipher_kms(&g.kms_info, g.fromold, g.tonew, g.inplace,
|
||||
g.staged, g.complete, g.kms_options,
|
||||
g.num_kms_options, g.verbose);
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user