mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zkey-ekmfweb: Re-encipher the identity key
The identity key of the plugin is a secure key. When the APKA master key of the associated APQNs is changed, the identity key must be re-enciphered under the new master key. 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
cc0d030ce9
commit
57b70a0fe0
@@ -975,6 +975,12 @@ int kms_display_info(const kms_handle_t handle)
|
||||
printf(" Identity key: (configuration required)\n");
|
||||
}
|
||||
|
||||
tmp = properties_get(ph->properties, EKMFWEB_CONFIG_IDENTITY_KEY_REENC);
|
||||
if (tmp != NULL) {
|
||||
printf(" (re-enciphering pending)\n");
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define OPT_TLS_CLIENT_CERT 256
|
||||
@@ -2543,6 +2549,7 @@ static int _generate_identity_key(struct plugin_handle *ph)
|
||||
struct ekmf_template_info *template_info = NULL;
|
||||
struct ekmf_key_gen_info gen_info;
|
||||
char *template_uuid = NULL;
|
||||
char *reenc_file = NULL;
|
||||
char *error_msg = NULL;
|
||||
char key_params[200];
|
||||
int rc = 0;
|
||||
@@ -2678,6 +2685,15 @@ static int _generate_identity_key(struct plugin_handle *ph)
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
reenc_file = properties_get(ph->properties,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC);
|
||||
if (reenc_file != NULL) {
|
||||
remove(reenc_file);
|
||||
free(reenc_file);
|
||||
properties_remove(ph->properties,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC);
|
||||
}
|
||||
|
||||
pr_verbose(ph, "Generated identity key into '%s'",
|
||||
ph->ekmf_config.identity_secure_key);
|
||||
|
||||
@@ -3120,7 +3136,10 @@ int kms_reenciper(const kms_handle_t handle, enum kms_reencipher_mode mode,
|
||||
const struct kms_option *options, size_t num_options)
|
||||
{
|
||||
struct plugin_handle *ph = handle;
|
||||
char *reenc_file = NULL;
|
||||
const char *tmp = NULL;
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
util_assert(handle != NULL, "Internal error: handle is NULL");
|
||||
util_assert(num_options == 0 || options != NULL,
|
||||
@@ -3140,7 +3159,217 @@ int kms_reenciper(const kms_handle_t handle, enum kms_reencipher_mode mode,
|
||||
|
||||
_clear_error(ph);
|
||||
|
||||
return 0;
|
||||
if (ph->ekmf_config.identity_secure_key == NULL)
|
||||
return 0;
|
||||
|
||||
reenc_file = properties_get(ph->properties,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC);
|
||||
if (reenc_file != NULL && mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_STAGED_COMPLETE;
|
||||
|
||||
if (mode == KMS_REENC_MODE_STAGED_COMPLETE) {
|
||||
if (reenc_file == NULL) {
|
||||
_set_error(ph, "Staged re-enciphering is not pending");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Completing re-enciphering of identity key.\n");
|
||||
|
||||
rc = remove(ph->ekmf_config.identity_secure_key);
|
||||
if (rc != 0) {
|
||||
rc = -errno;
|
||||
_set_error(ph, "Failed to remove file '%s': %s",
|
||||
ph->ekmf_config.identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = rename(reenc_file, ph->ekmf_config.identity_secure_key);
|
||||
if (rc != 0) {
|
||||
rc = -errno;
|
||||
_set_error(ph, "Failed to rename file '%s' to '%s': %s",
|
||||
reenc_file,
|
||||
ph->ekmf_config.identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = properties_remove(ph->properties,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC);
|
||||
if (rc != 0) {
|
||||
_set_error(ph, "Failed to remove property %s: %s",
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _save_config(ph);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
printf("Successfully completed re-enciphering of identity "
|
||||
"key.\n");
|
||||
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (reenc_file != NULL)
|
||||
free(reenc_file);
|
||||
reenc_file = NULL;
|
||||
|
||||
rc = _select_cca_adapter(ph);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
switch (mkreg) {
|
||||
case KMS_REENC_MKREG_AUTO:
|
||||
case KMS_REENC_MKREG_TO_NEW:
|
||||
if (mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_STAGED;
|
||||
|
||||
if (mode == KMS_REENC_MODE_STAGED)
|
||||
util_asprintf(&reenc_file, "%s/%s", ph->config_path,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC_FILE);
|
||||
|
||||
printf("Re-enciphering the identity key with the APKA master "
|
||||
"key in the NEW register.\n");
|
||||
|
||||
rc = ekmf_reencipher_identity_key(&ph->ekmf_config, true,
|
||||
reenc_file, &ph->ext_lib,
|
||||
ph->verbose);
|
||||
if (rc != 0) {
|
||||
_set_error(ph, "Failed to re-encipher identity key "
|
||||
"'%s': %s",
|
||||
ph->ekmf_config.identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case KMS_REENC_MKREG_FROM_OLD:
|
||||
if (mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_IN_PLACE;
|
||||
|
||||
if (mode == KMS_REENC_MODE_STAGED)
|
||||
util_asprintf(&reenc_file, "%s/%s", ph->config_path,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC_FILE);
|
||||
|
||||
printf("Re-enciphering the identity key with the APKA master "
|
||||
"key in the CURRENT register.\n");
|
||||
|
||||
rc = ekmf_reencipher_identity_key(&ph->ekmf_config, false,
|
||||
reenc_file, &ph->ext_lib,
|
||||
ph->verbose);
|
||||
if (rc != 0) {
|
||||
_set_error(ph, "Failed to re-encipher identity key "
|
||||
"'%s': %s",
|
||||
ph->ekmf_config.identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case KMS_REENC_MKREG_FROM_OLD_TO_NEW:
|
||||
if (mode == KMS_REENC_MODE_AUTO)
|
||||
mode = KMS_REENC_MODE_STAGED;
|
||||
|
||||
if (mode == KMS_REENC_MODE_STAGED)
|
||||
util_asprintf(&reenc_file, "%s/%s", ph->config_path,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC_FILE);
|
||||
|
||||
printf("Re-enciphering the identity key with the APKA master "
|
||||
"key in the CURRENT and then the NEW register.\n");
|
||||
|
||||
rc = ekmf_reencipher_identity_key(&ph->ekmf_config, false,
|
||||
reenc_file, &ph->ext_lib,
|
||||
ph->verbose);
|
||||
if (rc != 0) {
|
||||
_set_error(ph, "Failed to re-encipher identity key "
|
||||
"'%s': %s",
|
||||
ph->ekmf_config.identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (reenc_file != NULL) {
|
||||
tmp = ph->ekmf_config.identity_secure_key;
|
||||
ph->ekmf_config.identity_secure_key = reenc_file;
|
||||
}
|
||||
|
||||
rc = ekmf_reencipher_identity_key(&ph->ekmf_config, true,
|
||||
reenc_file, &ph->ext_lib,
|
||||
ph->verbose);
|
||||
|
||||
if (tmp != NULL)
|
||||
ph->ekmf_config.identity_secure_key = tmp;
|
||||
|
||||
if (rc != 0) {
|
||||
_set_error(ph, "Failed to re-encipher identity key "
|
||||
"'%s': %s",
|
||||
ph->ekmf_config.identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
_set_error(ph, "Invalid re-encipher MK register selection");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mode == KMS_REENC_MODE_STAGED) {
|
||||
rc = _set_file_permission(ph, reenc_file);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = properties_set(ph->properties,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC,
|
||||
reenc_file);
|
||||
if (rc != 0) {
|
||||
_set_error(ph, "Failed to set property %s: %s",
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
rc = properties_remove(ph->properties,
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC);
|
||||
if (rc != 0 && rc != -ENOENT) {
|
||||
_set_error(ph, "Failed to remove property %s: %s",
|
||||
EKMFWEB_CONFIG_IDENTITY_KEY_REENC,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = _save_config(ph);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = 0;
|
||||
|
||||
if (mode == KMS_REENC_MODE_STAGED)
|
||||
util_print_indented("Staged re-enciphering is initiated for "
|
||||
"the identity key. After the NEW master "
|
||||
"key has been set to become the CURRENT "
|
||||
"master key run 'zkey kms reencipher' with "
|
||||
"option '--complete' to complete the "
|
||||
"re-enciphering process.", 0);
|
||||
else
|
||||
printf("Successfully re-enciphered the identity key\n");
|
||||
|
||||
out:
|
||||
if (rc != 0 && reenc_file != NULL)
|
||||
remove(reenc_file);
|
||||
if (reenc_file != NULL)
|
||||
free(reenc_file);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,6 +41,7 @@ struct plugin_handle {
|
||||
#define EKMFWEB_CONFIG_LOGIN_TOKEN_FILE "login.token"
|
||||
#define EKMFWEB_CONFIG_EKMFWEB_PUBKEY_FILE "ekmfweb-pubkey.pem"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_FILE "identity-key.skey"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_REENC_FILE "identity-key.reenc"
|
||||
|
||||
#define EKMFWEB_CONFIG_APQNS "apqns"
|
||||
#define EKMFWEB_CONFIG_URL "url"
|
||||
@@ -70,6 +71,7 @@ struct plugin_handle {
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY "identity-key"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_ALGORITHM "identity-key-algorithm"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_PARAMS "identity-key-params"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_REENC "identity-key-reenc"
|
||||
|
||||
#define EKMFWEB_PASSCODE_URL "/administration/passcode"
|
||||
#define EKMFWEB_TEMPLATE_STATE_ACTIVE "ACTIVE"
|
||||
|
||||
Reference in New Issue
Block a user