2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/crypto.h>
11 #include <openssl/core_numbers.h>
12 #include <openssl/evp.h>
13 #include <openssl/err.h>
14 #include "internal/provider.h"
15 #include "internal/refcount.h"
16 #include "internal/evp_int.h"
20 static void *keymgmt_new(void)
22 EVP_KEYMGMT
*keymgmt
= NULL
;
24 if ((keymgmt
= OPENSSL_zalloc(sizeof(*keymgmt
))) == NULL
25 || (keymgmt
->lock
= CRYPTO_THREAD_lock_new()) == NULL
) {
26 EVP_KEYMGMT_free(keymgmt
);
27 EVPerr(0, ERR_R_MALLOC_FAILURE
);
36 static void *keymgmt_from_dispatch(const char *name
, const OSSL_DISPATCH
*fns
,
39 EVP_KEYMGMT
*keymgmt
= NULL
;
41 if ((keymgmt
= keymgmt_new()) == NULL
42 || (keymgmt
->name
= OPENSSL_strdup(name
)) == NULL
) {
43 EVP_KEYMGMT_free(keymgmt
);
47 for (; fns
->function_id
!= 0; fns
++) {
48 switch (fns
->function_id
) {
49 case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS
:
50 if (keymgmt
->importdomparams
!= NULL
)
52 keymgmt
->importdomparams
=
53 OSSL_get_OP_keymgmt_importdomparams(fns
);
55 case OSSL_FUNC_KEYMGMT_GENDOMPARAMS
:
56 if (keymgmt
->gendomparams
!= NULL
)
58 keymgmt
->gendomparams
= OSSL_get_OP_keymgmt_gendomparams(fns
);
60 case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS
:
61 if (keymgmt
->freedomparams
!= NULL
)
63 keymgmt
->freedomparams
= OSSL_get_OP_keymgmt_freedomparams(fns
);
65 case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS
:
66 if (keymgmt
->exportdomparams
!= NULL
)
68 keymgmt
->exportdomparams
=
69 OSSL_get_OP_keymgmt_exportdomparams(fns
);
71 case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES
:
72 if (keymgmt
->importdomparam_types
!= NULL
)
74 keymgmt
->importdomparam_types
=
75 OSSL_get_OP_keymgmt_importdomparam_types(fns
);
77 case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES
:
78 if (keymgmt
->exportdomparam_types
!= NULL
)
80 keymgmt
->exportdomparam_types
=
81 OSSL_get_OP_keymgmt_exportdomparam_types(fns
);
83 case OSSL_FUNC_KEYMGMT_IMPORTKEY
:
84 if (keymgmt
->importkey
!= NULL
)
86 keymgmt
->importkey
= OSSL_get_OP_keymgmt_importkey(fns
);
88 case OSSL_FUNC_KEYMGMT_GENKEY
:
89 if (keymgmt
->genkey
!= NULL
)
91 keymgmt
->genkey
= OSSL_get_OP_keymgmt_genkey(fns
);
93 case OSSL_FUNC_KEYMGMT_LOADKEY
:
94 if (keymgmt
->loadkey
!= NULL
)
96 keymgmt
->loadkey
= OSSL_get_OP_keymgmt_loadkey(fns
);
98 case OSSL_FUNC_KEYMGMT_FREEKEY
:
99 if (keymgmt
->freekey
!= NULL
)
101 keymgmt
->freekey
= OSSL_get_OP_keymgmt_freekey(fns
);
103 case OSSL_FUNC_KEYMGMT_EXPORTKEY
:
104 if (keymgmt
->exportkey
!= NULL
)
106 keymgmt
->exportkey
= OSSL_get_OP_keymgmt_exportkey(fns
);
108 case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES
:
109 if (keymgmt
->importkey_types
!= NULL
)
111 keymgmt
->importkey_types
=
112 OSSL_get_OP_keymgmt_importkey_types(fns
);
114 case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES
:
115 if (keymgmt
->exportkey_types
!= NULL
)
117 keymgmt
->exportkey_types
=
118 OSSL_get_OP_keymgmt_exportkey_types(fns
);
123 * Try to check that the method is sensible.
124 * It makes no sense being able to free stuff if you can't create it.
125 * It makes no sense providing OSSL_PARAM descriptors for import and
126 * export if you can't import or export.
128 if ((keymgmt
->freedomparams
!= NULL
129 && (keymgmt
->importdomparams
== NULL
130 && keymgmt
->gendomparams
== NULL
))
131 || (keymgmt
->freekey
!= NULL
132 && (keymgmt
->importkey
== NULL
133 && keymgmt
->genkey
== NULL
134 && keymgmt
->loadkey
== NULL
))
135 || (keymgmt
->importdomparam_types
!= NULL
136 && keymgmt
->importdomparams
== NULL
)
137 || (keymgmt
->exportdomparam_types
!= NULL
138 && keymgmt
->exportdomparams
== NULL
)
139 || (keymgmt
->importkey_types
!= NULL
140 && keymgmt
->importkey
== NULL
)
141 || (keymgmt
->exportkey_types
!= NULL
142 && keymgmt
->exportkey
== NULL
)) {
143 EVP_KEYMGMT_free(keymgmt
);
144 EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS
);
147 keymgmt
->prov
= prov
;
149 ossl_provider_up_ref(prov
);
154 EVP_KEYMGMT
*EVP_KEYMGMT_fetch(OPENSSL_CTX
*ctx
, const char *algorithm
,
155 const char *properties
)
157 EVP_KEYMGMT
*keymgmt
=
158 evp_generic_fetch(ctx
, OSSL_OP_KEYMGMT
, algorithm
, properties
,
159 keymgmt_from_dispatch
,
160 (int (*)(void *))EVP_KEYMGMT_up_ref
,
161 (void (*)(void *))EVP_KEYMGMT_free
);
166 int EVP_KEYMGMT_up_ref(EVP_KEYMGMT
*keymgmt
)
170 CRYPTO_UP_REF(&keymgmt
->refcnt
, &ref
, keymgmt
->lock
);
174 void EVP_KEYMGMT_free(EVP_KEYMGMT
*keymgmt
)
181 CRYPTO_DOWN_REF(&keymgmt
->refcnt
, &ref
, keymgmt
->lock
);
184 ossl_provider_free(keymgmt
->prov
);
185 OPENSSL_free(keymgmt
->name
);
186 CRYPTO_THREAD_lock_free(keymgmt
->lock
);
187 OPENSSL_free(keymgmt
);
190 const OSSL_PROVIDER
*EVP_KEYMGMT_provider(const EVP_KEYMGMT
*keymgmt
)
192 return keymgmt
->prov
;