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