aboutsummaryrefslogtreecommitdiff
path: root/crypto/encode_decode/decoder_pkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/encode_decode/decoder_pkey.c')
-rw-r--r--crypto/encode_decode/decoder_pkey.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c
index f99566bde744..9fc4e2312331 100644
--- a/crypto/encode_decode/decoder_pkey.c
+++ b/crypto/encode_decode/decoder_pkey.c
@@ -222,15 +222,21 @@ struct collect_data_st {
int total; /* number of matching results */
char error_occurred;
char keytype_resolved;
+ OSSL_PROPERTY_LIST *pq;
STACK_OF(EVP_KEYMGMT) *keymgmts;
};
-static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
- void *provctx, struct collect_data_st *data)
+/*
+ * Add decoder instance to the decoder context if it is compatible. Returns 1
+ * if a decoder was added, 0 otherwise.
+ */
+static int collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
+ void *provctx, struct collect_data_st *data)
{
void *decoderctx = NULL;
OSSL_DECODER_INSTANCE *di = NULL;
+ const OSSL_PROPERTY_LIST *props;
/*
* We already checked the EVP_KEYMGMT is applicable in check_keymgmt so we
@@ -239,17 +245,17 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
if (keymgmt->name_id != decoder->base.id)
/* Mismatch is not an error, continue. */
- return;
+ return 0;
if ((decoderctx = decoder->newctx(provctx)) == NULL) {
data->error_occurred = 1;
- return;
+ return 0;
}
if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) {
decoder->freectx(decoderctx);
data->error_occurred = 1;
- return;
+ return 0;
}
/*
@@ -263,7 +269,7 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
|| OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) {
/* Mismatch is not an error, continue. */
ossl_decoder_instance_free(di);
- return;
+ return 0;
}
OSSL_TRACE_BEGIN(DECODER) {
@@ -275,13 +281,30 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
OSSL_DECODER_get0_properties(decoder));
} OSSL_TRACE_END(DECODER);
+ /*
+ * Get the property match score so the decoders can be prioritized later.
+ */
+ props = ossl_decoder_parsed_properties(decoder);
+ if (data->pq != NULL && props != NULL) {
+ di->score = ossl_property_match_count(data->pq, props);
+ /*
+ * Mismatch of mandatory properties is not an error, the decoder is just
+ * ignored, continue.
+ */
+ if (di->score < 0) {
+ ossl_decoder_instance_free(di);
+ return 0;
+ }
+ }
+
if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) {
ossl_decoder_instance_free(di);
data->error_occurred = 1;
- return;
+ return 0;
}
++data->total;
+ return 1;
}
static void collect_decoder(OSSL_DECODER *decoder, void *arg)
@@ -321,7 +344,9 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
for (i = 0; i < end_i; ++i) {
keymgmt = sk_EVP_KEYMGMT_value(keymgmts, i);
- collect_decoder_keymgmt(keymgmt, decoder, provctx, data);
+ /* Only add this decoder once */
+ if (collect_decoder_keymgmt(keymgmt, decoder, provctx, data))
+ break;
if (data->error_occurred)
return;
}
@@ -407,6 +432,8 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
struct decoder_pkey_data_st *process_data = NULL;
struct collect_data_st collect_data = { NULL };
STACK_OF(EVP_KEYMGMT) *keymgmts = NULL;
+ OSSL_PROPERTY_LIST **plp;
+ OSSL_PROPERTY_LIST *pq = NULL, *p2 = NULL;
OSSL_TRACE_BEGIN(DECODER) {
const char *input_type = ctx->start_input_type;
@@ -443,6 +470,25 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
process_data->keymgmts = keymgmts;
/*
+ * Collect passed and default properties to prioritize the decoders.
+ */
+ if (propquery != NULL)
+ p2 = pq = ossl_parse_query(libctx, propquery, 1);
+
+ plp = ossl_ctx_global_properties(libctx, 0);
+ if (plp != NULL && *plp != NULL) {
+ if (pq == NULL) {
+ pq = *plp;
+ } else {
+ p2 = ossl_property_merge(pq, *plp);
+ ossl_property_free(pq);
+ if (p2 == NULL)
+ goto err;
+ pq = p2;
+ }
+ }
+
+ /*
* Enumerate all keymgmts into a stack.
*
* We could nest EVP_KEYMGMT_do_all_provided inside
@@ -457,10 +503,11 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
* upfront, as this ensures that the names for all loaded providers have
* been registered by the time we try to resolve the keytype string.
*/
- collect_data.ctx = ctx;
- collect_data.libctx = libctx;
- collect_data.keymgmts = keymgmts;
- collect_data.keytype = keytype;
+ collect_data.ctx = ctx;
+ collect_data.libctx = libctx;
+ collect_data.keymgmts = keymgmts;
+ collect_data.keytype = keytype;
+ collect_data.pq = pq;
EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, &collect_data);
if (collect_data.error_occurred)
@@ -496,6 +543,7 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
ok = 1;
err:
decoder_clean_pkey_construct_arg(process_data);
+ ossl_property_free(p2);
return ok;
}