EVP: Implement support for key downgrading in backends
[openssl.git] / crypto / core_algorithm.c
1 /*
2  * Copyright 2019 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_numbers.h>
12 #include "internal/core.h"
13 #include "internal/property.h"
14 #include "internal/provider.h"
15
16 struct algorithm_data_st {
17     OPENSSL_CTX *libctx;
18     int operation_id;            /* May be zero for finding them all */
19     void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store,
20                void *data);
21     void *data;
22 };
23
24 static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata)
25 {
26     struct algorithm_data_st *data = cbdata;
27     int no_store = 0;    /* Assume caching is ok */
28     int first_operation = 1;
29     int last_operation = OSSL_OP__HIGHEST;
30     int cur_operation;
31     int ok = 0;
32
33     if (data->operation_id != 0)
34         first_operation = last_operation = data->operation_id;
35
36     for (cur_operation = first_operation;
37          cur_operation <= last_operation;
38          cur_operation++) {
39         const OSSL_ALGORITHM *map =
40             ossl_provider_query_operation(provider, data->operation_id,
41                                           &no_store);
42
43         if (map == NULL)
44             break;
45
46         ok = 1;                  /* As long as we've found *something* */
47         while (map->algorithm_names != NULL) {
48             const OSSL_ALGORITHM *thismap = map++;
49
50             data->fn(provider, thismap, no_store, data->data);
51         }
52     }
53
54     return ok;
55 }
56
57 void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id,
58                            OSSL_PROVIDER *provider,
59                            void (*fn)(OSSL_PROVIDER *provider,
60                                       const OSSL_ALGORITHM *algo,
61                                       int no_store, void *data),
62                            void *data)
63 {
64     struct algorithm_data_st cbdata;
65
66     cbdata.libctx = libctx;
67     cbdata.operation_id = operation_id;
68     cbdata.fn = fn;
69     cbdata.data = data;
70
71     if (provider == NULL)
72         ossl_provider_forall_loaded(libctx, algorithm_do_this, &cbdata);
73     else
74         algorithm_do_this(provider, &cbdata);
75 }