xref: /openbsd-src/lib/libcrypto/dsa/dsa_ameth.c (revision e5157e49389faebcb42b7237d55fbf096d9c2523)
1 /* $OpenBSD: dsa_ameth.c,v 1.14 2014/07/13 12:45:01 miod Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2006.
4  */
5 /* ====================================================================
6  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <stdio.h>
60 
61 #include <openssl/opensslconf.h>
62 
63 #include <openssl/asn1.h>
64 #include <openssl/bn.h>
65 #include <openssl/dsa.h>
66 #include <openssl/err.h>
67 #include <openssl/x509.h>
68 
69 #ifndef OPENSSL_NO_CMS
70 #include <openssl/cms.h>
71 #endif
72 
73 #include "asn1_locl.h"
74 
75 static int
76 dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
77 {
78 	const unsigned char *p, *pm;
79 	int pklen, pmlen;
80 	int ptype;
81 	void *pval;
82 	ASN1_STRING *pstr;
83 	X509_ALGOR *palg;
84 	ASN1_INTEGER *public_key = NULL;
85 
86 	DSA *dsa = NULL;
87 
88 	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
89 		return 0;
90 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
91 
92 	if (ptype == V_ASN1_SEQUENCE) {
93 		pstr = pval;
94 		pm = pstr->data;
95 		pmlen = pstr->length;
96 
97 		if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) {
98 			DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
99 			goto err;
100 		}
101 	} else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
102 		if (!(dsa = DSA_new())) {
103 			DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
104 			goto err;
105 			}
106 	} else {
107 		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
108 		goto err;
109 	}
110 
111 	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) {
112 		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
113 		goto err;
114 	}
115 
116 	if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
117 		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
118 		goto err;
119 	}
120 
121 	ASN1_INTEGER_free(public_key);
122 	EVP_PKEY_assign_DSA(pkey, dsa);
123 	return 1;
124 
125 err:
126 	if (public_key)
127 		ASN1_INTEGER_free(public_key);
128 	DSA_free(dsa);
129 	return 0;
130 }
131 
132 static int
133 dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
134 {
135 	DSA *dsa;
136 	void *pval = NULL;
137 	int ptype;
138 	unsigned char *penc = NULL;
139 	int penclen;
140 
141 	dsa = pkey->pkey.dsa;
142 	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
143 		ASN1_STRING *str;
144 
145 		str = ASN1_STRING_new();
146 		str->length = i2d_DSAparams(dsa, &str->data);
147 		if (str->length <= 0) {
148 			DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
149 			goto err;
150 		}
151 		pval = str;
152 		ptype = V_ASN1_SEQUENCE;
153 	} else
154 		ptype = V_ASN1_UNDEF;
155 
156 	dsa->write_params = 0;
157 
158 	penclen = i2d_DSAPublicKey(dsa, &penc);
159 
160 	if (penclen <= 0) {
161 		DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
162 		goto err;
163 	}
164 
165 	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
166 	    penc, penclen))
167 		return 1;
168 
169 err:
170 	free(penc);
171 	ASN1_STRING_free(pval);
172 
173 	return 0;
174 }
175 
176 /* In PKCS#8 DSA: you just get a private key integer and parameters in the
177  * AlgorithmIdentifier the pubkey must be recalculated.
178  */
179 
180 static int
181 dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
182 {
183 	const unsigned char *p, *pm;
184 	int pklen, pmlen;
185 	int ptype;
186 	void *pval;
187 	ASN1_STRING *pstr;
188 	X509_ALGOR *palg;
189 	ASN1_INTEGER *privkey = NULL;
190 	BN_CTX *ctx = NULL;
191 	STACK_OF(ASN1_TYPE) *ndsa = NULL;
192 	DSA *dsa = NULL;
193 
194 	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
195 		return 0;
196 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
197 
198 	/* Check for broken DSA PKCS#8, UGH! */
199 	if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
200 		ASN1_TYPE *t1, *t2;
201 	    	if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)))
202 			goto decerr;
203 		if (sk_ASN1_TYPE_num(ndsa) != 2)
204 			goto decerr;
205 		/*
206 		 * Handle Two broken types:
207 	    	 * SEQUENCE {parameters, priv_key}
208 		 * SEQUENCE {pub_key, priv_key}
209 		 */
210 
211 		t1 = sk_ASN1_TYPE_value(ndsa, 0);
212 		t2 = sk_ASN1_TYPE_value(ndsa, 1);
213 		if (t1->type == V_ASN1_SEQUENCE) {
214 			p8->broken = PKCS8_EMBEDDED_PARAM;
215 			pval = t1->value.ptr;
216 		} else if (ptype == V_ASN1_SEQUENCE)
217 			p8->broken = PKCS8_NS_DB;
218 		else
219 			goto decerr;
220 
221 		if (t2->type != V_ASN1_INTEGER)
222 			goto decerr;
223 
224 		privkey = t2->value.integer;
225 	} else {
226 		const unsigned char *q = p;
227 
228 		if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
229 			goto decerr;
230 		if (privkey->type == V_ASN1_NEG_INTEGER) {
231 			p8->broken = PKCS8_NEG_PRIVKEY;
232 			ASN1_INTEGER_free(privkey);
233 			if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen)))
234 				goto decerr;
235 		}
236 		if (ptype != V_ASN1_SEQUENCE)
237 			goto decerr;
238 	}
239 
240 	pstr = pval;
241 	pm = pstr->data;
242 	pmlen = pstr->length;
243 	if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
244 		goto decerr;
245 	/* We have parameters now set private key */
246 	if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
247 		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
248 		goto dsaerr;
249 	}
250 	/* Calculate public key */
251 	if (!(dsa->pub_key = BN_new())) {
252 		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
253 		goto dsaerr;
254 	}
255 	if (!(ctx = BN_CTX_new())) {
256 		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
257 		goto dsaerr;
258 	}
259 
260 	if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
261 		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
262 		goto dsaerr;
263 	}
264 
265 	EVP_PKEY_assign_DSA(pkey, dsa);
266 	BN_CTX_free(ctx);
267 	if (ndsa)
268 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
269 	else
270 		ASN1_INTEGER_free(privkey);
271 
272 	return 1;
273 
274 decerr:
275 	DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
276 dsaerr:
277 	BN_CTX_free(ctx);
278 	if (ndsa)
279 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
280 	else
281 		ASN1_INTEGER_free(privkey);
282 	DSA_free(dsa);
283 	return 0;
284 }
285 
286 static int
287 dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
288 {
289 	ASN1_STRING *params = NULL;
290 	ASN1_INTEGER *prkey = NULL;
291 	unsigned char *dp = NULL;
292 	int dplen;
293 
294 	params = ASN1_STRING_new();
295 	if (!params) {
296 		DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
297 		goto err;
298 	}
299 
300 	params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
301 	if (params->length <= 0) {
302 		DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
303 		goto err;
304 	}
305 	params->type = V_ASN1_SEQUENCE;
306 
307 	/* Get private key into integer */
308 	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
309 	if (!prkey) {
310 		DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
311 		goto err;
312 	}
313 
314 	dplen = i2d_ASN1_INTEGER(prkey, &dp);
315 
316 	ASN1_INTEGER_free(prkey);
317 	prkey = NULL;
318 
319 	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE,
320 	    params, dp, dplen))
321 		goto err;
322 
323 	return 1;
324 
325 err:
326 	free(dp);
327 	ASN1_STRING_free(params);
328 	ASN1_INTEGER_free(prkey);
329 	return 0;
330 }
331 
332 static int
333 int_dsa_size(const EVP_PKEY *pkey)
334 {
335 	return DSA_size(pkey->pkey.dsa);
336 }
337 
338 static int
339 dsa_bits(const EVP_PKEY *pkey)
340 {
341 	return BN_num_bits(pkey->pkey.dsa->p);
342 }
343 
344 static int
345 dsa_missing_parameters(const EVP_PKEY *pkey)
346 {
347 	DSA *dsa;
348 
349 	dsa = pkey->pkey.dsa;
350 	if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
351 		return 1;
352 	return 0;
353 }
354 
355 static int
356 dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
357 {
358 	BIGNUM *a;
359 
360 	if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
361 		return 0;
362 	BN_free(to->pkey.dsa->p);
363 	to->pkey.dsa->p = a;
364 
365 	if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
366 		return 0;
367 	BN_free(to->pkey.dsa->q);
368 	to->pkey.dsa->q = a;
369 
370 	if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
371 		return 0;
372 	BN_free(to->pkey.dsa->g);
373 	to->pkey.dsa->g = a;
374 	return 1;
375 }
376 
377 static int
378 dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
379 {
380 	if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
381 	    BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
382 	    BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
383 		return 0;
384 	else
385 		return 1;
386 }
387 
388 static int
389 dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
390 {
391 	if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
392 		return 0;
393 	else
394 		return 1;
395 }
396 
397 static void
398 int_dsa_free(EVP_PKEY *pkey)
399 {
400 	DSA_free(pkey->pkey.dsa);
401 }
402 
403 static void
404 update_buflen(const BIGNUM *b, size_t *pbuflen)
405 {
406 	size_t i;
407 
408 	if (!b)
409 		return;
410 	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
411 		*pbuflen = i;
412 }
413 
414 static int
415 do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
416 {
417 	unsigned char *m = NULL;
418 	int ret = 0;
419 	size_t buf_len = 0;
420 	const char *ktype = NULL;
421 	const BIGNUM *priv_key, *pub_key;
422 
423 	if (ptype == 2)
424 		priv_key = x->priv_key;
425 	else
426 		priv_key = NULL;
427 
428 	if (ptype > 0)
429 		pub_key = x->pub_key;
430 	else
431 		pub_key = NULL;
432 
433 	if (ptype == 2)
434 		ktype = "Private-Key";
435 	else if (ptype == 1)
436 		ktype = "Public-Key";
437 	else
438 		ktype = "DSA-Parameters";
439 
440 	update_buflen(x->p, &buf_len);
441 	update_buflen(x->q, &buf_len);
442 	update_buflen(x->g, &buf_len);
443 	update_buflen(priv_key, &buf_len);
444 	update_buflen(pub_key, &buf_len);
445 
446 	m = malloc(buf_len + 10);
447 	if (m == NULL) {
448 		DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE);
449 		goto err;
450 	}
451 
452 	if (priv_key) {
453 		if (!BIO_indent(bp, off, 128))
454 			goto err;
455 		if (BIO_printf(bp, "%s: (%d bit)\n", ktype,
456 		    BN_num_bits(x->p)) <= 0)
457 			goto err;
458 	}
459 
460 	if (!ASN1_bn_print(bp, "priv:", priv_key, m, off))
461 		goto err;
462 	if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off))
463 		goto err;
464 	if (!ASN1_bn_print(bp, "P:   ", x->p, m, off))
465 		goto err;
466 	if (!ASN1_bn_print(bp, "Q:   ", x->q, m, off))
467 		goto err;
468 	if (!ASN1_bn_print(bp, "G:   ", x->g, m, off))
469 		goto err;
470 	ret = 1;
471 err:
472 	free(m);
473 	return(ret);
474 }
475 
476 static int
477 dsa_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
478 {
479 	DSA *dsa;
480 
481 	if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) {
482 		DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
483 		return 0;
484 	}
485 	EVP_PKEY_assign_DSA(pkey, dsa);
486 	return 1;
487 }
488 
489 static int
490 dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
491 {
492 	return i2d_DSAparams(pkey->pkey.dsa, pder);
493 }
494 
495 static int
496 dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
497 {
498 	return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
499 }
500 
501 static int
502 dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
503 {
504 	return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
505 }
506 
507 static int
508 dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
509 {
510 	return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
511 }
512 
513 static int
514 old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
515 {
516 	DSA *dsa;
517 
518 	if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen))) {
519 		DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
520 		return 0;
521 	}
522 	EVP_PKEY_assign_DSA(pkey, dsa);
523 	return 1;
524 }
525 
526 static int
527 old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
528 {
529 	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
530 }
531 
532 static int
533 dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
534     int indent, ASN1_PCTX *pctx)
535 {
536 	DSA_SIG *dsa_sig;
537 	const unsigned char *p;
538 
539 	if (!sig) {
540 		if (BIO_puts(bp, "\n") <= 0)
541 			return 0;
542 		else
543 			return 1;
544 	}
545 	p = sig->data;
546 	dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
547 	if (dsa_sig) {
548 		int rv = 0;
549 		size_t buf_len = 0;
550 		unsigned char *m = NULL;
551 
552 		update_buflen(dsa_sig->r, &buf_len);
553 		update_buflen(dsa_sig->s, &buf_len);
554 		m = malloc(buf_len + 10);
555 		if (m == NULL) {
556 			DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE);
557 			goto err;
558 		}
559 
560 		if (BIO_write(bp, "\n", 1) != 1)
561 			goto err;
562 
563 		if (!ASN1_bn_print(bp, "r:   ", dsa_sig->r, m, indent))
564 			goto err;
565 		if (!ASN1_bn_print(bp, "s:   ", dsa_sig->s, m, indent))
566 			goto err;
567 		rv = 1;
568 err:
569 		free(m);
570 		DSA_SIG_free(dsa_sig);
571 		return rv;
572 	}
573 	return X509_signature_dump(bp, sig, indent);
574 }
575 
576 static int
577 dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
578 {
579 	switch (op) {
580 	case ASN1_PKEY_CTRL_PKCS7_SIGN:
581 		if (arg1 == 0) {
582 			int snid, hnid;
583 			X509_ALGOR *alg1, *alg2;
584 
585 			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
586 			if (alg1 == NULL || alg1->algorithm == NULL)
587 				return -1;
588 			hnid = OBJ_obj2nid(alg1->algorithm);
589 			if (hnid == NID_undef)
590 				return -1;
591 			if (!OBJ_find_sigid_by_algs(&snid, hnid,
592 			    EVP_PKEY_id(pkey)))
593 				return -1;
594 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF,
595 			    0);
596 		}
597 		return 1;
598 #ifndef OPENSSL_NO_CMS
599 	case ASN1_PKEY_CTRL_CMS_SIGN:
600 		if (arg1 == 0) {
601 			int snid, hnid;
602 			X509_ALGOR *alg1, *alg2;
603 
604 			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
605 			if (alg1 == NULL || alg1->algorithm == NULL)
606 				return -1;
607 			hnid = OBJ_obj2nid(alg1->algorithm);
608 			if (hnid == NID_undef)
609 				return -1;
610 			if (!OBJ_find_sigid_by_algs(&snid, hnid,
611 			    EVP_PKEY_id(pkey)))
612 				return -1;
613 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF,
614 			    0);
615 		}
616 		return 1;
617 #endif
618 
619 	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
620 		*(int *)arg2 = NID_sha1;
621 		return 2;
622 
623 	default:
624 		return -2;
625 	}
626 }
627 
628 /* NB these are sorted in pkey_id order, lowest first */
629 
630 const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = {
631 	{
632 		.pkey_id = EVP_PKEY_DSA2,
633 		.pkey_base_id = EVP_PKEY_DSA,
634 		.pkey_flags = ASN1_PKEY_ALIAS
635 	},
636 
637 	{
638 		.pkey_id = EVP_PKEY_DSA1,
639 		.pkey_base_id = EVP_PKEY_DSA,
640 		.pkey_flags = ASN1_PKEY_ALIAS
641 	},
642 
643 	{
644 		.pkey_id = EVP_PKEY_DSA4,
645 		.pkey_base_id = EVP_PKEY_DSA,
646 		.pkey_flags = ASN1_PKEY_ALIAS
647 	},
648 
649 	{
650 		.pkey_id = EVP_PKEY_DSA3,
651 		.pkey_base_id = EVP_PKEY_DSA,
652 		.pkey_flags = ASN1_PKEY_ALIAS
653 	},
654 
655 	{
656 		.pkey_id = EVP_PKEY_DSA,
657 		.pkey_base_id = EVP_PKEY_DSA,
658 
659 		.pem_str = "DSA",
660 		.info = "OpenSSL DSA method",
661 
662 		.pub_decode = dsa_pub_decode,
663 		.pub_encode = dsa_pub_encode,
664 		.pub_cmp = dsa_pub_cmp,
665 		.pub_print = dsa_pub_print,
666 
667 		.priv_decode = dsa_priv_decode,
668 		.priv_encode = dsa_priv_encode,
669 		.priv_print = dsa_priv_print,
670 
671 		.pkey_size = int_dsa_size,
672 		.pkey_bits = dsa_bits,
673 
674 		.param_decode = dsa_param_decode,
675 		.param_encode = dsa_param_encode,
676 		.param_missing = dsa_missing_parameters,
677 		.param_copy = dsa_copy_parameters,
678 		.param_cmp = dsa_cmp_parameters,
679 		.param_print = dsa_param_print,
680 		.sig_print = dsa_sig_print,
681 
682 		.pkey_free = int_dsa_free,
683 		.pkey_ctrl = dsa_pkey_ctrl,
684 		.old_priv_decode = old_dsa_priv_decode,
685 		.old_priv_encode = old_dsa_priv_encode
686 	}
687 };
688