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