Home | History | Annotate | Line # | Download | only in encode_decode
      1 /*
      2  * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include <openssl/core_names.h>
     11 #include <openssl/core_object.h>
     12 #include <openssl/provider.h>
     13 #include <openssl/evp.h>
     14 #include <openssl/ui.h>
     15 #include <openssl/decoder.h>
     16 #include <openssl/safestack.h>
     17 #include <openssl/trace.h>
     18 #include "crypto/evp.h"
     19 #include "crypto/decoder.h"
     20 #include "crypto/evp/evp_local.h"
     21 #include "crypto/lhash.h"
     22 #include "encoder_local.h"
     23 #include "internal/namemap.h"
     24 #include "internal/sizes.h"
     25 
     26 int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
     27     const unsigned char *kstr,
     28     size_t klen)
     29 {
     30     return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen);
     31 }
     32 
     33 int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
     34     const UI_METHOD *ui_method,
     35     void *ui_data)
     36 {
     37     return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data);
     38 }
     39 
     40 int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
     41     pem_password_cb *cb, void *cbarg)
     42 {
     43     return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg);
     44 }
     45 
     46 int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx,
     47     OSSL_PASSPHRASE_CALLBACK *cb,
     48     void *cbarg)
     49 {
     50     return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg);
     51 }
     52 
     53 /*
     54  * Support for OSSL_DECODER_CTX_new_for_pkey:
     55  * The construct data, and collecting keymgmt information for it
     56  */
     57 
     58 DEFINE_STACK_OF(EVP_KEYMGMT)
     59 
     60 struct decoder_pkey_data_st {
     61     OSSL_LIB_CTX *libctx;
     62     char *propq;
     63     int selection;
     64 
     65     STACK_OF(EVP_KEYMGMT) *keymgmts;
     66     char *object_type; /* recorded object data type, may be NULL */
     67     void **object; /* Where the result should end up */
     68     OSSL_DECODER_CTX *ctx; /* The parent decoder context */
     69 };
     70 
     71 static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst,
     72     const OSSL_PARAM *params,
     73     void *construct_data)
     74 {
     75     struct decoder_pkey_data_st *data = construct_data;
     76     OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst);
     77     void *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst);
     78     const OSSL_PROVIDER *decoder_prov = OSSL_DECODER_get0_provider(decoder);
     79     EVP_KEYMGMT *keymgmt = NULL;
     80     const OSSL_PROVIDER *keymgmt_prov = NULL;
     81     int i, end;
     82     /*
     83      * |object_ref| points to a provider reference to an object, its exact
     84      * contents entirely opaque to us, but may be passed to any provider
     85      * function that expects this (such as OSSL_FUNC_keymgmt_load().
     86      *
     87      * This pointer is considered volatile, i.e. whatever it points at
     88      * is assumed to be freed as soon as this function returns.
     89      */
     90     void *object_ref = NULL;
     91     size_t object_ref_sz = 0;
     92     const OSSL_PARAM *p;
     93 
     94     p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE);
     95     if (p != NULL) {
     96         char *object_type = NULL;
     97 
     98         if (!OSSL_PARAM_get_utf8_string(p, &object_type, 0))
     99             return 0;
    100         OPENSSL_free(data->object_type);
    101         data->object_type = object_type;
    102     }
    103 
    104     /*
    105      * For stuff that should end up in an EVP_PKEY, we only accept an object
    106      * reference for the moment.  This enforces that the key data itself
    107      * remains with the provider.
    108      */
    109     p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE);
    110     if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
    111         return 0;
    112     object_ref = p->data;
    113     object_ref_sz = p->data_size;
    114 
    115     /*
    116      * First, we try to find a keymgmt that comes from the same provider as
    117      * the decoder that passed the params.
    118      */
    119     end = sk_EVP_KEYMGMT_num(data->keymgmts);
    120     for (i = 0; i < end; i++) {
    121         keymgmt = sk_EVP_KEYMGMT_value(data->keymgmts, i);
    122         keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt);
    123 
    124         if (keymgmt_prov == decoder_prov
    125             && evp_keymgmt_has_load(keymgmt)
    126             && EVP_KEYMGMT_is_a(keymgmt, data->object_type))
    127             break;
    128     }
    129     if (i < end) {
    130         /* To allow it to be freed further down */
    131         if (!EVP_KEYMGMT_up_ref(keymgmt))
    132             return 0;
    133     } else if ((keymgmt = EVP_KEYMGMT_fetch(data->libctx,
    134                     data->object_type,
    135                     data->propq))
    136         != NULL) {
    137         keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt);
    138     }
    139 
    140     if (keymgmt != NULL) {
    141         EVP_PKEY *pkey = NULL;
    142         void *keydata = NULL;
    143 
    144         /*
    145          * If the EVP_KEYMGMT and the OSSL_DECODER are from the
    146          * same provider, we assume that the KEYMGMT has a key loading
    147          * function that can handle the provider reference we hold.
    148          *
    149          * Otherwise, we export from the decoder and import the
    150          * result in the keymgmt.
    151          */
    152         if (keymgmt_prov == decoder_prov) {
    153             keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz);
    154         } else {
    155             struct evp_keymgmt_util_try_import_data_st import_data;
    156 
    157             import_data.keymgmt = keymgmt;
    158             import_data.keydata = NULL;
    159             if (data->selection == 0)
    160                 /* import/export functions do not tolerate 0 selection */
    161                 import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
    162             else
    163                 import_data.selection = data->selection;
    164 
    165             /*
    166              * No need to check for errors here, the value of
    167              * |import_data.keydata| is as much an indicator.
    168              */
    169             (void)decoder->export_object(decoderctx,
    170                 object_ref, object_ref_sz,
    171                 &evp_keymgmt_util_try_import,
    172                 &import_data);
    173             keydata = import_data.keydata;
    174             import_data.keydata = NULL;
    175         }
    176         /*
    177          * When load or import fails, because this is not an acceptable key
    178          * (despite the provided key material being syntactically valid), the
    179          * reason why the key is rejected would be lost, unless we signal a
    180          * hard error, and suppress resetting for another try.
    181          */
    182         if (keydata == NULL)
    183             ossl_decoder_ctx_set_harderr(data->ctx);
    184 
    185         if (keydata != NULL
    186             && (pkey = evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL)
    187             evp_keymgmt_freedata(keymgmt, keydata);
    188 
    189         *data->object = pkey;
    190 
    191         /*
    192          * evp_keymgmt_util_make_pkey() increments the reference count when
    193          * assigning the EVP_PKEY, so we can free the keymgmt here.
    194          */
    195         EVP_KEYMGMT_free(keymgmt);
    196     }
    197     /*
    198      * We successfully looked through, |*ctx->object| determines if we
    199      * actually found something.
    200      */
    201     return (*data->object != NULL);
    202 }
    203 
    204 static void decoder_clean_pkey_construct_arg(void *construct_data)
    205 {
    206     struct decoder_pkey_data_st *data = construct_data;
    207 
    208     if (data != NULL) {
    209         sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free);
    210         OPENSSL_free(data->propq);
    211         OPENSSL_free(data->object_type);
    212         OPENSSL_free(data);
    213     }
    214 }
    215 
    216 struct collect_data_st {
    217     OSSL_LIB_CTX *libctx;
    218     OSSL_DECODER_CTX *ctx;
    219 
    220     const char *keytype; /* the keytype requested, if any */
    221     int keytype_id; /* if keytype_resolved is set, keymgmt name_id; else 0 */
    222     int sm2_id; /* if keytype_resolved is set and EC, SM2 name_id; else 0 */
    223     int total; /* number of matching results */
    224     char error_occurred;
    225     char keytype_resolved;
    226     OSSL_PROPERTY_LIST *pq;
    227 
    228     STACK_OF(EVP_KEYMGMT) *keymgmts;
    229 };
    230 
    231 /*
    232  * Add decoder instance to the decoder context if it is compatible. Returns 1
    233  * if a decoder was added, 0 otherwise.
    234  */
    235 static int collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
    236     void *provctx, struct collect_data_st *data)
    237 {
    238     void *decoderctx = NULL;
    239     OSSL_DECODER_INSTANCE *di = NULL;
    240     const OSSL_PROPERTY_LIST *props;
    241 
    242     /*
    243      * We already checked the EVP_KEYMGMT is applicable in check_keymgmt so we
    244      * don't check it again here.
    245      */
    246 
    247     if (keymgmt->name_id != decoder->base.id)
    248         /* Mismatch is not an error, continue. */
    249         return 0;
    250 
    251     if ((decoderctx = decoder->newctx(provctx)) == NULL) {
    252         data->error_occurred = 1;
    253         return 0;
    254     }
    255 
    256     if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) {
    257         decoder->freectx(decoderctx);
    258         data->error_occurred = 1;
    259         return 0;
    260     }
    261 
    262     /*
    263      * Input types must be compatible, but we must accept DER encoders when the
    264      * start input type is "PEM".
    265      */
    266     if (data->ctx->start_input_type != NULL
    267         && di->input_type != NULL
    268         && OPENSSL_strcasecmp(di->input_type, data->ctx->start_input_type) != 0
    269         && (OPENSSL_strcasecmp(di->input_type, "DER") != 0
    270             || OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) {
    271         /* Mismatch is not an error, continue. */
    272         ossl_decoder_instance_free(di);
    273         return 0;
    274     }
    275 
    276     OSSL_TRACE_BEGIN(DECODER)
    277     {
    278         BIO_printf(trc_out,
    279             "(ctx %p) Checking out decoder %p:\n"
    280             "    %s with %s\n",
    281             (void *)data->ctx, (void *)decoder,
    282             OSSL_DECODER_get0_name(decoder),
    283             OSSL_DECODER_get0_properties(decoder));
    284     }
    285     OSSL_TRACE_END(DECODER);
    286 
    287     /*
    288      * Get the property match score so the decoders can be prioritized later.
    289      */
    290     props = ossl_decoder_parsed_properties(decoder);
    291     if (data->pq != NULL && props != NULL) {
    292         di->score = ossl_property_match_count(data->pq, props);
    293         /*
    294          * Mismatch of mandatory properties is not an error, the decoder is just
    295          * ignored, continue.
    296          */
    297         if (di->score < 0) {
    298             ossl_decoder_instance_free(di);
    299             return 0;
    300         }
    301     }
    302 
    303     if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) {
    304         ossl_decoder_instance_free(di);
    305         data->error_occurred = 1;
    306         return 0;
    307     }
    308 
    309     ++data->total;
    310     return 1;
    311 }
    312 
    313 static void collect_decoder(OSSL_DECODER *decoder, void *arg)
    314 {
    315     struct collect_data_st *data = arg;
    316     STACK_OF(EVP_KEYMGMT) *keymgmts = data->keymgmts;
    317     int i, end_i;
    318     EVP_KEYMGMT *keymgmt;
    319     const OSSL_PROVIDER *prov;
    320     void *provctx;
    321 
    322     if (data->error_occurred)
    323         return;
    324 
    325     prov = OSSL_DECODER_get0_provider(decoder);
    326     provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
    327 
    328     /*
    329      * Either the caller didn't give us a selection, or if they did, the decoder
    330      * must tell us if it supports that selection to be accepted. If the decoder
    331      * doesn't have |does_selection|, it's seen as taking anything.
    332      */
    333     if (decoder->does_selection != NULL
    334         && !decoder->does_selection(provctx, data->ctx->selection))
    335         return;
    336 
    337     OSSL_TRACE_BEGIN(DECODER)
    338     {
    339         BIO_printf(trc_out,
    340             "(ctx %p) Checking out decoder %p:\n"
    341             "    %s with %s\n",
    342             (void *)data->ctx, (void *)decoder,
    343             OSSL_DECODER_get0_name(decoder),
    344             OSSL_DECODER_get0_properties(decoder));
    345     }
    346     OSSL_TRACE_END(DECODER);
    347 
    348     end_i = sk_EVP_KEYMGMT_num(keymgmts);
    349     for (i = 0; i < end_i; ++i) {
    350         keymgmt = sk_EVP_KEYMGMT_value(keymgmts, i);
    351 
    352         /* Only add this decoder once */
    353         if (collect_decoder_keymgmt(keymgmt, decoder, provctx, data))
    354             break;
    355         if (data->error_occurred)
    356             return;
    357     }
    358 }
    359 
    360 /*
    361  * Is this EVP_KEYMGMT applicable given the key type given in the call to
    362  * ossl_decoder_ctx_setup_for_pkey (if any)?
    363  */
    364 static int check_keymgmt(EVP_KEYMGMT *keymgmt, struct collect_data_st *data)
    365 {
    366     /* If no keytype was specified, everything matches. */
    367     if (data->keytype == NULL)
    368         return 1;
    369 
    370     if (!data->keytype_resolved) {
    371         /* We haven't cached the IDs from the keytype string yet. */
    372         OSSL_NAMEMAP *namemap = ossl_namemap_stored(data->libctx);
    373         data->keytype_id = ossl_namemap_name2num(namemap, data->keytype);
    374 
    375         /*
    376          * If keytype is a value ambiguously used for both EC and SM2,
    377          * collect the ID for SM2 as well.
    378          */
    379         if (data->keytype_id != 0
    380             && (strcmp(data->keytype, "id-ecPublicKey") == 0
    381                 || strcmp(data->keytype, "1.2.840.10045.2.1") == 0))
    382             data->sm2_id = ossl_namemap_name2num(namemap, "SM2");
    383 
    384         /*
    385          * If keytype_id is zero the name was not found, but we still
    386          * set keytype_resolved to avoid trying all this again.
    387          */
    388         data->keytype_resolved = 1;
    389     }
    390 
    391     /* Specified keytype could not be resolved, so nothing matches. */
    392     if (data->keytype_id == 0)
    393         return 0;
    394 
    395     /* Does not match the keytype specified, so skip. */
    396     if (keymgmt->name_id != data->keytype_id
    397         && keymgmt->name_id != data->sm2_id)
    398         return 0;
    399 
    400     return 1;
    401 }
    402 
    403 static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg)
    404 {
    405     struct collect_data_st *data = arg;
    406 
    407     if (!check_keymgmt(keymgmt, data))
    408         return;
    409 
    410     /*
    411      * We have to ref EVP_KEYMGMT here because in the success case,
    412      * data->keymgmts is referenced by the constructor we register in the
    413      * OSSL_DECODER_CTX. The registered cleanup function
    414      * (decoder_clean_pkey_construct_arg) unrefs every element of the stack and
    415      * frees it.
    416      */
    417     if (!EVP_KEYMGMT_up_ref(keymgmt))
    418         return;
    419 
    420     if (sk_EVP_KEYMGMT_push(data->keymgmts, keymgmt) <= 0) {
    421         EVP_KEYMGMT_free(keymgmt);
    422         data->error_occurred = 1;
    423     }
    424 }
    425 
    426 /*
    427  * This function does the actual binding of decoders to the OSSL_DECODER_CTX. It
    428  * searches for decoders matching 'keytype', which is a string like "RSA", "DH",
    429  * etc. If 'keytype' is NULL, decoders for all keytypes are bound.
    430  */
    431 static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
    432     const char *keytype,
    433     OSSL_LIB_CTX *libctx,
    434     const char *propquery)
    435 {
    436     int ok = 0;
    437     struct decoder_pkey_data_st *process_data = NULL;
    438     struct collect_data_st collect_data = { NULL };
    439     STACK_OF(EVP_KEYMGMT) *keymgmts = NULL;
    440     OSSL_PROPERTY_LIST **plp;
    441     OSSL_PROPERTY_LIST *pq = NULL, *p2 = NULL;
    442 
    443     OSSL_TRACE_BEGIN(DECODER)
    444     {
    445         const char *input_type = ctx->start_input_type;
    446         const char *input_structure = ctx->input_structure;
    447 
    448         BIO_printf(trc_out,
    449             "(ctx %p) Looking for decoders producing %s%s%s%s%s%s\n",
    450             (void *)ctx,
    451             keytype != NULL ? keytype : "",
    452             keytype != NULL ? " keys" : "keys of any type",
    453             input_type != NULL ? " from " : "",
    454             input_type != NULL ? input_type : "",
    455             input_structure != NULL ? " with " : "",
    456             input_structure != NULL ? input_structure : "");
    457     }
    458     OSSL_TRACE_END(DECODER);
    459 
    460     /* Allocate data. */
    461     if ((process_data = OPENSSL_zalloc(sizeof(*process_data))) == NULL)
    462         goto err;
    463     if ((propquery != NULL
    464             && (process_data->propq = OPENSSL_strdup(propquery)) == NULL))
    465         goto err;
    466 
    467     /* Allocate our list of EVP_KEYMGMTs. */
    468     keymgmts = sk_EVP_KEYMGMT_new_null();
    469     if (keymgmts == NULL) {
    470         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB);
    471         goto err;
    472     }
    473 
    474     process_data->object = NULL;
    475     process_data->libctx = libctx;
    476     process_data->selection = ctx->selection;
    477     process_data->keymgmts = keymgmts;
    478 
    479     /*
    480      * Collect passed and default properties to prioritize the decoders.
    481      */
    482     if (propquery != NULL)
    483         p2 = pq = ossl_parse_query(libctx, propquery, 1);
    484 
    485     plp = ossl_ctx_global_properties(libctx, 0);
    486     if (plp != NULL && *plp != NULL) {
    487         if (pq == NULL) {
    488             pq = *plp;
    489         } else {
    490             p2 = ossl_property_merge(pq, *plp);
    491             ossl_property_free(pq);
    492             if (p2 == NULL)
    493                 goto err;
    494             pq = p2;
    495         }
    496     }
    497 
    498     /*
    499      * Enumerate all keymgmts into a stack.
    500      *
    501      * We could nest EVP_KEYMGMT_do_all_provided inside
    502      * OSSL_DECODER_do_all_provided or vice versa but these functions become
    503      * bottlenecks if called repeatedly, which is why we collect the
    504      * EVP_KEYMGMTs into a stack here and call both functions only once.
    505      *
    506      * We resolve the keytype string to a name ID so we don't have to resolve it
    507      * multiple times, avoiding repeated calls to EVP_KEYMGMT_is_a, which is a
    508      * performance bottleneck. However, we do this lazily on the first call to
    509      * collect_keymgmt made by EVP_KEYMGMT_do_all_provided, rather than do it
    510      * upfront, as this ensures that the names for all loaded providers have
    511      * been registered by the time we try to resolve the keytype string.
    512      */
    513     collect_data.ctx = ctx;
    514     collect_data.libctx = libctx;
    515     collect_data.keymgmts = keymgmts;
    516     collect_data.keytype = keytype;
    517     collect_data.pq = pq;
    518     EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, &collect_data);
    519 
    520     if (collect_data.error_occurred)
    521         goto err;
    522 
    523     /* Enumerate all matching decoders. */
    524     OSSL_DECODER_do_all_provided(libctx, collect_decoder, &collect_data);
    525 
    526     if (collect_data.error_occurred)
    527         goto err;
    528 
    529     OSSL_TRACE_BEGIN(DECODER)
    530     {
    531         BIO_printf(trc_out,
    532             "(ctx %p) Got %d decoders producing keys\n",
    533             (void *)ctx, collect_data.total);
    534     }
    535     OSSL_TRACE_END(DECODER);
    536 
    537     /*
    538      * Finish initializing the decoder context. If one or more decoders matched
    539      * above then the number of decoders attached to the OSSL_DECODER_CTX will
    540      * be nonzero. Else nothing was found and we do nothing.
    541      */
    542     if (OSSL_DECODER_CTX_get_num_decoders(ctx) != 0) {
    543         if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_pkey)
    544             || !OSSL_DECODER_CTX_set_construct_data(ctx, process_data)
    545             || !OSSL_DECODER_CTX_set_cleanup(ctx,
    546                 decoder_clean_pkey_construct_arg))
    547             goto err;
    548 
    549         process_data = NULL; /* Avoid it being freed */
    550     }
    551 
    552     ok = 1;
    553 err:
    554     decoder_clean_pkey_construct_arg(process_data);
    555     ossl_property_free(p2);
    556     return ok;
    557 }
    558 
    559 /* Only const here because deep_copy requires it */
    560 static EVP_KEYMGMT *keymgmt_dup(const EVP_KEYMGMT *keymgmt)
    561 {
    562     if (!EVP_KEYMGMT_up_ref((EVP_KEYMGMT *)keymgmt))
    563         return NULL;
    564 
    565     return (EVP_KEYMGMT *)keymgmt;
    566 }
    567 
    568 /*
    569  * Duplicates a template OSSL_DECODER_CTX that has been setup for an EVP_PKEY
    570  * operation and sets up the duplicate for a new operation.
    571  * It does not duplicate the pwdata on the assumption that this does not form
    572  * part of the template. That is set up later.
    573  */
    574 static OSSL_DECODER_CTX *
    575 ossl_decoder_ctx_for_pkey_dup(OSSL_DECODER_CTX *src,
    576     EVP_PKEY **pkey,
    577     const char *input_type,
    578     const char *input_structure)
    579 {
    580     OSSL_DECODER_CTX *dest;
    581     struct decoder_pkey_data_st *process_data_src, *process_data_dest = NULL;
    582 
    583     if (src == NULL)
    584         return NULL;
    585 
    586     if ((dest = OSSL_DECODER_CTX_new()) == NULL) {
    587         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    588         return NULL;
    589     }
    590 
    591     if (!OSSL_DECODER_CTX_set_input_type(dest, input_type)
    592         || !OSSL_DECODER_CTX_set_input_structure(dest, input_structure)) {
    593         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    594         goto err;
    595     }
    596     dest->selection = src->selection;
    597 
    598     if (src->decoder_insts != NULL) {
    599         dest->decoder_insts
    600             = sk_OSSL_DECODER_INSTANCE_deep_copy(src->decoder_insts,
    601                 ossl_decoder_instance_dup,
    602                 ossl_decoder_instance_free);
    603         if (dest->decoder_insts == NULL) {
    604             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    605             goto err;
    606         }
    607     }
    608 
    609     if (!OSSL_DECODER_CTX_set_construct(dest,
    610             OSSL_DECODER_CTX_get_construct(src))) {
    611         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    612         goto err;
    613     }
    614 
    615     process_data_src = OSSL_DECODER_CTX_get_construct_data(src);
    616     if (process_data_src != NULL) {
    617         process_data_dest = OPENSSL_zalloc(sizeof(*process_data_dest));
    618         if (process_data_dest == NULL) {
    619             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB);
    620             goto err;
    621         }
    622         if (process_data_src->propq != NULL) {
    623             process_data_dest->propq = OPENSSL_strdup(process_data_src->propq);
    624             if (process_data_dest->propq == NULL) {
    625                 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB);
    626                 goto err;
    627             }
    628         }
    629 
    630         if (process_data_src->keymgmts != NULL) {
    631             process_data_dest->keymgmts
    632                 = sk_EVP_KEYMGMT_deep_copy(process_data_src->keymgmts,
    633                     keymgmt_dup,
    634                     EVP_KEYMGMT_free);
    635             if (process_data_dest->keymgmts == NULL) {
    636                 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_EVP_LIB);
    637                 goto err;
    638             }
    639         }
    640 
    641         process_data_dest->object = (void **)pkey;
    642         process_data_dest->libctx = process_data_src->libctx;
    643         process_data_dest->selection = process_data_src->selection;
    644         process_data_dest->ctx = dest;
    645         if (!OSSL_DECODER_CTX_set_construct_data(dest, process_data_dest)) {
    646             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    647             goto err;
    648         }
    649         process_data_dest = NULL;
    650     }
    651 
    652     if (!OSSL_DECODER_CTX_set_cleanup(dest,
    653             OSSL_DECODER_CTX_get_cleanup(src))) {
    654         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    655         goto err;
    656     }
    657 
    658     return dest;
    659 err:
    660     decoder_clean_pkey_construct_arg(process_data_dest);
    661     OSSL_DECODER_CTX_free(dest);
    662     return NULL;
    663 }
    664 
    665 typedef struct {
    666     char *input_type;
    667     char *input_structure;
    668     char *keytype;
    669     int selection;
    670     char *propquery;
    671     OSSL_DECODER_CTX *template;
    672 } DECODER_CACHE_ENTRY;
    673 
    674 DEFINE_LHASH_OF_EX(DECODER_CACHE_ENTRY);
    675 
    676 typedef struct {
    677     CRYPTO_RWLOCK *lock;
    678     LHASH_OF(DECODER_CACHE_ENTRY) *hashtable;
    679 } DECODER_CACHE;
    680 
    681 static void decoder_cache_entry_free(DECODER_CACHE_ENTRY *entry)
    682 {
    683     if (entry == NULL)
    684         return;
    685     OPENSSL_free(entry->input_type);
    686     OPENSSL_free(entry->input_structure);
    687     OPENSSL_free(entry->keytype);
    688     OPENSSL_free(entry->propquery);
    689     OSSL_DECODER_CTX_free(entry->template);
    690     OPENSSL_free(entry);
    691 }
    692 
    693 static unsigned long decoder_cache_entry_hash(const DECODER_CACHE_ENTRY *cache)
    694 {
    695     unsigned long hash = 17;
    696 
    697     hash = (hash * 23)
    698         + (cache->propquery == NULL
    699                 ? 0
    700                 : ossl_lh_strcasehash(cache->propquery));
    701     hash = (hash * 23)
    702         + (cache->input_structure == NULL
    703                 ? 0
    704                 : ossl_lh_strcasehash(cache->input_structure));
    705     hash = (hash * 23)
    706         + (cache->input_type == NULL
    707                 ? 0
    708                 : ossl_lh_strcasehash(cache->input_type));
    709     hash = (hash * 23)
    710         + (cache->keytype == NULL
    711                 ? 0
    712                 : ossl_lh_strcasehash(cache->keytype));
    713 
    714     hash ^= cache->selection;
    715 
    716     return hash;
    717 }
    718 
    719 static ossl_inline int nullstrcmp(const char *a, const char *b, int casecmp)
    720 {
    721     if (a == NULL || b == NULL) {
    722         if (a == NULL) {
    723             if (b == NULL)
    724                 return 0;
    725             else
    726                 return 1;
    727         } else {
    728             return -1;
    729         }
    730     } else {
    731         if (casecmp)
    732             return OPENSSL_strcasecmp(a, b);
    733         else
    734             return strcmp(a, b);
    735     }
    736 }
    737 
    738 static int decoder_cache_entry_cmp(const DECODER_CACHE_ENTRY *a,
    739     const DECODER_CACHE_ENTRY *b)
    740 {
    741     int cmp;
    742 
    743     if (a->selection != b->selection)
    744         return (a->selection < b->selection) ? -1 : 1;
    745 
    746     cmp = nullstrcmp(a->keytype, b->keytype, 1);
    747     if (cmp != 0)
    748         return cmp;
    749 
    750     cmp = nullstrcmp(a->input_type, b->input_type, 1);
    751     if (cmp != 0)
    752         return cmp;
    753 
    754     cmp = nullstrcmp(a->input_structure, b->input_structure, 1);
    755     if (cmp != 0)
    756         return cmp;
    757 
    758     cmp = nullstrcmp(a->propquery, b->propquery, 0);
    759 
    760     return cmp;
    761 }
    762 
    763 void *ossl_decoder_cache_new(OSSL_LIB_CTX *ctx)
    764 {
    765     DECODER_CACHE *cache = OPENSSL_malloc(sizeof(*cache));
    766 
    767     if (cache == NULL)
    768         return NULL;
    769 
    770     cache->lock = CRYPTO_THREAD_lock_new();
    771     if (cache->lock == NULL) {
    772         OPENSSL_free(cache);
    773         return NULL;
    774     }
    775     cache->hashtable = lh_DECODER_CACHE_ENTRY_new(decoder_cache_entry_hash,
    776         decoder_cache_entry_cmp);
    777     if (cache->hashtable == NULL) {
    778         CRYPTO_THREAD_lock_free(cache->lock);
    779         OPENSSL_free(cache);
    780         return NULL;
    781     }
    782 
    783     return cache;
    784 }
    785 
    786 void ossl_decoder_cache_free(void *vcache)
    787 {
    788     DECODER_CACHE *cache = (DECODER_CACHE *)vcache;
    789 
    790     lh_DECODER_CACHE_ENTRY_doall(cache->hashtable, decoder_cache_entry_free);
    791     lh_DECODER_CACHE_ENTRY_free(cache->hashtable);
    792     CRYPTO_THREAD_lock_free(cache->lock);
    793     OPENSSL_free(cache);
    794 }
    795 
    796 /*
    797  * Called whenever a provider gets activated/deactivated. In that case the
    798  * decoders that are available might change so we flush our cache.
    799  */
    800 int ossl_decoder_cache_flush(OSSL_LIB_CTX *libctx)
    801 {
    802     DECODER_CACHE *cache
    803         = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX);
    804 
    805     if (cache == NULL)
    806         return 0;
    807 
    808     if (!CRYPTO_THREAD_write_lock(cache->lock)) {
    809         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    810         return 0;
    811     }
    812 
    813     lh_DECODER_CACHE_ENTRY_doall(cache->hashtable, decoder_cache_entry_free);
    814     lh_DECODER_CACHE_ENTRY_flush(cache->hashtable);
    815 
    816     CRYPTO_THREAD_unlock(cache->lock);
    817     return 1;
    818 }
    819 
    820 OSSL_DECODER_CTX *
    821 OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey,
    822     const char *input_type,
    823     const char *input_structure,
    824     const char *keytype, int selection,
    825     OSSL_LIB_CTX *libctx, const char *propquery)
    826 {
    827     OSSL_DECODER_CTX *ctx = NULL;
    828     OSSL_PARAM decoder_params[] = {
    829         OSSL_PARAM_END,
    830         OSSL_PARAM_END,
    831         OSSL_PARAM_END
    832     };
    833     DECODER_CACHE *cache
    834         = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX);
    835     DECODER_CACHE_ENTRY cacheent, *res, *newcache = NULL;
    836     int i = 0;
    837 
    838     if (cache == NULL) {
    839         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    840         return NULL;
    841     }
    842     if (input_structure != NULL)
    843         decoder_params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
    844             (char *)input_structure, 0);
    845     if (propquery != NULL)
    846         decoder_params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_PROPERTIES,
    847             (char *)propquery, 0);
    848 
    849     /* It is safe to cast away the const here */
    850     cacheent.input_type = (char *)input_type;
    851     cacheent.input_structure = (char *)input_structure;
    852     cacheent.keytype = (char *)keytype;
    853     cacheent.selection = selection;
    854     cacheent.propquery = (char *)propquery;
    855 
    856     if (!CRYPTO_THREAD_read_lock(cache->lock)) {
    857         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB);
    858         return NULL;
    859     }
    860 
    861     /* First see if we have a template OSSL_DECODER_CTX */
    862     res = lh_DECODER_CACHE_ENTRY_retrieve(cache->hashtable, &cacheent);
    863 
    864     if (res == NULL) {
    865         /*
    866          * There is no template so we will have to construct one. This will be
    867          * time consuming so release the lock and we will later upgrade it to a
    868          * write lock.
    869          */
    870         CRYPTO_THREAD_unlock(cache->lock);
    871 
    872         if ((ctx = OSSL_DECODER_CTX_new()) == NULL) {
    873             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    874             return NULL;
    875         }
    876 
    877         OSSL_TRACE_BEGIN(DECODER)
    878         {
    879             BIO_printf(trc_out,
    880                 "(ctx %p) Looking for %s decoders with selection %d\n",
    881                 (void *)ctx, keytype, selection);
    882             BIO_printf(trc_out, "    input type: %s, input structure: %s\n",
    883                 input_type, input_structure);
    884         }
    885         OSSL_TRACE_END(DECODER);
    886 
    887         if (OSSL_DECODER_CTX_set_input_type(ctx, input_type)
    888             && OSSL_DECODER_CTX_set_input_structure(ctx, input_structure)
    889             && OSSL_DECODER_CTX_set_selection(ctx, selection)
    890             && ossl_decoder_ctx_setup_for_pkey(ctx, keytype, libctx, propquery)
    891             && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)
    892             && (propquery == NULL
    893                 || OSSL_DECODER_CTX_set_params(ctx, decoder_params))) {
    894             OSSL_TRACE_BEGIN(DECODER)
    895             {
    896                 BIO_printf(trc_out, "(ctx %p) Got %d decoders\n",
    897                     (void *)ctx, OSSL_DECODER_CTX_get_num_decoders(ctx));
    898             }
    899             OSSL_TRACE_END(DECODER);
    900         } else {
    901             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
    902             OSSL_DECODER_CTX_free(ctx);
    903             return NULL;
    904         }
    905 
    906         newcache = OPENSSL_zalloc(sizeof(*newcache));
    907         if (newcache == NULL) {
    908             OSSL_DECODER_CTX_free(ctx);
    909             return NULL;
    910         }
    911 
    912         if (input_type != NULL) {
    913             newcache->input_type = OPENSSL_strdup(input_type);
    914             if (newcache->input_type == NULL)
    915                 goto err;
    916         }
    917         if (input_structure != NULL) {
    918             newcache->input_structure = OPENSSL_strdup(input_structure);
    919             if (newcache->input_structure == NULL)
    920                 goto err;
    921         }
    922         if (keytype != NULL) {
    923             newcache->keytype = OPENSSL_strdup(keytype);
    924             if (newcache->keytype == NULL)
    925                 goto err;
    926         }
    927         if (propquery != NULL) {
    928             newcache->propquery = OPENSSL_strdup(propquery);
    929             if (newcache->propquery == NULL)
    930                 goto err;
    931         }
    932         newcache->selection = selection;
    933         newcache->template = ctx;
    934 
    935         if (!CRYPTO_THREAD_write_lock(cache->lock)) {
    936             ctx = NULL;
    937             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB);
    938             goto err;
    939         }
    940         res = lh_DECODER_CACHE_ENTRY_retrieve(cache->hashtable, &cacheent);
    941         if (res == NULL) {
    942             (void)lh_DECODER_CACHE_ENTRY_insert(cache->hashtable, newcache);
    943             if (lh_DECODER_CACHE_ENTRY_error(cache->hashtable)) {
    944                 ctx = NULL;
    945                 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB);
    946                 goto err;
    947             }
    948         } else {
    949             /*
    950              * We raced with another thread to construct this and lost. Free
    951              * what we just created and use the entry from the hashtable instead
    952              */
    953             decoder_cache_entry_free(newcache);
    954             ctx = res->template;
    955         }
    956     } else {
    957         ctx = res->template;
    958     }
    959 
    960     ctx = ossl_decoder_ctx_for_pkey_dup(ctx, pkey, input_type, input_structure);
    961     CRYPTO_THREAD_unlock(cache->lock);
    962 
    963     return ctx;
    964 err:
    965     decoder_cache_entry_free(newcache);
    966     OSSL_DECODER_CTX_free(ctx);
    967     return NULL;
    968 }
    969