]>
Commit | Line | Data |
---|---|---|
4889dadc MC |
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_numbers.h> | |
11 | #include <openssl/core_names.h> | |
12 | #include <openssl/bn.h> | |
4889dadc | 13 | #include <openssl/params.h> |
1640d48c | 14 | #include "internal/param_build.h" |
8dd5c603 | 15 | #include "crypto/dsa.h" |
af3e7e1b | 16 | #include "prov/implementations.h" |
1640d48c | 17 | #include "prov/providercommon.h" |
e683582b SL |
18 | #include "prov/provider_ctx.h" |
19 | #include "crypto/dsa.h" | |
4889dadc | 20 | |
8dd5c603 RL |
21 | static OSSL_OP_keymgmt_new_fn dsa_newdata; |
22 | static OSSL_OP_keymgmt_free_fn dsa_freedata; | |
273a67e3 RL |
23 | static OSSL_OP_keymgmt_get_params_fn dsa_get_params; |
24 | static OSSL_OP_keymgmt_gettable_params_fn dsa_gettable_params; | |
8dd5c603 RL |
25 | static OSSL_OP_keymgmt_has_fn dsa_has; |
26 | static OSSL_OP_keymgmt_import_fn dsa_import; | |
273a67e3 | 27 | static OSSL_OP_keymgmt_import_types_fn dsa_import_types; |
8dd5c603 | 28 | static OSSL_OP_keymgmt_export_fn dsa_export; |
273a67e3 | 29 | static OSSL_OP_keymgmt_export_types_fn dsa_export_types; |
4889dadc | 30 | |
8baa49ae | 31 | #define DSA_DEFAULT_MD "SHA256" |
8dd5c603 | 32 | #define DSA_POSSIBLE_SELECTIONS \ |
273a67e3 | 33 | (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) |
8baa49ae | 34 | |
073f59c4 | 35 | static int params_to_domparams(DSA *dsa, const OSSL_PARAM params[]) |
4889dadc | 36 | { |
073f59c4 RL |
37 | const OSSL_PARAM *param_p, *param_q, *param_g; |
38 | BIGNUM *p = NULL, *q = NULL, *g = NULL; | |
4889dadc MC |
39 | |
40 | if (dsa == NULL) | |
41 | return 0; | |
42 | ||
43 | param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P); | |
44 | param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q); | |
45 | param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G); | |
073f59c4 RL |
46 | |
47 | if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p)) | |
48 | || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q)) | |
49 | || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))) | |
50 | goto err; | |
51 | ||
52 | if (!DSA_set0_pqg(dsa, p, q, g)) | |
53 | goto err; | |
54 | ||
55 | return 1; | |
56 | ||
57 | err: | |
58 | BN_free(p); | |
59 | BN_free(q); | |
60 | BN_free(g); | |
61 | return 0; | |
62 | } | |
63 | ||
1640d48c | 64 | static int domparams_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl) |
13aa5d29 | 65 | { |
13aa5d29 RL |
66 | const BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL; |
67 | ||
68 | if (dsa == NULL) | |
69 | return 0; | |
70 | ||
71 | DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g); | |
1640d48c RL |
72 | if (dsa_p != NULL |
73 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, dsa_p)) | |
13aa5d29 | 74 | return 0; |
1640d48c RL |
75 | if (dsa_q != NULL |
76 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, dsa_q)) | |
13aa5d29 | 77 | return 0; |
1640d48c RL |
78 | if (dsa_g != NULL |
79 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, dsa_g)) | |
13aa5d29 RL |
80 | return 0; |
81 | ||
82 | return 1; | |
83 | } | |
84 | ||
073f59c4 RL |
85 | static int params_to_key(DSA *dsa, const OSSL_PARAM params[]) |
86 | { | |
87 | const OSSL_PARAM *param_priv_key, *param_pub_key; | |
88 | BIGNUM *priv_key = NULL, *pub_key = NULL; | |
89 | ||
90 | if (dsa == NULL) | |
91 | return 0; | |
92 | ||
93 | if (!params_to_domparams(dsa, params)) | |
94 | return 0; | |
95 | ||
4889dadc MC |
96 | param_priv_key = |
97 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY); | |
98 | param_pub_key = | |
99 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PUB_KEY); | |
100 | ||
101 | /* | |
102 | * DSA documentation says that a public key must be present if a private key | |
103 | * is. | |
104 | */ | |
105 | if (param_priv_key != NULL && param_pub_key == NULL) | |
106 | return 0; | |
107 | ||
073f59c4 RL |
108 | if ((param_priv_key != NULL |
109 | && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) | |
4889dadc MC |
110 | || (param_pub_key != NULL |
111 | && !OSSL_PARAM_get_BN(param_pub_key, &pub_key))) | |
112 | goto err; | |
113 | ||
4889dadc MC |
114 | if (pub_key != NULL && !DSA_set0_key(dsa, pub_key, priv_key)) |
115 | goto err; | |
4889dadc MC |
116 | |
117 | return 1; | |
118 | ||
119 | err: | |
4889dadc MC |
120 | BN_free(priv_key); |
121 | BN_free(pub_key); | |
122 | return 0; | |
123 | } | |
124 | ||
1640d48c | 125 | static int key_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl) |
13aa5d29 | 126 | { |
13aa5d29 RL |
127 | const BIGNUM *priv_key = NULL, *pub_key = NULL; |
128 | ||
129 | if (dsa == NULL) | |
130 | return 0; | |
1640d48c | 131 | if (!domparams_to_params(dsa, tmpl)) |
13aa5d29 RL |
132 | return 0; |
133 | ||
134 | DSA_get0_key(dsa, &pub_key, &priv_key); | |
1640d48c RL |
135 | if (priv_key != NULL |
136 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY, priv_key)) | |
13aa5d29 | 137 | return 0; |
1640d48c RL |
138 | if (pub_key != NULL |
139 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY, pub_key)) | |
13aa5d29 RL |
140 | return 0; |
141 | ||
142 | return 1; | |
143 | } | |
144 | ||
8dd5c603 | 145 | static void *dsa_newdata(void *provctx) |
073f59c4 | 146 | { |
8dd5c603 | 147 | return DSA_new(); |
073f59c4 RL |
148 | } |
149 | ||
8dd5c603 | 150 | static void dsa_freedata(void *keydata) |
13aa5d29 | 151 | { |
8dd5c603 RL |
152 | DSA_free(keydata); |
153 | } | |
1640d48c | 154 | |
8dd5c603 RL |
155 | static int dsa_has(void *keydata, int selection) |
156 | { | |
157 | DSA *dsa = keydata; | |
158 | int ok = 0; | |
159 | ||
160 | if ((selection & DSA_POSSIBLE_SELECTIONS) != 0) | |
161 | ok = 1; | |
162 | ||
163 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) | |
164 | ok = ok && (DSA_get0_pub_key(dsa) != NULL); | |
165 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) | |
166 | ok = ok && (DSA_get0_priv_key(dsa) != NULL); | |
167 | if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) | |
168 | ok = ok && (DSA_get0_p(dsa) != NULL && DSA_get0_g(dsa) != NULL); | |
169 | return ok; | |
13aa5d29 RL |
170 | } |
171 | ||
8dd5c603 | 172 | static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[]) |
4889dadc | 173 | { |
8dd5c603 RL |
174 | DSA *dsa = keydata; |
175 | int ok = 0; | |
176 | ||
177 | if (dsa == NULL) | |
178 | return 0; | |
179 | ||
180 | if ((selection & DSA_POSSIBLE_SELECTIONS) != 0) | |
181 | ok = 1; | |
182 | ||
183 | if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) | |
184 | ok = ok && params_to_domparams(dsa, params); | |
185 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) | |
186 | ok = ok && params_to_key(dsa, params); | |
187 | ||
188 | return ok; | |
4889dadc MC |
189 | } |
190 | ||
8dd5c603 RL |
191 | static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, |
192 | void *cbarg) | |
13aa5d29 | 193 | { |
8dd5c603 | 194 | DSA *dsa = keydata; |
1640d48c RL |
195 | OSSL_PARAM_BLD tmpl; |
196 | OSSL_PARAM *params = NULL; | |
8dd5c603 RL |
197 | int ok = 1; |
198 | ||
199 | if (dsa == NULL) | |
200 | return 0; | |
1640d48c RL |
201 | |
202 | ossl_param_bld_init(&tmpl); | |
8dd5c603 RL |
203 | |
204 | if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) | |
205 | ok = ok && domparams_to_params(dsa, &tmpl); | |
206 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) | |
207 | ok = ok && key_to_params(dsa, &tmpl); | |
208 | ||
209 | if (!ok | |
1640d48c RL |
210 | || (params = ossl_param_bld_to_param(&tmpl)) == NULL) |
211 | return 0; | |
8dd5c603 RL |
212 | |
213 | ok = param_cb(params, cbarg); | |
1640d48c | 214 | ossl_param_bld_free(params); |
8dd5c603 | 215 | return ok; |
13aa5d29 RL |
216 | } |
217 | ||
273a67e3 RL |
218 | /* IMEXPORT = IMPORT + EXPORT */ |
219 | ||
220 | # define DSA_IMEXPORTABLE_PARAMETERS \ | |
221 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \ | |
222 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \ | |
223 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0) | |
224 | # define DSA_IMEXPORTABLE_PUBLIC_KEY \ | |
225 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_DSA_PUB_KEY, NULL, 0) | |
226 | # define DSA_IMEXPORTABLE_PRIVATE_KEY \ | |
227 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_DSA_PRIV_KEY, NULL, 0) | |
228 | static const OSSL_PARAM dsa_all_types[] = { | |
229 | DSA_IMEXPORTABLE_PARAMETERS, | |
230 | DSA_IMEXPORTABLE_PUBLIC_KEY, | |
231 | DSA_IMEXPORTABLE_PRIVATE_KEY, | |
232 | OSSL_PARAM_END | |
233 | }; | |
234 | static const OSSL_PARAM dsa_parameter_types[] = { | |
235 | DSA_IMEXPORTABLE_PARAMETERS, | |
236 | OSSL_PARAM_END | |
237 | }; | |
238 | static const OSSL_PARAM dsa_key_types[] = { | |
239 | DSA_IMEXPORTABLE_PUBLIC_KEY, | |
240 | DSA_IMEXPORTABLE_PRIVATE_KEY, | |
241 | OSSL_PARAM_END | |
242 | }; | |
243 | static const OSSL_PARAM *dsa_types[] = { | |
244 | NULL, /* Index 0 = none of them */ | |
245 | dsa_parameter_types, /* Index 1 = parameter types */ | |
246 | dsa_key_types, /* Index 2 = key types */ | |
247 | dsa_all_types /* Index 3 = 1 + 2 */ | |
248 | }; | |
249 | ||
250 | static const OSSL_PARAM *dsa_imexport_types(int selection) | |
251 | { | |
252 | int type_select = 0; | |
253 | ||
254 | if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) | |
255 | type_select += 1; | |
256 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) | |
257 | type_select += 2; | |
258 | return dsa_types[type_select]; | |
259 | } | |
260 | ||
261 | static const OSSL_PARAM *dsa_import_types(int selection) | |
262 | { | |
263 | return dsa_imexport_types(selection); | |
264 | } | |
265 | ||
266 | static const OSSL_PARAM *dsa_export_types(int selection) | |
267 | { | |
268 | return dsa_imexport_types(selection); | |
269 | } | |
270 | ||
8dd5c603 | 271 | static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[]) |
9e5aaf78 RL |
272 | { |
273 | DSA *dsa = key; | |
274 | OSSL_PARAM *p; | |
275 | ||
276 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL | |
277 | && !OSSL_PARAM_set_int(p, DSA_bits(dsa))) | |
278 | return 0; | |
279 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL | |
280 | && !OSSL_PARAM_set_int(p, DSA_security_bits(dsa))) | |
281 | return 0; | |
282 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL | |
283 | && !OSSL_PARAM_set_int(p, DSA_size(dsa))) | |
284 | return 0; | |
8baa49ae RL |
285 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL |
286 | && !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD)) | |
287 | return 0; | |
9e5aaf78 RL |
288 | return 1; |
289 | } | |
290 | ||
273a67e3 RL |
291 | static const OSSL_PARAM dsa_params[] = { |
292 | OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), | |
293 | OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), | |
294 | OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), | |
295 | OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), | |
296 | OSSL_PARAM_END | |
297 | }; | |
298 | ||
299 | static const OSSL_PARAM *dsa_gettable_params(void) | |
300 | { | |
301 | return dsa_params; | |
302 | } | |
303 | ||
4889dadc | 304 | const OSSL_DISPATCH dsa_keymgmt_functions[] = { |
8dd5c603 RL |
305 | { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata }, |
306 | { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata }, | |
273a67e3 RL |
307 | { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dsa_get_params }, |
308 | { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dsa_gettable_params }, | |
8dd5c603 RL |
309 | { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dsa_has }, |
310 | { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dsa_import }, | |
273a67e3 | 311 | { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types }, |
8dd5c603 | 312 | { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export }, |
273a67e3 | 313 | { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types }, |
4889dadc MC |
314 | { 0, NULL } |
315 | }; |