Coverage Report

Created: 2025-12-31 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl30/crypto/encode_decode/decoder_meth.c
Line
Count
Source
1
/*
2
 * Copyright 2020-2022 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.h>
11
#include <openssl/core_dispatch.h>
12
#include <openssl/decoder.h>
13
#include <openssl/ui.h>
14
#include "internal/core.h"
15
#include "internal/namemap.h"
16
#include "internal/property.h"
17
#include "internal/provider.h"
18
#include "crypto/decoder.h"
19
#include "encoder_local.h"
20
21
/*
22
 * Decoder can have multiple names, separated with colons in a name string
23
 */
24
7.17k
#define NAME_SEPARATOR ':'
25
26
/* Simple method structure constructor and destructor */
27
static OSSL_DECODER *ossl_decoder_new(void)
28
240
{
29
240
    OSSL_DECODER *decoder = NULL;
30
31
240
    if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL
32
240
        || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
33
0
        OSSL_DECODER_free(decoder);
34
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
35
0
        return NULL;
36
0
    }
37
38
240
    decoder->base.refcnt = 1;
39
40
240
    return decoder;
41
240
}
42
43
int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
44
25.4M
{
45
25.4M
    int ref = 0;
46
47
25.4M
    CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
48
25.4M
    return 1;
49
25.4M
}
50
51
void OSSL_DECODER_free(OSSL_DECODER *decoder)
52
25.4M
{
53
25.4M
    int ref = 0;
54
55
25.4M
    if (decoder == NULL)
56
0
        return;
57
58
25.4M
    CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
59
25.4M
    if (ref > 0)
60
25.4M
        return;
61
2.75k
    OPENSSL_free(decoder->base.name);
62
2.75k
    ossl_property_free(decoder->base.parsed_propdef);
63
2.75k
    ossl_provider_free(decoder->base.prov);
64
2.75k
    CRYPTO_THREAD_lock_free(decoder->base.lock);
65
2.75k
    OPENSSL_free(decoder);
66
2.75k
}
67
68
/* Permanent decoder method store, constructor and destructor */
69
static void decoder_store_free(void *vstore)
70
11
{
71
11
    ossl_method_store_free(vstore);
72
11
}
73
74
static void *decoder_store_new(OSSL_LIB_CTX *ctx)
75
11
{
76
11
    return ossl_method_store_new(ctx);
77
11
}
78
79
static const OSSL_LIB_CTX_METHOD decoder_store_method = {
80
    /* We want decoder_store to be cleaned up before the provider store */
81
    OSSL_LIB_CTX_METHOD_PRIORITY_2,
82
    decoder_store_new,
83
    decoder_store_free,
84
};
85
86
/* Data to be passed through ossl_method_construct() */
87
struct decoder_data_st {
88
    OSSL_LIB_CTX *libctx;
89
    int id; /* For get_decoder_from_store() */
90
    const char *names; /* For get_decoder_from_store() */
91
    const char *propquery; /* For get_decoder_from_store() */
92
93
    OSSL_METHOD_STORE *tmp_store; /* For get_tmp_decoder_store() */
94
95
    unsigned int flag_construct_error_occurred : 1;
96
};
97
98
/*
99
 * Generic routines to fetch / create DECODER methods with
100
 * ossl_method_construct()
101
 */
102
103
/* Temporary decoder method store, constructor and destructor */
104
static void *get_tmp_decoder_store(void *data)
105
0
{
106
0
    struct decoder_data_st *methdata = data;
107
108
0
    if (methdata->tmp_store == NULL)
109
0
        methdata->tmp_store = ossl_method_store_new(methdata->libctx);
110
0
    return methdata->tmp_store;
111
0
}
112
113
static void dealloc_tmp_decoder_store(void *store)
114
523k
{
115
523k
    if (store != NULL)
116
0
        ossl_method_store_free(store);
117
523k
}
118
119
/* Get the permanent decoder store */
120
static OSSL_METHOD_STORE *get_decoder_store(OSSL_LIB_CTX *libctx)
121
2.89M
{
122
2.89M
    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_STORE_INDEX,
123
2.89M
        &decoder_store_method);
124
2.89M
}
125
126
static int reserve_decoder_store(void *store, void *data)
127
920k
{
128
920k
    struct decoder_data_st *methdata = data;
129
130
920k
    if (store == NULL
131
920k
        && (store = get_decoder_store(methdata->libctx)) == NULL)
132
0
        return 0;
133
134
920k
    return ossl_method_lock_store(store);
135
920k
}
136
137
static int unreserve_decoder_store(void *store, void *data)
138
920k
{
139
920k
    struct decoder_data_st *methdata = data;
140
141
920k
    if (store == NULL
142
920k
        && (store = get_decoder_store(methdata->libctx)) == NULL)
143
0
        return 0;
144
145
920k
    return ossl_method_unlock_store(store);
146
920k
}
147
148
/* Get decoder methods from a store, or put one in */
149
static void *get_decoder_from_store(void *store, const OSSL_PROVIDER **prov,
150
    void *data)
151
523k
{
152
523k
    struct decoder_data_st *methdata = data;
153
523k
    void *method = NULL;
154
523k
    int id;
155
156
    /*
157
     * get_decoder_from_store() is only called to try and get the method
158
     * that OSSL_DECODER_fetch() is asking for, and the name or name id are
159
     * passed via methdata.
160
     */
161
523k
    if ((id = methdata->id) == 0 && methdata->names != NULL) {
162
0
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
163
0
        const char *names = methdata->names;
164
0
        const char *q = strchr(names, NAME_SEPARATOR);
165
0
        size_t l = (q == NULL ? strlen(names) : (size_t)(q - names));
166
167
0
        if (namemap == 0)
168
0
            return NULL;
169
0
        id = ossl_namemap_name2num_n(namemap, names, l);
170
0
    }
171
172
523k
    if (id == 0)
173
523k
        return NULL;
174
175
0
    if (store == NULL
176
0
        && (store = get_decoder_store(methdata->libctx)) == NULL)
177
0
        return NULL;
178
179
0
    if (!ossl_method_store_fetch(store, id, methdata->propquery, prov, &method))
180
0
        return NULL;
181
0
    return method;
182
0
}
183
184
static int put_decoder_in_store(void *store, void *method,
185
    const OSSL_PROVIDER *prov,
186
    const char *names, const char *propdef,
187
    void *data)
188
3.58k
{
189
3.58k
    struct decoder_data_st *methdata = data;
190
3.58k
    OSSL_NAMEMAP *namemap;
191
3.58k
    int id;
192
3.58k
    size_t l = 0;
193
194
    /*
195
     * put_decoder_in_store() is only called with an OSSL_DECODER method that
196
     * was successfully created by construct_decoder() below, which means that
197
     * all the names should already be stored in the namemap with the same
198
     * numeric identity, so just use the first to get that identity.
199
     */
200
3.58k
    if (names != NULL) {
201
3.58k
        const char *q = strchr(names, NAME_SEPARATOR);
202
203
3.58k
        l = (q == NULL ? strlen(names) : (size_t)(q - names));
204
3.58k
    }
205
206
3.58k
    if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
207
3.58k
        || (id = ossl_namemap_name2num_n(namemap, names, l)) == 0)
208
0
        return 0;
209
210
3.58k
    if (store == NULL && (store = get_decoder_store(methdata->libctx)) == NULL)
211
0
        return 0;
212
213
3.58k
    return ossl_method_store_add(store, prov, id, propdef, method,
214
3.58k
        (int (*)(void *))OSSL_DECODER_up_ref,
215
3.58k
        (void (*)(void *))OSSL_DECODER_free);
216
3.58k
}
217
218
/* Create and populate a decoder method */
219
void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
220
    OSSL_PROVIDER *prov)
221
3.58k
{
222
3.58k
    OSSL_DECODER *decoder = NULL;
223
3.58k
    const OSSL_DISPATCH *fns = algodef->implementation;
224
3.58k
    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
225
226
3.58k
    if ((decoder = ossl_decoder_new()) == NULL)
227
0
        return NULL;
228
3.58k
    decoder->base.id = id;
229
3.58k
    if ((decoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
230
0
        OSSL_DECODER_free(decoder);
231
0
        return NULL;
232
0
    }
233
3.58k
    decoder->base.algodef = algodef;
234
3.58k
    if ((decoder->base.parsed_propdef
235
3.58k
            = ossl_parse_property(libctx, algodef->property_definition))
236
3.58k
        == NULL) {
237
0
        OSSL_DECODER_free(decoder);
238
0
        return NULL;
239
0
    }
240
241
27.6k
    for (; fns->function_id != 0; fns++) {
242
24.0k
        switch (fns->function_id) {
243
3.58k
        case OSSL_FUNC_DECODER_NEWCTX:
244
3.58k
            if (decoder->newctx == NULL)
245
3.58k
                decoder->newctx = OSSL_FUNC_decoder_newctx(fns);
246
3.58k
            break;
247
3.58k
        case OSSL_FUNC_DECODER_FREECTX:
248
3.58k
            if (decoder->freectx == NULL)
249
3.58k
                decoder->freectx = OSSL_FUNC_decoder_freectx(fns);
250
3.58k
            break;
251
0
        case OSSL_FUNC_DECODER_GET_PARAMS:
252
0
            if (decoder->get_params == NULL)
253
0
                decoder->get_params = OSSL_FUNC_decoder_get_params(fns);
254
0
            break;
255
0
        case OSSL_FUNC_DECODER_GETTABLE_PARAMS:
256
0
            if (decoder->gettable_params == NULL)
257
0
                decoder->gettable_params = OSSL_FUNC_decoder_gettable_params(fns);
258
0
            break;
259
3.21k
        case OSSL_FUNC_DECODER_SET_CTX_PARAMS:
260
3.21k
            if (decoder->set_ctx_params == NULL)
261
3.21k
                decoder->set_ctx_params = OSSL_FUNC_decoder_set_ctx_params(fns);
262
3.21k
            break;
263
3.21k
        case OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS:
264
3.21k
            if (decoder->settable_ctx_params == NULL)
265
3.21k
                decoder->settable_ctx_params = OSSL_FUNC_decoder_settable_ctx_params(fns);
266
3.21k
            break;
267
3.40k
        case OSSL_FUNC_DECODER_DOES_SELECTION:
268
3.40k
            if (decoder->does_selection == NULL)
269
3.40k
                decoder->does_selection = OSSL_FUNC_decoder_does_selection(fns);
270
3.40k
            break;
271
3.58k
        case OSSL_FUNC_DECODER_DECODE:
272
3.58k
            if (decoder->decode == NULL)
273
3.58k
                decoder->decode = OSSL_FUNC_decoder_decode(fns);
274
3.58k
            break;
275
3.40k
        case OSSL_FUNC_DECODER_EXPORT_OBJECT:
276
3.40k
            if (decoder->export_object == NULL)
277
3.40k
                decoder->export_object = OSSL_FUNC_decoder_export_object(fns);
278
3.40k
            break;
279
24.0k
        }
280
24.0k
    }
281
    /*
282
     * Try to check that the method is sensible.
283
     * If you have a constructor, you must have a destructor and vice versa.
284
     * You must have at least one of the encoding driver functions.
285
     */
286
3.58k
    if (!((decoder->newctx == NULL && decoder->freectx == NULL)
287
3.58k
            || (decoder->newctx != NULL && decoder->freectx != NULL))
288
3.58k
        || decoder->decode == NULL) {
289
0
        OSSL_DECODER_free(decoder);
290
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
291
0
        return NULL;
292
0
    }
293
294
3.58k
    if (prov != NULL && !ossl_provider_up_ref(prov)) {
295
0
        OSSL_DECODER_free(decoder);
296
0
        return NULL;
297
0
    }
298
299
3.58k
    decoder->base.prov = prov;
300
3.58k
    return decoder;
301
3.58k
}
302
303
/*
304
 * The core fetching functionality passes the names of the implementation.
305
 * This function is responsible to getting an identity number for them,
306
 * then call ossl_decoder_from_algorithm() with that identity number.
307
 */
308
static void *construct_decoder(const OSSL_ALGORITHM *algodef,
309
    OSSL_PROVIDER *prov, void *data)
310
3.58k
{
311
    /*
312
     * This function is only called if get_decoder_from_store() returned
313
     * NULL, so it's safe to say that of all the spots to create a new
314
     * namemap entry, this is it.  Should the name already exist there, we
315
     * know that ossl_namemap_add() will return its corresponding number.
316
     */
317
3.58k
    struct decoder_data_st *methdata = data;
318
3.58k
    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
319
3.58k
    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
320
3.58k
    const char *names = algodef->algorithm_names;
321
3.58k
    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
322
3.58k
    void *method = NULL;
323
324
3.58k
    if (id != 0)
325
3.58k
        method = ossl_decoder_from_algorithm(id, algodef, prov);
326
327
    /*
328
     * Flag to indicate that there was actual construction errors.  This
329
     * helps inner_evp_generic_fetch() determine what error it should
330
     * record on inaccessible algorithms.
331
     */
332
3.58k
    if (method == NULL)
333
0
        methdata->flag_construct_error_occurred = 1;
334
335
3.58k
    return method;
336
3.58k
}
337
338
/* Intermediary function to avoid ugly casts, used below */
339
static void destruct_decoder(void *method, void *data)
340
3.58k
{
341
3.58k
    OSSL_DECODER_free(method);
342
3.58k
}
343
344
static int up_ref_decoder(void *method)
345
0
{
346
0
    return OSSL_DECODER_up_ref(method);
347
0
}
348
349
static void free_decoder(void *method)
350
0
{
351
0
    OSSL_DECODER_free(method);
352
0
}
353
354
/* Fetching support.  Can fetch by numeric identity or by name */
355
static OSSL_DECODER *
356
inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id,
357
    const char *name, const char *properties)
358
506k
{
359
506k
    OSSL_METHOD_STORE *store = get_decoder_store(methdata->libctx);
360
506k
    OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
361
506k
    const char *const propq = properties != NULL ? properties : "";
362
506k
    void *method = NULL;
363
506k
    int unsupported = 0;
364
365
506k
    if (store == NULL || namemap == NULL) {
366
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_INVALID_ARGUMENT);
367
0
        return NULL;
368
0
    }
369
370
    /*
371
     * If we have been passed both an id and a name, we have an
372
     * internal programming error.
373
     */
374
506k
    if (!ossl_assert(id == 0 || name == NULL)) {
375
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR);
376
0
        return NULL;
377
0
    }
378
379
506k
    if (id == 0 && name != NULL)
380
0
        id = ossl_namemap_name2num(namemap, name);
381
382
    /*
383
     * If we haven't found the name yet, chances are that the algorithm to
384
     * be fetched is unsupported.
385
     */
386
506k
    if (id == 0)
387
506k
        unsupported = 1;
388
389
506k
    if (id == 0
390
506k
        || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
391
506k
        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
392
506k
            get_tmp_decoder_store,
393
506k
            reserve_decoder_store,
394
506k
            unreserve_decoder_store,
395
506k
            get_decoder_from_store,
396
506k
            put_decoder_in_store,
397
506k
            construct_decoder,
398
506k
            destruct_decoder
399
506k
        };
400
506k
        OSSL_PROVIDER *prov = NULL;
401
402
506k
        methdata->id = id;
403
506k
        methdata->names = name;
404
506k
        methdata->propquery = propq;
405
506k
        methdata->flag_construct_error_occurred = 0;
406
506k
        if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_DECODER,
407
506k
                 &prov, 0 /* !force_cache */,
408
506k
                 &mcm, methdata))
409
506k
            != NULL) {
410
            /*
411
             * If construction did create a method for us, we know that
412
             * there is a correct name_id and meth_id, since those have
413
             * already been calculated in get_decoder_from_store() and
414
             * put_decoder_in_store() above.
415
             */
416
0
            if (id == 0 && name != NULL)
417
0
                id = ossl_namemap_name2num(namemap, name);
418
0
            if (id != 0)
419
0
                ossl_method_store_cache_set(store, prov, id, propq, method,
420
0
                    up_ref_decoder, free_decoder);
421
0
        }
422
423
        /*
424
         * If we never were in the constructor, the algorithm to be fetched
425
         * is unsupported.
426
         */
427
506k
        unsupported = !methdata->flag_construct_error_occurred;
428
506k
    }
429
430
506k
    if ((id != 0 || name != NULL) && method == NULL) {
431
0
        int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED;
432
433
0
        if (name == NULL)
434
0
            name = ossl_namemap_num2name(namemap, id, 0);
435
0
        ERR_raise_data(ERR_LIB_OSSL_DECODER, code,
436
0
            "%s, Name (%s : %d), Properties (%s)",
437
0
            ossl_lib_ctx_get_descriptor(methdata->libctx),
438
0
            name == NULL ? "<null>" : name, id,
439
0
            properties == NULL ? "<null>" : properties);
440
0
    }
441
442
506k
    return method;
443
506k
}
444
445
OSSL_DECODER *OSSL_DECODER_fetch(OSSL_LIB_CTX *libctx, const char *name,
446
    const char *properties)
447
0
{
448
0
    struct decoder_data_st methdata;
449
0
    void *method;
450
451
0
    methdata.libctx = libctx;
452
0
    methdata.tmp_store = NULL;
453
0
    method = inner_ossl_decoder_fetch(&methdata, 0, name, properties);
454
0
    dealloc_tmp_decoder_store(methdata.tmp_store);
455
0
    return method;
456
0
}
457
458
OSSL_DECODER *ossl_decoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id,
459
    const char *properties)
460
0
{
461
0
    struct decoder_data_st methdata;
462
0
    void *method;
463
464
0
    methdata.libctx = libctx;
465
0
    methdata.tmp_store = NULL;
466
0
    method = inner_ossl_decoder_fetch(&methdata, id, NULL, properties);
467
0
    dealloc_tmp_decoder_store(methdata.tmp_store);
468
0
    return method;
469
0
}
470
471
int ossl_decoder_store_cache_flush(OSSL_LIB_CTX *libctx)
472
136
{
473
136
    OSSL_METHOD_STORE *store = get_decoder_store(libctx);
474
475
136
    if (store != NULL)
476
136
        return ossl_method_store_cache_flush_all(store);
477
0
    return 1;
478
136
}
479
480
int ossl_decoder_store_remove_all_provided(const OSSL_PROVIDER *prov)
481
0
{
482
0
    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
483
0
    OSSL_METHOD_STORE *store = get_decoder_store(libctx);
484
485
0
    if (store != NULL)
486
0
        return ossl_method_store_remove_all_provided(store, prov);
487
0
    return 1;
488
0
}
489
490
/*
491
 * Library of basic method functions
492
 */
493
494
const OSSL_PROVIDER *OSSL_DECODER_get0_provider(const OSSL_DECODER *decoder)
495
204M
{
496
204M
    if (!ossl_assert(decoder != NULL)) {
497
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
498
0
        return 0;
499
0
    }
500
501
204M
    return decoder->base.prov;
502
204M
}
503
504
const char *OSSL_DECODER_get0_properties(const OSSL_DECODER *decoder)
505
0
{
506
0
    if (!ossl_assert(decoder != NULL)) {
507
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
508
0
        return 0;
509
0
    }
510
511
0
    return decoder->base.algodef->property_definition;
512
0
}
513
514
const OSSL_PROPERTY_LIST *
515
ossl_decoder_parsed_properties(const OSSL_DECODER *decoder)
516
3.42M
{
517
3.42M
    if (!ossl_assert(decoder != NULL)) {
518
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
519
0
        return 0;
520
0
    }
521
522
3.42M
    return decoder->base.parsed_propdef;
523
3.42M
}
524
525
int ossl_decoder_get_number(const OSSL_DECODER *decoder)
526
5.18M
{
527
5.18M
    if (!ossl_assert(decoder != NULL)) {
528
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
529
0
        return 0;
530
0
    }
531
532
5.18M
    return decoder->base.id;
533
5.18M
}
534
535
const char *OSSL_DECODER_get0_name(const OSSL_DECODER *decoder)
536
0
{
537
0
    return decoder->base.name;
538
0
}
539
540
const char *OSSL_DECODER_get0_description(const OSSL_DECODER *decoder)
541
0
{
542
0
    return decoder->base.algodef->algorithm_description;
543
0
}
544
545
int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name)
546
231M
{
547
231M
    if (decoder->base.prov != NULL) {
548
231M
        OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov);
549
231M
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
550
551
231M
        return ossl_namemap_name2num(namemap, name) == decoder->base.id;
552
231M
    }
553
0
    return 0;
554
231M
}
555
556
struct do_one_data_st {
557
    void (*user_fn)(OSSL_DECODER *decoder, void *arg);
558
    void *user_arg;
559
};
560
561
static void do_one(ossl_unused int id, void *method, void *arg)
562
21.3M
{
563
21.3M
    struct do_one_data_st *data = arg;
564
565
21.3M
    data->user_fn(method, data->user_arg);
566
21.3M
}
567
568
void OSSL_DECODER_do_all_provided(OSSL_LIB_CTX *libctx,
569
    void (*user_fn)(OSSL_DECODER *decoder,
570
        void *arg),
571
    void *user_arg)
572
523k
{
573
523k
    struct decoder_data_st methdata;
574
523k
    struct do_one_data_st data;
575
576
523k
    methdata.libctx = libctx;
577
523k
    methdata.tmp_store = NULL;
578
523k
    (void)inner_ossl_decoder_fetch(&methdata, 0, NULL, NULL /* properties */);
579
580
523k
    data.user_fn = user_fn;
581
523k
    data.user_arg = user_arg;
582
523k
    if (methdata.tmp_store != NULL)
583
0
        ossl_method_store_do_all(methdata.tmp_store, &do_one, &data);
584
523k
    ossl_method_store_do_all(get_decoder_store(libctx), &do_one, &data);
585
523k
    dealloc_tmp_decoder_store(methdata.tmp_store);
586
523k
}
587
588
int OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder,
589
    void (*fn)(const char *name, void *data),
590
    void *data)
591
0
{
592
0
    if (decoder == NULL)
593
0
        return 0;
594
595
0
    if (decoder->base.prov != NULL) {
596
0
        OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov);
597
0
        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
598
599
0
        return ossl_namemap_doall_names(namemap, decoder->base.id, fn, data);
600
0
    }
601
602
0
    return 1;
603
0
}
604
605
const OSSL_PARAM *
606
OSSL_DECODER_gettable_params(OSSL_DECODER *decoder)
607
0
{
608
0
    if (decoder != NULL && decoder->gettable_params != NULL) {
609
0
        void *provctx = ossl_provider_ctx(OSSL_DECODER_get0_provider(decoder));
610
611
0
        return decoder->gettable_params(provctx);
612
0
    }
613
0
    return NULL;
614
0
}
615
616
int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[])
617
0
{
618
0
    if (decoder != NULL && decoder->get_params != NULL)
619
0
        return decoder->get_params(params);
620
0
    return 0;
621
0
}
622
623
const OSSL_PARAM *
624
OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder)
625
0
{
626
0
    if (decoder != NULL && decoder->settable_ctx_params != NULL) {
627
0
        void *provctx = ossl_provider_ctx(OSSL_DECODER_get0_provider(decoder));
628
629
0
        return decoder->settable_ctx_params(provctx);
630
0
    }
631
0
    return NULL;
632
0
}
633
634
/*
635
 * Decoder context support
636
 */
637
638
/*
639
 * |encoder| value NULL is valid, and signifies that there is no decoder.
640
 * This is useful to provide fallback mechanisms.
641
 *  Functions that want to verify if there is a decoder can do so with
642
 * OSSL_DECODER_CTX_get_decoder()
643
 */
644
OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void)
645
261k
{
646
261k
    OSSL_DECODER_CTX *ctx;
647
648
261k
    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
649
261k
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
650
651
261k
    return ctx;
652
261k
}
653
654
int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
655
    const OSSL_PARAM params[])
656
0
{
657
0
    int ok = 1;
658
0
    size_t i;
659
0
    size_t l;
660
661
0
    if (!ossl_assert(ctx != NULL)) {
662
0
        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
663
0
        return 0;
664
0
    }
665
666
0
    if (ctx->decoder_insts == NULL)
667
0
        return 1;
668
669
0
    l = OSSL_DECODER_CTX_get_num_decoders(ctx);
670
0
    for (i = 0; i < l; i++) {
671
0
        OSSL_DECODER_INSTANCE *decoder_inst = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
672
0
        OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst);
673
0
        OSSL_DECODER *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst);
674
675
0
        if (decoderctx == NULL || decoder->set_ctx_params == NULL)
676
0
            continue;
677
0
        if (!decoder->set_ctx_params(decoderctx, params))
678
0
            ok = 0;
679
0
    }
680
0
    return ok;
681
0
}
682
683
void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx)
684
2.31M
{
685
2.31M
    if (ctx != NULL) {
686
1.35M
        if (ctx->cleanup != NULL)
687
1.24M
            ctx->cleanup(ctx->construct_data);
688
1.35M
        sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts,
689
1.35M
            ossl_decoder_instance_free);
690
1.35M
        ossl_pw_clear_passphrase_data(&ctx->pwdata);
691
1.35M
        OPENSSL_free(ctx);
692
1.35M
    }
693
2.31M
}