summaryrefslogtreecommitdiff
path: root/crypto/provider.c
blob: 65f919aec281da09dbef8859925f3b4c53c7e7a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <string.h>
#include <openssl/err.h>
#include <openssl/cryptoerr.h>
#include <openssl/provider.h>
#include <openssl/core_names.h>
#include "internal/provider.h"
#include "provider_local.h"

OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name,
                                      int retain_fallbacks)
{
    OSSL_PROVIDER *prov = NULL, *actual;
    int isnew = 0;

    /* Find it or create it */
    if ((prov = ossl_provider_find(libctx, name, 0)) == NULL) {
        if ((prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL)
            return NULL;
        isnew = 1;
    }

    if (!ossl_provider_activate(prov, 1, 0)) {
        ossl_provider_free(prov);
        return NULL;
    }

    actual = prov;
    if (isnew && !ossl_provider_add_to_store(prov, &actual, retain_fallbacks)) {
        ossl_provider_deactivate(prov, 1);
        ossl_provider_free(prov);
        return NULL;
    }
    if (actual != prov) {
        if (!ossl_provider_activate(actual, 1, 0)) {
            ossl_provider_free(actual);
            return NULL;
        }
    }

    return actual;
}

OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name)
{
    /* Any attempt to load a provider disables auto-loading of defaults */
    if (ossl_provider_disable_fallback_loading(libctx))
        return OSSL_PROVIDER_try_load(libctx, name, 0);
    return NULL;
}

int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov)
{
    if (!ossl_provider_deactivate(prov, 1))
        return 0;
    ossl_provider_free(prov);
    return 1;
}

const OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov)
{
    return ossl_provider_gettable_params(prov);
}

int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
{
    return ossl_provider_get_params(prov, params);
}

const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov,
                                                    int operation_id,
                                                    int *no_cache)
{
    return ossl_provider_query_operation(prov, operation_id, no_cache);
}

void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov,
                                     int operation_id,
                                     const OSSL_ALGORITHM *algs)
{
    ossl_provider_unquery_operation(prov, operation_id, algs);
}

void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov)
{
    return ossl_provider_prov_ctx(prov);
}

const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov)
{
    return ossl_provider_get0_dispatch(prov);
}

int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov)
{
    return ossl_provider_self_test(prov);
}

int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov,
                                   const char *capability,
                                   OSSL_CALLBACK *cb,
                                   void *arg)
{
    return ossl_provider_get_capabilities(prov, capability, cb, arg);
}

int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name,
                              OSSL_provider_init_fn *init_fn)
{
    OSSL_PROVIDER_INFO entry;

    if (name == NULL || init_fn == NULL) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    memset(&entry, 0, sizeof(entry));
    entry.name = OPENSSL_strdup(name);
    if (entry.name == NULL)
        return 0;
    entry.init = init_fn;
    if (!ossl_provider_info_add_to_store(libctx, &entry)) {
        ossl_provider_info_clear(&entry);
        return 0;
    }
    return 1;
}

const char *OSSL_PROVIDER_get0_name(const OSSL_PROVIDER *prov)
{
    return ossl_provider_name(prov);
}

int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx,
                         int (*cb)(OSSL_PROVIDER *provider,
                                   void *cbdata),
                         void *cbdata)
{
    return ossl_provider_doall_activated(ctx, cb, cbdata);
}