diff options
Diffstat (limited to 'crypto/encode_decode/decoder_pkey.c')
-rw-r--r-- | crypto/encode_decode/decoder_pkey.c | 72 |
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; } |