提交 fb890008 编写于 作者: R Richard Levitte

DESERIALIZER: Adjust to allow the use several deserializers with same name

A key type may be deserialized from one of several sources, which
means that more than one deserializer with the same name should be
possible to add to the stack of deserializers to try, in the
OSSL_DESERIALIZER_CTX collection.
Reviewed-by: NShane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12574)
上级 413835f5
...@@ -241,6 +241,7 @@ DEFINE_STACK_OF_CSTRING() ...@@ -241,6 +241,7 @@ DEFINE_STACK_OF_CSTRING()
struct collected_data_st { struct collected_data_st {
struct deser_EVP_PKEY_data_st *process_data; struct deser_EVP_PKEY_data_st *process_data;
STACK_OF(OPENSSL_CSTRING) *names; STACK_OF(OPENSSL_CSTRING) *names;
OSSL_DESERIALIZER_CTX *ctx;
unsigned int error_occured:1; unsigned int error_occured:1;
}; };
...@@ -279,6 +280,28 @@ static void collect_name(const char *name, void *arg) ...@@ -279,6 +280,28 @@ static void collect_name(const char *name, void *arg)
data->error_occured = 0; /* All is good now */ data->error_occured = 0; /* All is good now */
} }
static void collect_deserializer(OSSL_DESERIALIZER *deser, void *arg)
{
struct collected_data_st *data = arg;
size_t i, end_i;
if (data->error_occured)
return;
data->error_occured = 1; /* Assume the worst */
end_i = sk_OPENSSL_CSTRING_num(data->names);
for (i = 0; i < end_i; i++) {
const char *name = sk_OPENSSL_CSTRING_value(data->names, i);
if (!OSSL_DESERIALIZER_is_a(deser, name))
continue;
(void)OSSL_DESERIALIZER_CTX_add_deserializer(data->ctx, deser);
}
data->error_occured = 0; /* All is good now */
}
OSSL_DESERIALIZER_CTX * OSSL_DESERIALIZER_CTX *
OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
const char *input_type, const char *input_type,
...@@ -300,6 +323,7 @@ OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, ...@@ -300,6 +323,7 @@ OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
goto err; goto err;
} }
data->process_data->object = (void **)pkey; data->process_data->object = (void **)pkey;
data->ctx = ctx;
OSSL_DESERIALIZER_CTX_set_input_type(ctx, input_type); OSSL_DESERIALIZER_CTX_set_input_type(ctx, input_type);
/* First, find all keymgmts to form goals */ /* First, find all keymgmts to form goals */
...@@ -308,49 +332,30 @@ OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, ...@@ -308,49 +332,30 @@ OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
if (data->error_occured) if (data->error_occured)
goto err; goto err;
/* /* Then, we collect all the keymgmt names */
* Then, use the names of those keymgmts to find the first set of
* derializers.
*/
ERR_set_mark();
end_i = sk_EVP_KEYMGMT_num(data->process_data->keymgmts); end_i = sk_EVP_KEYMGMT_num(data->process_data->keymgmts);
for (i = 0; i < end_i; i++) { for (i = 0; i < end_i; i++) {
EVP_KEYMGMT *keymgmt = EVP_KEYMGMT *keymgmt =
sk_EVP_KEYMGMT_value(data->process_data->keymgmts, i); sk_EVP_KEYMGMT_value(data->process_data->keymgmts, i);
size_t j;
OSSL_DESERIALIZER *deser = NULL;
EVP_KEYMGMT_names_do_all(keymgmt, collect_name, data); EVP_KEYMGMT_names_do_all(keymgmt, collect_name, data);
for (j = sk_OPENSSL_CSTRING_num(data->names); if (data->error_occured)
j-- > 0 && deser == NULL;) { goto err;
const char *name = sk_OPENSSL_CSTRING_pop(data->names);
ERR_set_mark();
deser = OSSL_DESERIALIZER_fetch(libctx, name, propquery);
ERR_pop_to_mark();
} }
/* /*
* The names in |data->names| aren't allocated for the stack, * Finally, find all deserializers that have any keymgmt of the collected
* so we can simply clear it and let it be re-used. * keymgmt names
*/ */
sk_OPENSSL_CSTRING_zero(data->names); OSSL_DESERIALIZER_do_all_provided(libctx, collect_deserializer, data);
if (data->error_occured)
goto err;
/*
* If we found a matching serializer, try to add it to the context.
*/
if (deser != NULL) {
(void)OSSL_DESERIALIZER_CTX_add_deserializer(ctx, deser);
OSSL_DESERIALIZER_free(deser);
}
}
/* If we found no deserializers to match the keymgmts, we err */ /* If we found no deserializers to match the keymgmts, we err */
if (OSSL_DESERIALIZER_CTX_num_deserializers(ctx) == 0) { if (OSSL_DESERIALIZER_CTX_num_deserializers(ctx) == 0)
ERR_clear_last_mark();
goto err; goto err;
}
ERR_pop_to_mark();
/* Finally, collect extra deserializers based on what we already have */ /* Finally, collect extra deserializers based on what we already have */
(void)OSSL_DESERIALIZER_CTX_add_extra(ctx, libctx, propquery); (void)OSSL_DESERIALIZER_CTX_add_extra(ctx, libctx, propquery);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册