40995eb4a89d62701c5f52f8f2052571e946f398
[openssl.git] / providers / implementations / keymgmt / dsa_kmgmt.c
1 /*
2  * Copyright 2019-2020 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 /*
11  * DSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <openssl/core_numbers.h>
17 #include <openssl/core_names.h>
18 #include <openssl/bn.h>
19 #include <openssl/params.h>
20 #include "prov/implementations.h"
21 #include "prov/providercommon.h"
22 #include "prov/provider_ctx.h"
23 #include "crypto/dsa.h"
24 #include "openssl/param_build.h"
25
26 static OSSL_OP_keymgmt_new_fn dsa_newdata;
27 static OSSL_OP_keymgmt_free_fn dsa_freedata;
28 static OSSL_OP_keymgmt_get_params_fn dsa_get_params;
29 static OSSL_OP_keymgmt_gettable_params_fn dsa_gettable_params;
30 static OSSL_OP_keymgmt_has_fn dsa_has;
31 static OSSL_OP_keymgmt_match_fn dsa_match;
32 static OSSL_OP_keymgmt_validate_fn dsa_validate;
33 static OSSL_OP_keymgmt_import_fn dsa_import;
34 static OSSL_OP_keymgmt_import_types_fn dsa_import_types;
35 static OSSL_OP_keymgmt_export_fn dsa_export;
36 static OSSL_OP_keymgmt_export_types_fn dsa_export_types;
37
38 #define DSA_DEFAULT_MD "SHA256"
39 #define DSA_POSSIBLE_SELECTIONS                 \
40     (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
41
42 static int domparams_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl)
43 {
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);
50     if (dsa_p != NULL
51         && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, dsa_p))
52         return 0;
53     if (dsa_q != NULL
54         && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, dsa_q))
55         return 0;
56     if (dsa_g != NULL
57         && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, dsa_g))
58         return 0;
59
60     return 1;
61 }
62
63 static int key_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl)
64 {
65     const BIGNUM *priv_key = NULL, *pub_key = NULL;
66
67     if (dsa == NULL)
68         return 0;
69     if (!domparams_to_params(dsa, tmpl))
70         return 0;
71
72     DSA_get0_key(dsa, &pub_key, &priv_key);
73     if (priv_key != NULL
74         && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, priv_key))
75         return 0;
76     if (pub_key != NULL
77         && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
78         return 0;
79
80     return 1;
81 }
82
83 static void *dsa_newdata(void *provctx)
84 {
85     return dsa_new_with_ctx(PROV_LIBRARY_CONTEXT_OF(provctx));
86 }
87
88 static void dsa_freedata(void *keydata)
89 {
90     DSA_free(keydata);
91 }
92
93 static int dsa_has(void *keydata, int selection)
94 {
95     DSA *dsa = keydata;
96     int ok = 0;
97
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     }
109     return ok;
110 }
111
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
133 static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
134 {
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)
145         ok = ok && ffc_fromdata(dsa_get0_params(dsa), params);
146     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
147         ok = ok && dsa_key_fromdata(dsa, params);
148
149     return ok;
150 }
151
152 static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
153                       void *cbarg)
154 {
155     DSA *dsa = keydata;
156     OSSL_PARAM_BLD tmpl;
157     OSSL_PARAM *params = NULL;
158     int ok = 1;
159
160     if (dsa == NULL)
161         return 0;
162
163     OSSL_PARAM_BLD_init(&tmpl);
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
171         || (params = OSSL_PARAM_BLD_to_param(&tmpl)) == NULL)
172         return 0;
173
174     ok = param_cb(params, cbarg);
175     OSSL_PARAM_BLD_free(params);
176     return ok;
177 }
178
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                    \
186     OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
187 # define DSA_IMEXPORTABLE_PRIVATE_KEY                   \
188     OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
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
232 static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[])
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;
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;
249     return 1;
250 }
251
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
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
314 const OSSL_DISPATCH dsa_keymgmt_functions[] = {
315     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata },
316     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata },
317     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dsa_get_params },
318     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dsa_gettable_params },
319     { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dsa_has },
320     { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dsa_match },
321     { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dsa_validate },
322     { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dsa_import },
323     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types },
324     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export },
325     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types },
326     { 0, NULL }
327 };