/src/boringssl/crypto/evp/p_dsa_asn1.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project |
2 | | * 2006. |
3 | | */ |
4 | | /* ==================================================================== |
5 | | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. |
6 | | * |
7 | | * Redistribution and use in source and binary forms, with or without |
8 | | * modification, are permitted provided that the following conditions |
9 | | * are met: |
10 | | * |
11 | | * 1. Redistributions of source code must retain the above copyright |
12 | | * notice, this list of conditions and the following disclaimer. |
13 | | * |
14 | | * 2. Redistributions in binary form must reproduce the above copyright |
15 | | * notice, this list of conditions and the following disclaimer in |
16 | | * the documentation and/or other materials provided with the |
17 | | * distribution. |
18 | | * |
19 | | * 3. All advertising materials mentioning features or use of this |
20 | | * software must display the following acknowledgment: |
21 | | * "This product includes software developed by the OpenSSL Project |
22 | | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
23 | | * |
24 | | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
25 | | * endorse or promote products derived from this software without |
26 | | * prior written permission. For written permission, please contact |
27 | | * licensing@OpenSSL.org. |
28 | | * |
29 | | * 5. Products derived from this software may not be called "OpenSSL" |
30 | | * nor may "OpenSSL" appear in their names without prior written |
31 | | * permission of the OpenSSL Project. |
32 | | * |
33 | | * 6. Redistributions of any form whatsoever must retain the following |
34 | | * acknowledgment: |
35 | | * "This product includes software developed by the OpenSSL Project |
36 | | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
37 | | * |
38 | | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
39 | | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
40 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
41 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
42 | | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
43 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
44 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
45 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
46 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
47 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
48 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
49 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
50 | | * ==================================================================== |
51 | | * |
52 | | * This product includes cryptographic software written by Eric Young |
53 | | * (eay@cryptsoft.com). This product includes software written by Tim |
54 | | * Hudson (tjh@cryptsoft.com). */ |
55 | | |
56 | | #include <openssl/evp.h> |
57 | | |
58 | | #include <openssl/digest.h> |
59 | | #include <openssl/bn.h> |
60 | | #include <openssl/bytestring.h> |
61 | | #include <openssl/dsa.h> |
62 | | #include <openssl/err.h> |
63 | | |
64 | | #include "../dsa/internal.h" |
65 | | #include "internal.h" |
66 | | |
67 | | |
68 | 0 | static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { |
69 | | // See RFC 3279, section 2.3.2. |
70 | | |
71 | | // Parameters may or may not be present. |
72 | 0 | DSA *dsa; |
73 | 0 | if (CBS_len(params) == 0) { |
74 | 0 | dsa = DSA_new(); |
75 | 0 | if (dsa == NULL) { |
76 | 0 | return 0; |
77 | 0 | } |
78 | 0 | } else { |
79 | 0 | dsa = DSA_parse_parameters(params); |
80 | 0 | if (dsa == NULL || CBS_len(params) != 0) { |
81 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); |
82 | 0 | goto err; |
83 | 0 | } |
84 | 0 | } |
85 | | |
86 | 0 | dsa->pub_key = BN_new(); |
87 | 0 | if (dsa->pub_key == NULL) { |
88 | 0 | goto err; |
89 | 0 | } |
90 | | |
91 | 0 | if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || |
92 | 0 | CBS_len(key) != 0) { |
93 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); |
94 | 0 | goto err; |
95 | 0 | } |
96 | | |
97 | 0 | EVP_PKEY_assign_DSA(out, dsa); |
98 | 0 | return 1; |
99 | | |
100 | 0 | err: |
101 | 0 | DSA_free(dsa); |
102 | 0 | return 0; |
103 | 0 | } |
104 | | |
105 | 0 | static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { |
106 | 0 | const DSA *dsa = key->pkey; |
107 | 0 | const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL; |
108 | | |
109 | | // See RFC 5480, section 2. |
110 | 0 | CBB spki, algorithm, oid, key_bitstring; |
111 | 0 | if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || |
112 | 0 | !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || |
113 | 0 | !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || |
114 | 0 | !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || |
115 | 0 | (has_params && |
116 | 0 | !DSA_marshal_parameters(&algorithm, dsa)) || |
117 | 0 | !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || |
118 | 0 | !CBB_add_u8(&key_bitstring, 0 /* padding */) || |
119 | 0 | !BN_marshal_asn1(&key_bitstring, dsa->pub_key) || |
120 | 0 | !CBB_flush(out)) { |
121 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); |
122 | 0 | return 0; |
123 | 0 | } |
124 | | |
125 | 0 | return 1; |
126 | 0 | } |
127 | | |
128 | 0 | static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { |
129 | | // See PKCS#11, v2.40, section 2.5. |
130 | | |
131 | | // Decode parameters. |
132 | 0 | BN_CTX *ctx = NULL; |
133 | 0 | DSA *dsa = DSA_parse_parameters(params); |
134 | 0 | if (dsa == NULL || CBS_len(params) != 0) { |
135 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); |
136 | 0 | goto err; |
137 | 0 | } |
138 | | |
139 | 0 | dsa->priv_key = BN_new(); |
140 | 0 | if (dsa->priv_key == NULL) { |
141 | 0 | goto err; |
142 | 0 | } |
143 | 0 | if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || |
144 | 0 | CBS_len(key) != 0) { |
145 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); |
146 | 0 | goto err; |
147 | 0 | } |
148 | | |
149 | | // To avoid DoS attacks when importing private keys, check bounds on |dsa|. |
150 | | // This bounds |dsa->priv_key| against |dsa->q| and bounds |dsa->q|'s bit |
151 | | // width. |
152 | 0 | if (!dsa_check_key(dsa)) { |
153 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); |
154 | 0 | goto err; |
155 | 0 | } |
156 | | |
157 | | // Calculate the public key. |
158 | 0 | ctx = BN_CTX_new(); |
159 | 0 | dsa->pub_key = BN_new(); |
160 | 0 | if (ctx == NULL || dsa->pub_key == NULL || |
161 | 0 | !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, |
162 | 0 | ctx, NULL)) { |
163 | 0 | goto err; |
164 | 0 | } |
165 | | |
166 | 0 | BN_CTX_free(ctx); |
167 | 0 | EVP_PKEY_assign_DSA(out, dsa); |
168 | 0 | return 1; |
169 | | |
170 | 0 | err: |
171 | 0 | BN_CTX_free(ctx); |
172 | 0 | DSA_free(dsa); |
173 | 0 | return 0; |
174 | 0 | } |
175 | | |
176 | 0 | static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { |
177 | 0 | const DSA *dsa = key->pkey; |
178 | 0 | if (dsa == NULL || dsa->priv_key == NULL) { |
179 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); |
180 | 0 | return 0; |
181 | 0 | } |
182 | | |
183 | | // See PKCS#11, v2.40, section 2.5. |
184 | 0 | CBB pkcs8, algorithm, oid, private_key; |
185 | 0 | if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || |
186 | 0 | !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || |
187 | 0 | !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || |
188 | 0 | !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || |
189 | 0 | !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || |
190 | 0 | !DSA_marshal_parameters(&algorithm, dsa) || |
191 | 0 | !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || |
192 | 0 | !BN_marshal_asn1(&private_key, dsa->priv_key) || |
193 | 0 | !CBB_flush(out)) { |
194 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); |
195 | 0 | return 0; |
196 | 0 | } |
197 | | |
198 | 0 | return 1; |
199 | 0 | } |
200 | | |
201 | 0 | static int int_dsa_size(const EVP_PKEY *pkey) { |
202 | 0 | const DSA *dsa = pkey->pkey; |
203 | 0 | return DSA_size(dsa); |
204 | 0 | } |
205 | | |
206 | 0 | static int dsa_bits(const EVP_PKEY *pkey) { |
207 | 0 | const DSA *dsa = pkey->pkey; |
208 | 0 | return BN_num_bits(DSA_get0_p(dsa)); |
209 | 0 | } |
210 | | |
211 | 0 | static int dsa_missing_parameters(const EVP_PKEY *pkey) { |
212 | 0 | const DSA *dsa = pkey->pkey; |
213 | 0 | if (DSA_get0_p(dsa) == NULL || DSA_get0_q(dsa) == NULL || |
214 | 0 | DSA_get0_g(dsa) == NULL) { |
215 | 0 | return 1; |
216 | 0 | } |
217 | 0 | return 0; |
218 | 0 | } |
219 | | |
220 | 0 | static int dup_bn_into(BIGNUM **out, BIGNUM *src) { |
221 | 0 | BIGNUM *a; |
222 | |
|
223 | 0 | a = BN_dup(src); |
224 | 0 | if (a == NULL) { |
225 | 0 | return 0; |
226 | 0 | } |
227 | 0 | BN_free(*out); |
228 | 0 | *out = a; |
229 | |
|
230 | 0 | return 1; |
231 | 0 | } |
232 | | |
233 | 0 | static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { |
234 | 0 | DSA *to_dsa = to->pkey; |
235 | 0 | const DSA *from_dsa = from->pkey; |
236 | 0 | if (!dup_bn_into(&to_dsa->p, from_dsa->p) || |
237 | 0 | !dup_bn_into(&to_dsa->q, from_dsa->q) || |
238 | 0 | !dup_bn_into(&to_dsa->g, from_dsa->g)) { |
239 | 0 | return 0; |
240 | 0 | } |
241 | | |
242 | 0 | return 1; |
243 | 0 | } |
244 | | |
245 | 0 | static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { |
246 | 0 | const DSA *a_dsa = a->pkey; |
247 | 0 | const DSA *b_dsa = b->pkey; |
248 | 0 | return BN_cmp(DSA_get0_p(a_dsa), DSA_get0_p(b_dsa)) == 0 && |
249 | 0 | BN_cmp(DSA_get0_q(a_dsa), DSA_get0_q(b_dsa)) == 0 && |
250 | 0 | BN_cmp(DSA_get0_g(a_dsa), DSA_get0_g(b_dsa)) == 0; |
251 | 0 | } |
252 | | |
253 | 0 | static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { |
254 | 0 | const DSA *a_dsa = a->pkey; |
255 | 0 | const DSA *b_dsa = b->pkey; |
256 | 0 | return BN_cmp(DSA_get0_pub_key(b_dsa), DSA_get0_pub_key(a_dsa)) == 0; |
257 | 0 | } |
258 | | |
259 | 0 | static void int_dsa_free(EVP_PKEY *pkey) { |
260 | 0 | DSA_free(pkey->pkey); |
261 | 0 | pkey->pkey = NULL; |
262 | 0 | } |
263 | | |
264 | | const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { |
265 | | EVP_PKEY_DSA, |
266 | | // 1.2.840.10040.4.1 |
267 | | {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, |
268 | | 7, |
269 | | |
270 | | /*pkey_method=*/NULL, |
271 | | |
272 | | dsa_pub_decode, |
273 | | dsa_pub_encode, |
274 | | dsa_pub_cmp, |
275 | | |
276 | | dsa_priv_decode, |
277 | | dsa_priv_encode, |
278 | | |
279 | | /*set_priv_raw=*/NULL, |
280 | | /*set_pub_raw=*/NULL, |
281 | | /*get_priv_raw=*/NULL, |
282 | | /*get_pub_raw=*/NULL, |
283 | | /*set1_tls_encodedpoint=*/NULL, |
284 | | /*get1_tls_encodedpoint=*/NULL, |
285 | | |
286 | | /*pkey_opaque=*/NULL, |
287 | | |
288 | | int_dsa_size, |
289 | | dsa_bits, |
290 | | |
291 | | dsa_missing_parameters, |
292 | | dsa_copy_parameters, |
293 | | dsa_cmp_parameters, |
294 | | |
295 | | int_dsa_free, |
296 | | }; |
297 | | |
298 | 0 | int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) { |
299 | | // BoringSSL does not support DSA in |EVP_PKEY_CTX|. |
300 | 0 | OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
301 | 0 | return 0; |
302 | 0 | } |
303 | | |
304 | 0 | int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits) { |
305 | | // BoringSSL does not support DSA in |EVP_PKEY_CTX|. |
306 | 0 | OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
307 | 0 | return 0; |
308 | 0 | } |
309 | | |
310 | 0 | int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { |
311 | 0 | if (EVP_PKEY_assign_DSA(pkey, key)) { |
312 | 0 | DSA_up_ref(key); |
313 | 0 | return 1; |
314 | 0 | } |
315 | 0 | return 0; |
316 | 0 | } |
317 | | |
318 | 0 | int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { |
319 | 0 | evp_pkey_set_method(pkey, &dsa_asn1_meth); |
320 | 0 | pkey->pkey = key; |
321 | 0 | return key != NULL; |
322 | 0 | } |
323 | | |
324 | 0 | DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { |
325 | 0 | if (pkey->type != EVP_PKEY_DSA) { |
326 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); |
327 | 0 | return NULL; |
328 | 0 | } |
329 | 0 | return pkey->pkey; |
330 | 0 | } |
331 | | |
332 | 0 | DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) { |
333 | 0 | DSA *dsa = EVP_PKEY_get0_DSA(pkey); |
334 | 0 | if (dsa != NULL) { |
335 | 0 | DSA_up_ref(dsa); |
336 | 0 | } |
337 | 0 | return dsa; |
338 | 0 | } |