zkey-ekmfweb: Avoid sequence number clash when generating keys

When keys are generated concurrently in EKMF Web from multiple clients,
and the key labels use a sequence number tag, then the assignment logic
of the sequence number may cause a duplicate sequence number to be used,
because another key might have already been generated with the same
sequence number, since the next-to-use sequence number has been retrieved
from EKMF Web. This results in a HTTP response code of 409 and a -EEXIST
return code from ekmf_generate_key().

Instead of getting the last used sequence number from EKMFWeb, tell
EKMFWeb to automatically use the next available sequence number when
generating a key. When the sequence number label tag value is 'next'
then EKMFWeb will automatically assign the next available sequence number
to the label tag and increment the sequence number in an atomic way.

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-01-25 11:16:04 +01:00
committed by Jan Höppner
parent 1e18429f69
commit c4546daf34
2 changed files with 6 additions and 54 deletions
+5 -54
View File
@@ -3347,45 +3347,6 @@ static void _free_ekmf_tags(struct ekmf_tag_list *ekmf_tag_list)
ekmf_tag_list->num_tags = 0;
}
/**
* Gets the next sequence number of the template
*
* @param ph the plugin handle
* @param template_uuid the template UUID
*
* @returns an allocated string, or NULL in case of an error.
*/
static char *_get_seqno(struct plugin_handle *ph, const char *template_uuid)
{
unsigned int seqno = 0;
char *error_msg = NULL;
char *ret = NULL;
int rc;
rc = ekmf_get_last_seq_no(&ph->ekmf_config, &ph->curl_handle,
template_uuid, &seqno, &error_msg,
ph->verbose);
if (rc != 0) {
_set_error(ph, "Failed to get last used sequence number for "
"template '%s': %s",
template_uuid, error_msg != NULL ? error_msg :
strerror(-rc));
_remove_login_token_if_error(ph, rc);
goto out;
}
seqno++;
util_asprintf(&ret, "%05u", seqno);
pr_verbose(ph, "Seqno: '%s'", ret);
out:
if (error_msg != NULL)
free(error_msg);
return ret;
}
/**
* Parses the label tags passed in via option (<tag>=<value>;<tag>=<value;....)
* and allocates an array of KMS properties. The tags must be freed by the
@@ -3450,25 +3411,16 @@ static int _parse_label_tags(struct plugin_handle *ph,
if (value != NULL) {
ekmf_tag_list->tags[i].value =
util_strdup(value);
util_str_toupper((char *)
ekmf_tag_list->tags[i].value);
} else {
ekmf_tag_list->tags[i].value =
_get_seqno(ph,
template_info->uuid);
if (ekmf_tag_list->tags[i].value ==
NULL) {
rc = -EIO;
goto out;
}
util_strdup(EKMFWEB_SEQNO_NEXT);
}
k++;
} else {
ekmf_tag_list->tags[i].value =
_get_seqno(ph,
template_info->uuid);
if (ekmf_tag_list->tags[i].value == NULL) {
rc = -EIO;
goto out;
}
util_strdup(EKMFWEB_SEQNO_NEXT);
}
} else {
if (tag == NULL) {
@@ -3504,11 +3456,10 @@ static int _parse_label_tags(struct plugin_handle *ph,
}
ekmf_tag_list->tags[i].value = util_strdup(value);
util_str_toupper((char *)ekmf_tag_list->tags[i].value);
k++;
}
util_str_toupper((char *)ekmf_tag_list->tags[i].value);
pr_verbose(ph, "Tag: '%s', Value: '%s'",
ekmf_tag_list->tags[i].name,
ekmf_tag_list->tags[i].value);
+1
View File
@@ -99,6 +99,7 @@ struct plugin_handle {
#define EKMFWEB_CURVE_PRIME "PRIME_CURVE"
#define EKMFWEB_CURVE_BAINPOOL "BRAINPOOL_CURVE"
#define EKMFWEB_SEQNO_TAG "seqno"
#define EKMFWEB_SEQNO_NEXT "next"
#define DEFAULT_IDENTITY_KEY_PUBLIC_EXPONENT 65537