]>
Commit | Line | Data |
---|---|---|
0abae163 | 1 | /* |
fecb3aae | 2 | * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. |
0abae163 RL |
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 | ||
52c8535a 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 | ||
0abae163 | 16 | #include <openssl/core_names.h> |
cf333799 | 17 | #include <openssl/err.h> |
3f773c91 TM |
18 | #ifndef FIPS_MODULE |
19 | # include <openssl/x509.h> | |
20 | #endif | |
0abae163 | 21 | #include "crypto/dsa.h" |
4a9fe33c | 22 | #include "dsa_local.h" |
0abae163 RL |
23 | |
24 | /* | |
25 | * The intention with the "backend" source file is to offer backend support | |
26 | * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider | |
27 | * implementations alike. | |
28 | */ | |
29 | ||
944f822a | 30 | int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[], |
31 | int include_private) | |
0abae163 | 32 | { |
944f822a | 33 | const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; |
0abae163 RL |
34 | BIGNUM *priv_key = NULL, *pub_key = NULL; |
35 | ||
36 | if (dsa == NULL) | |
37 | return 0; | |
38 | ||
944f822a | 39 | if (include_private) { |
40 | param_priv_key = | |
41 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); | |
42 | } | |
0abae163 RL |
43 | param_pub_key = |
44 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); | |
45 | ||
46 | /* It's ok if neither half is present */ | |
47 | if (param_priv_key == NULL && param_pub_key == NULL) | |
48 | return 1; | |
49 | ||
0abae163 RL |
50 | if (param_pub_key != NULL && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)) |
51 | goto err; | |
52 | if (param_priv_key != NULL && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) | |
53 | goto err; | |
54 | ||
55 | if (!DSA_set0_key(dsa, pub_key, priv_key)) | |
56 | goto err; | |
57 | ||
58 | return 1; | |
59 | ||
60 | err: | |
61 | BN_clear_free(priv_key); | |
62 | BN_free(pub_key); | |
63 | return 0; | |
64 | } | |
cf333799 | 65 | |
b247113c TM |
66 | int ossl_dsa_is_foreign(const DSA *dsa) |
67 | { | |
68 | #ifndef FIPS_MODULE | |
69 | if (dsa->engine != NULL || DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) | |
70 | return 1; | |
71 | #endif | |
72 | return 0; | |
73 | } | |
74 | ||
4a9fe33c TM |
75 | static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) |
76 | { | |
77 | if (f != NULL && (*out = BN_dup(f)) == NULL) | |
78 | return 0; | |
79 | return 1; | |
80 | } | |
81 | ||
b4f447c0 | 82 | DSA *ossl_dsa_dup(const DSA *dsa, int selection) |
4a9fe33c TM |
83 | { |
84 | DSA *dupkey = NULL; | |
85 | ||
4a9fe33c | 86 | /* Do not try to duplicate foreign DSA keys */ |
b247113c | 87 | if (ossl_dsa_is_foreign(dsa)) |
4a9fe33c | 88 | return NULL; |
4a9fe33c TM |
89 | |
90 | if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) | |
91 | return NULL; | |
92 | ||
b4f447c0 TM |
93 | if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 |
94 | && !ossl_ffc_params_copy(&dupkey->params, &dsa->params)) | |
4a9fe33c TM |
95 | goto err; |
96 | ||
97 | dupkey->flags = dsa->flags; | |
98 | ||
b4f447c0 TM |
99 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 |
100 | && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 | |
101 | || !dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key))) | |
4a9fe33c | 102 | goto err; |
b4f447c0 TM |
103 | |
104 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 | |
105 | && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 | |
106 | || !dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key))) | |
4a9fe33c TM |
107 | goto err; |
108 | ||
109 | #ifndef FIPS_MODULE | |
110 | if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA, | |
111 | &dupkey->ex_data, &dsa->ex_data)) | |
112 | goto err; | |
113 | #endif | |
114 | ||
115 | return dupkey; | |
116 | ||
117 | err: | |
118 | DSA_free(dupkey); | |
119 | return NULL; | |
120 | } | |
121 | ||
cf333799 RL |
122 | #ifndef FIPS_MODULE |
123 | DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, | |
124 | OSSL_LIB_CTX *libctx, const char *propq) | |
125 | { | |
126 | const unsigned char *p, *pm; | |
127 | int pklen, pmlen; | |
128 | int ptype; | |
129 | const void *pval; | |
130 | const ASN1_STRING *pstr; | |
131 | const X509_ALGOR *palg; | |
132 | ASN1_INTEGER *privkey = NULL; | |
133 | const BIGNUM *dsa_p, *dsa_g; | |
134 | BIGNUM *dsa_pubkey = NULL, *dsa_privkey = NULL; | |
135 | BN_CTX *ctx = NULL; | |
136 | ||
137 | DSA *dsa = NULL; | |
138 | ||
139 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) | |
140 | return 0; | |
141 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | |
142 | ||
143 | if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) | |
144 | goto decerr; | |
145 | if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) | |
146 | goto decerr; | |
147 | ||
148 | pstr = pval; | |
149 | pm = pstr->data; | |
150 | pmlen = pstr->length; | |
151 | if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) | |
152 | goto decerr; | |
153 | /* We have parameters now set private key */ | |
154 | if ((dsa_privkey = BN_secure_new()) == NULL | |
155 | || !ASN1_INTEGER_to_BN(privkey, dsa_privkey)) { | |
156 | ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); | |
157 | goto dsaerr; | |
158 | } | |
159 | /* Calculate public key */ | |
160 | if ((dsa_pubkey = BN_new()) == NULL) { | |
161 | ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); | |
162 | goto dsaerr; | |
163 | } | |
164 | if ((ctx = BN_CTX_new()) == NULL) { | |
165 | ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); | |
166 | goto dsaerr; | |
167 | } | |
168 | ||
169 | dsa_p = DSA_get0_p(dsa); | |
170 | dsa_g = DSA_get0_g(dsa); | |
171 | BN_set_flags(dsa_privkey, BN_FLG_CONSTTIME); | |
172 | if (!BN_mod_exp(dsa_pubkey, dsa_g, dsa_privkey, dsa_p, ctx)) { | |
173 | ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); | |
174 | goto dsaerr; | |
175 | } | |
176 | DSA_set0_key(dsa, dsa_pubkey, dsa_privkey); | |
177 | ||
178 | goto done; | |
179 | ||
180 | decerr: | |
181 | ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); | |
182 | dsaerr: | |
183 | BN_free(dsa_privkey); | |
184 | BN_free(dsa_pubkey); | |
185 | DSA_free(dsa); | |
186 | dsa = NULL; | |
187 | done: | |
188 | BN_CTX_free(ctx); | |
189 | ASN1_STRING_clear_free(privkey); | |
190 | return dsa; | |
191 | } | |
192 | #endif |