xref: /openbsd-src/lib/libcrypto/dsa/dsa_asn1.c (revision 019a55e8f98ec3ac544d2ddf9e0b1a4ff8310a61)
1*019a55e8Sbeck /* $OpenBSD: dsa_asn1.c,v 1.33 2024/07/08 17:11:05 beck Exp $ */
2e6841c1dSdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3da347917Sbeck  * project 2000.
4da347917Sbeck  */
5da347917Sbeck /* ====================================================================
60a5d6edeSdjm  * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
7da347917Sbeck  *
8da347917Sbeck  * Redistribution and use in source and binary forms, with or without
9da347917Sbeck  * modification, are permitted provided that the following conditions
10da347917Sbeck  * are met:
11da347917Sbeck  *
12da347917Sbeck  * 1. Redistributions of source code must retain the above copyright
13da347917Sbeck  *    notice, this list of conditions and the following disclaimer.
14da347917Sbeck  *
15da347917Sbeck  * 2. Redistributions in binary form must reproduce the above copyright
16da347917Sbeck  *    notice, this list of conditions and the following disclaimer in
17da347917Sbeck  *    the documentation and/or other materials provided with the
18da347917Sbeck  *    distribution.
19da347917Sbeck  *
20da347917Sbeck  * 3. All advertising materials mentioning features or use of this
21da347917Sbeck  *    software must display the following acknowledgment:
22da347917Sbeck  *    "This product includes software developed by the OpenSSL Project
23da347917Sbeck  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24da347917Sbeck  *
25da347917Sbeck  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26da347917Sbeck  *    endorse or promote products derived from this software without
27da347917Sbeck  *    prior written permission. For written permission, please contact
28da347917Sbeck  *    licensing@OpenSSL.org.
29da347917Sbeck  *
30da347917Sbeck  * 5. Products derived from this software may not be called "OpenSSL"
31da347917Sbeck  *    nor may "OpenSSL" appear in their names without prior written
32da347917Sbeck  *    permission of the OpenSSL Project.
33da347917Sbeck  *
34da347917Sbeck  * 6. Redistributions of any form whatsoever must retain the following
35da347917Sbeck  *    acknowledgment:
36da347917Sbeck  *    "This product includes software developed by the OpenSSL Project
37da347917Sbeck  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38da347917Sbeck  *
39da347917Sbeck  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40da347917Sbeck  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41da347917Sbeck  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42da347917Sbeck  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43da347917Sbeck  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44da347917Sbeck  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45da347917Sbeck  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46da347917Sbeck  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47da347917Sbeck  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48da347917Sbeck  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49da347917Sbeck  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50da347917Sbeck  * OF THE POSSIBILITY OF SUCH DAMAGE.
51da347917Sbeck  * ====================================================================
52da347917Sbeck  *
53da347917Sbeck  * This product includes cryptographic software written by Eric Young
54da347917Sbeck  * (eay@cryptsoft.com).  This product includes software written by Tim
55da347917Sbeck  * Hudson (tjh@cryptsoft.com).
56da347917Sbeck  *
57da347917Sbeck  */
58913ec974Sbeck 
59913ec974Sbeck #include <stdio.h>
60df47532eSbeck #include <string.h>
61b6ab114eSjsing 
62913ec974Sbeck #include <openssl/asn1.h>
63da347917Sbeck #include <openssl/asn1t.h>
6496bb3fc8Stb #include <openssl/bn.h>
65b6ab114eSjsing #include <openssl/dsa.h>
66b6ab114eSjsing #include <openssl/err.h>
67913ec974Sbeck 
68c9675a23Stb #include "dsa_local.h"
69f69303b6Stb 
70da347917Sbeck /* Override the default new methods */
71e85b1b81Smiod static int
sig_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)72e85b1b81Smiod sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
73913ec974Sbeck {
74da347917Sbeck 	if (operation == ASN1_OP_NEW_PRE) {
75da347917Sbeck 		DSA_SIG *sig;
76e85b1b81Smiod 
7739019809Sjsing 		if ((sig = DSA_SIG_new()) == NULL) {
785067ae9fSbeck 			DSAerror(ERR_R_MALLOC_FAILURE);
790a5d6edeSdjm 			return 0;
800a5d6edeSdjm 		}
81da347917Sbeck 		*pval = (ASN1_VALUE *)sig;
820a5d6edeSdjm 		return 2;
83913ec974Sbeck 	}
84da347917Sbeck 	return 1;
85913ec974Sbeck }
86913ec974Sbeck 
87b8da34fdSjsing static const ASN1_AUX DSA_SIG_aux = {
88b8da34fdSjsing 	.app_data = NULL,
89b8da34fdSjsing 	.flags = 0,
90b8da34fdSjsing 	.ref_offset = 0,
91b8da34fdSjsing 	.ref_lock = 0,
92b8da34fdSjsing 	.asn1_cb = sig_cb,
93b8da34fdSjsing 	.enc_offset = 0,
94b8da34fdSjsing };
95b8da34fdSjsing static const ASN1_TEMPLATE DSA_SIG_seq_tt[] = {
96b8da34fdSjsing 	{
97b8da34fdSjsing 		.flags = 0,
98b8da34fdSjsing 		.tag = 0,
99b8da34fdSjsing 		.offset = offsetof(DSA_SIG, r),
100b8da34fdSjsing 		.field_name = "r",
101ba6ce9beSjsing 		.item = &BIGNUM_it,
102b8da34fdSjsing 	},
103b8da34fdSjsing 	{
104b8da34fdSjsing 		.flags = 0,
105b8da34fdSjsing 		.tag = 0,
106b8da34fdSjsing 		.offset = offsetof(DSA_SIG, s),
107b8da34fdSjsing 		.field_name = "s",
108ba6ce9beSjsing 		.item = &BIGNUM_it,
109b8da34fdSjsing 	},
110b8da34fdSjsing };
111b8da34fdSjsing 
1126454157eStb static const ASN1_ITEM DSA_SIG_it = {
113b8da34fdSjsing 	.itype = ASN1_ITYPE_SEQUENCE,
114b8da34fdSjsing 	.utype = V_ASN1_SEQUENCE,
115b8da34fdSjsing 	.templates = DSA_SIG_seq_tt,
116b8da34fdSjsing 	.tcount = sizeof(DSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
117b8da34fdSjsing 	.funcs = &DSA_SIG_aux,
118b8da34fdSjsing 	.size = sizeof(DSA_SIG),
119b8da34fdSjsing 	.sname = "DSA_SIG",
120b8da34fdSjsing };
121da347917Sbeck 
122aded6b34Sjsing 
123aded6b34Sjsing DSA_SIG *
d2i_DSA_SIG(DSA_SIG ** a,const unsigned char ** in,long len)124aded6b34Sjsing d2i_DSA_SIG(DSA_SIG **a, const unsigned char **in, long len)
125aded6b34Sjsing {
126aded6b34Sjsing 	return (DSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
127aded6b34Sjsing 	    &DSA_SIG_it);
128aded6b34Sjsing }
12981dbdadeSbeck LCRYPTO_ALIAS(d2i_DSA_SIG);
130aded6b34Sjsing 
131aded6b34Sjsing int
i2d_DSA_SIG(const DSA_SIG * a,unsigned char ** out)132aded6b34Sjsing i2d_DSA_SIG(const DSA_SIG *a, unsigned char **out)
133aded6b34Sjsing {
134aded6b34Sjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSA_SIG_it);
135aded6b34Sjsing }
13681dbdadeSbeck LCRYPTO_ALIAS(i2d_DSA_SIG);
137da347917Sbeck 
138191fb070Stb void
DSA_SIG_get0(const DSA_SIG * sig,const BIGNUM ** pr,const BIGNUM ** ps)139191fb070Stb DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
140191fb070Stb {
141191fb070Stb 	if (pr != NULL)
142191fb070Stb 		*pr = sig->r;
143191fb070Stb 	if (ps != NULL)
144191fb070Stb 		*ps = sig->s;
145191fb070Stb }
14681dbdadeSbeck LCRYPTO_ALIAS(DSA_SIG_get0);
147191fb070Stb 
148191fb070Stb int
DSA_SIG_set0(DSA_SIG * sig,BIGNUM * r,BIGNUM * s)149191fb070Stb DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
150191fb070Stb {
151191fb070Stb 	if (r == NULL || s == NULL)
152191fb070Stb 		return 0;
153191fb070Stb 
154c11f7855Sjsing 	BN_free(sig->r);
155191fb070Stb 	sig->r = r;
156c11f7855Sjsing 	BN_free(sig->s);
157191fb070Stb 	sig->s = s;
158191fb070Stb 
159191fb070Stb 	return 1;
160191fb070Stb }
16181dbdadeSbeck LCRYPTO_ALIAS(DSA_SIG_set0);
162191fb070Stb 
163da347917Sbeck /* Override the default free and new methods */
164e85b1b81Smiod static int
dsa_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)165e85b1b81Smiod dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
166913ec974Sbeck {
167da347917Sbeck 	if (operation == ASN1_OP_NEW_PRE) {
168da347917Sbeck 		*pval = (ASN1_VALUE *)DSA_new();
169e85b1b81Smiod 		if (*pval)
170e85b1b81Smiod 			return 2;
171da347917Sbeck 		return 0;
172da347917Sbeck 	} else if (operation == ASN1_OP_FREE_PRE) {
173da347917Sbeck 		DSA_free((DSA *)*pval);
174da347917Sbeck 		*pval = NULL;
175da347917Sbeck 		return 2;
176da347917Sbeck 	}
177da347917Sbeck 	return 1;
178913ec974Sbeck }
179913ec974Sbeck 
180b8da34fdSjsing static const ASN1_AUX DSAPrivateKey_aux = {
181b8da34fdSjsing 	.app_data = NULL,
182b8da34fdSjsing 	.flags = 0,
183b8da34fdSjsing 	.ref_offset = 0,
184b8da34fdSjsing 	.ref_lock = 0,
185b8da34fdSjsing 	.asn1_cb = dsa_cb,
186b8da34fdSjsing 	.enc_offset = 0,
187b8da34fdSjsing };
188b8da34fdSjsing static const ASN1_TEMPLATE DSAPrivateKey_seq_tt[] = {
189b8da34fdSjsing 	{
190b8da34fdSjsing 		.flags = 0,
191b8da34fdSjsing 		.tag = 0,
192b8da34fdSjsing 		.offset = offsetof(DSA, version),
193b8da34fdSjsing 		.field_name = "version",
194b8da34fdSjsing 		.item = &LONG_it,
195b8da34fdSjsing 	},
196b8da34fdSjsing 	{
197b8da34fdSjsing 		.flags = 0,
198b8da34fdSjsing 		.tag = 0,
199b8da34fdSjsing 		.offset = offsetof(DSA, p),
200b8da34fdSjsing 		.field_name = "p",
201b8da34fdSjsing 		.item = &BIGNUM_it,
202b8da34fdSjsing 	},
203b8da34fdSjsing 	{
204b8da34fdSjsing 		.flags = 0,
205b8da34fdSjsing 		.tag = 0,
206b8da34fdSjsing 		.offset = offsetof(DSA, q),
207b8da34fdSjsing 		.field_name = "q",
208b8da34fdSjsing 		.item = &BIGNUM_it,
209b8da34fdSjsing 	},
210b8da34fdSjsing 	{
211b8da34fdSjsing 		.flags = 0,
212b8da34fdSjsing 		.tag = 0,
213b8da34fdSjsing 		.offset = offsetof(DSA, g),
214b8da34fdSjsing 		.field_name = "g",
215b8da34fdSjsing 		.item = &BIGNUM_it,
216b8da34fdSjsing 	},
217b8da34fdSjsing 	{
218b8da34fdSjsing 		.flags = 0,
219b8da34fdSjsing 		.tag = 0,
220b8da34fdSjsing 		.offset = offsetof(DSA, pub_key),
221b8da34fdSjsing 		.field_name = "pub_key",
222b8da34fdSjsing 		.item = &BIGNUM_it,
223b8da34fdSjsing 	},
224b8da34fdSjsing 	{
225b8da34fdSjsing 		.flags = 0,
226b8da34fdSjsing 		.tag = 0,
227b8da34fdSjsing 		.offset = offsetof(DSA, priv_key),
228b8da34fdSjsing 		.field_name = "priv_key",
229b8da34fdSjsing 		.item = &BIGNUM_it,
230b8da34fdSjsing 	},
231b8da34fdSjsing };
232b8da34fdSjsing 
233b8da34fdSjsing const ASN1_ITEM DSAPrivateKey_it = {
234b8da34fdSjsing 	.itype = ASN1_ITYPE_SEQUENCE,
235b8da34fdSjsing 	.utype = V_ASN1_SEQUENCE,
236b8da34fdSjsing 	.templates = DSAPrivateKey_seq_tt,
237b8da34fdSjsing 	.tcount = sizeof(DSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE),
238b8da34fdSjsing 	.funcs = &DSAPrivateKey_aux,
239b8da34fdSjsing 	.size = sizeof(DSA),
240b8da34fdSjsing 	.sname = "DSA",
241b8da34fdSjsing };
242*019a55e8Sbeck LCRYPTO_ALIAS(DSAPrivateKey_it);
243913ec974Sbeck 
244aded6b34Sjsing 
245aded6b34Sjsing DSA *
d2i_DSAPrivateKey(DSA ** a,const unsigned char ** in,long len)246aded6b34Sjsing d2i_DSAPrivateKey(DSA **a, const unsigned char **in, long len)
247aded6b34Sjsing {
248aded6b34Sjsing 	return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
249aded6b34Sjsing 	    &DSAPrivateKey_it);
250aded6b34Sjsing }
25181dbdadeSbeck LCRYPTO_ALIAS(d2i_DSAPrivateKey);
252aded6b34Sjsing 
253aded6b34Sjsing int
i2d_DSAPrivateKey(const DSA * a,unsigned char ** out)254aded6b34Sjsing i2d_DSAPrivateKey(const DSA *a, unsigned char **out)
255aded6b34Sjsing {
256aded6b34Sjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPrivateKey_it);
257aded6b34Sjsing }
25881dbdadeSbeck LCRYPTO_ALIAS(i2d_DSAPrivateKey);
259913ec974Sbeck 
260b8da34fdSjsing static const ASN1_AUX DSAparams_aux = {
261b8da34fdSjsing 	.app_data = NULL,
262b8da34fdSjsing 	.flags = 0,
263b8da34fdSjsing 	.ref_offset = 0,
264b8da34fdSjsing 	.ref_lock = 0,
265b8da34fdSjsing 	.asn1_cb = dsa_cb,
266b8da34fdSjsing 	.enc_offset = 0,
267b8da34fdSjsing };
268b8da34fdSjsing static const ASN1_TEMPLATE DSAparams_seq_tt[] = {
269b8da34fdSjsing 	{
270b8da34fdSjsing 		.flags = 0,
271b8da34fdSjsing 		.tag = 0,
272b8da34fdSjsing 		.offset = offsetof(DSA, p),
273b8da34fdSjsing 		.field_name = "p",
274b8da34fdSjsing 		.item = &BIGNUM_it,
275b8da34fdSjsing 	},
276b8da34fdSjsing 	{
277b8da34fdSjsing 		.flags = 0,
278b8da34fdSjsing 		.tag = 0,
279b8da34fdSjsing 		.offset = offsetof(DSA, q),
280b8da34fdSjsing 		.field_name = "q",
281b8da34fdSjsing 		.item = &BIGNUM_it,
282b8da34fdSjsing 	},
283b8da34fdSjsing 	{
284b8da34fdSjsing 		.flags = 0,
285b8da34fdSjsing 		.tag = 0,
286b8da34fdSjsing 		.offset = offsetof(DSA, g),
287b8da34fdSjsing 		.field_name = "g",
288b8da34fdSjsing 		.item = &BIGNUM_it,
289b8da34fdSjsing 	},
290b8da34fdSjsing };
291b8da34fdSjsing 
292b8da34fdSjsing const ASN1_ITEM DSAparams_it = {
293b8da34fdSjsing 	.itype = ASN1_ITYPE_SEQUENCE,
294b8da34fdSjsing 	.utype = V_ASN1_SEQUENCE,
295b8da34fdSjsing 	.templates = DSAparams_seq_tt,
296b8da34fdSjsing 	.tcount = sizeof(DSAparams_seq_tt) / sizeof(ASN1_TEMPLATE),
297b8da34fdSjsing 	.funcs = &DSAparams_aux,
298b8da34fdSjsing 	.size = sizeof(DSA),
299b8da34fdSjsing 	.sname = "DSA",
300b8da34fdSjsing };
301*019a55e8Sbeck LCRYPTO_ALIAS(DSAparams_it);
302913ec974Sbeck 
303aded6b34Sjsing 
304aded6b34Sjsing DSA *
d2i_DSAparams(DSA ** a,const unsigned char ** in,long len)305aded6b34Sjsing d2i_DSAparams(DSA **a, const unsigned char **in, long len)
306aded6b34Sjsing {
307aded6b34Sjsing 	return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
308aded6b34Sjsing 	    &DSAparams_it);
309aded6b34Sjsing }
31081dbdadeSbeck LCRYPTO_ALIAS(d2i_DSAparams);
311aded6b34Sjsing 
312aded6b34Sjsing int
i2d_DSAparams(const DSA * a,unsigned char ** out)313aded6b34Sjsing i2d_DSAparams(const DSA *a, unsigned char **out)
314aded6b34Sjsing {
315aded6b34Sjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAparams_it);
316aded6b34Sjsing }
31781dbdadeSbeck LCRYPTO_ALIAS(i2d_DSAparams);
318913ec974Sbeck 
3192ca51753Sjsing DSA *
d2i_DSAparams_bio(BIO * bp,DSA ** a)3202ca51753Sjsing d2i_DSAparams_bio(BIO *bp, DSA **a)
3212ca51753Sjsing {
3222ca51753Sjsing 	return ASN1_item_d2i_bio(&DSAparams_it, bp, a);
3232ca51753Sjsing }
32481dbdadeSbeck LCRYPTO_ALIAS(d2i_DSAparams_bio);
3252ca51753Sjsing 
3262ca51753Sjsing int
i2d_DSAparams_bio(BIO * bp,DSA * a)3272ca51753Sjsing i2d_DSAparams_bio(BIO *bp, DSA *a)
3282ca51753Sjsing {
3292ca51753Sjsing 	return ASN1_item_i2d_bio(&DSAparams_it, bp, a);
3302ca51753Sjsing }
33181dbdadeSbeck LCRYPTO_ALIAS(i2d_DSAparams_bio);
3322ca51753Sjsing 
3332ca51753Sjsing DSA *
d2i_DSAparams_fp(FILE * fp,DSA ** a)3342ca51753Sjsing d2i_DSAparams_fp(FILE *fp, DSA **a)
3352ca51753Sjsing {
3362ca51753Sjsing 	return ASN1_item_d2i_fp(&DSAparams_it, fp, a);
3372ca51753Sjsing }
33881dbdadeSbeck LCRYPTO_ALIAS(d2i_DSAparams_fp);
3392ca51753Sjsing 
3402ca51753Sjsing int
i2d_DSAparams_fp(FILE * fp,DSA * a)3412ca51753Sjsing i2d_DSAparams_fp(FILE *fp, DSA *a)
3422ca51753Sjsing {
3432ca51753Sjsing 	return ASN1_item_i2d_fp(&DSAparams_it, fp, a);
3442ca51753Sjsing }
34581dbdadeSbeck LCRYPTO_ALIAS(i2d_DSAparams_fp);
3462ca51753Sjsing 
347354ae18bStb static const ASN1_AUX DSAPublicKey_aux = {
348354ae18bStb 	.app_data = NULL,
349354ae18bStb 	.flags = 0,
350354ae18bStb 	.ref_offset = 0,
351354ae18bStb 	.ref_lock = 0,
352354ae18bStb 	.asn1_cb = dsa_cb,
353354ae18bStb 	.enc_offset = 0,
354354ae18bStb };
355354ae18bStb static const ASN1_TEMPLATE DSAPublicKey_seq_tt[] = {
356b8da34fdSjsing 	{
357b8da34fdSjsing 		.flags = 0,
358b8da34fdSjsing 		.tag = 0,
359b8da34fdSjsing 		.offset = offsetof(DSA, pub_key),
360b8da34fdSjsing 		.field_name = "pub_key",
361b8da34fdSjsing 		.item = &BIGNUM_it,
362b8da34fdSjsing 	},
363b8da34fdSjsing 	{
364b8da34fdSjsing 		.flags = 0,
365b8da34fdSjsing 		.tag = 0,
366b8da34fdSjsing 		.offset = offsetof(DSA, p),
367b8da34fdSjsing 		.field_name = "p",
368b8da34fdSjsing 		.item = &BIGNUM_it,
369b8da34fdSjsing 	},
370b8da34fdSjsing 	{
371b8da34fdSjsing 		.flags = 0,
372b8da34fdSjsing 		.tag = 0,
373b8da34fdSjsing 		.offset = offsetof(DSA, q),
374b8da34fdSjsing 		.field_name = "q",
375b8da34fdSjsing 		.item = &BIGNUM_it,
376b8da34fdSjsing 	},
377b8da34fdSjsing 	{
378b8da34fdSjsing 		.flags = 0,
379b8da34fdSjsing 		.tag = 0,
380b8da34fdSjsing 		.offset = offsetof(DSA, g),
381b8da34fdSjsing 		.field_name = "g",
382b8da34fdSjsing 		.item = &BIGNUM_it,
383b8da34fdSjsing 	},
384b8da34fdSjsing };
385913ec974Sbeck 
386354ae18bStb const ASN1_ITEM DSAPublicKey_it = {
387b8da34fdSjsing 	.itype = ASN1_ITYPE_SEQUENCE,
388b8da34fdSjsing 	.utype = V_ASN1_SEQUENCE,
389354ae18bStb 	.templates = DSAPublicKey_seq_tt,
390354ae18bStb 	.tcount = sizeof(DSAPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE),
391b8da34fdSjsing 	.funcs = &DSAPublicKey_aux,
392b8da34fdSjsing 	.size = sizeof(DSA),
393b8da34fdSjsing 	.sname = "DSA",
394b8da34fdSjsing };
395*019a55e8Sbeck LCRYPTO_ALIAS(DSAPublicKey_it);
396da347917Sbeck 
397aded6b34Sjsing DSA *
d2i_DSAPublicKey(DSA ** a,const unsigned char ** in,long len)398aded6b34Sjsing d2i_DSAPublicKey(DSA **a, const unsigned char **in, long len)
399aded6b34Sjsing {
400aded6b34Sjsing 	return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
401aded6b34Sjsing 	    &DSAPublicKey_it);
402aded6b34Sjsing }
40381dbdadeSbeck LCRYPTO_ALIAS(d2i_DSAPublicKey);
404aded6b34Sjsing 
405aded6b34Sjsing int
i2d_DSAPublicKey(const DSA * a,unsigned char ** out)406aded6b34Sjsing i2d_DSAPublicKey(const DSA *a, unsigned char **out)
407aded6b34Sjsing {
408aded6b34Sjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPublicKey_it);
409aded6b34Sjsing }
41081dbdadeSbeck LCRYPTO_ALIAS(i2d_DSAPublicKey);
411e6841c1dSdjm 
412e85b1b81Smiod DSA *
DSAparams_dup(DSA * dsa)413e85b1b81Smiod DSAparams_dup(DSA *dsa)
414e6841c1dSdjm {
415227fbe76Sjsing 	return ASN1_item_dup(&DSAparams_it, dsa);
416e6841c1dSdjm }
41781dbdadeSbeck LCRYPTO_ALIAS(DSAparams_dup);
4185cdd308eSdjm 
419e85b1b81Smiod int
DSA_sign(int type,const unsigned char * dgst,int dlen,unsigned char * sig,unsigned int * out_siglen,DSA * dsa)420e85b1b81Smiod DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
4210c6c9df4Stb     unsigned int *out_siglen, DSA *dsa)
4225cdd308eSdjm {
4235cdd308eSdjm 	DSA_SIG *s;
4240c6c9df4Stb 	int siglen;
4250c6c9df4Stb 	int ret = 0;
426e85b1b81Smiod 
4270c6c9df4Stb 	*out_siglen = 0;
4280c6c9df4Stb 
4290c6c9df4Stb 	if ((s = DSA_do_sign(dgst, dlen, dsa)) == NULL)
4300c6c9df4Stb 		goto err;
4310c6c9df4Stb 
4320c6c9df4Stb 	if ((siglen = i2d_DSA_SIG(s, &sig)) < 0)
4330c6c9df4Stb 		goto err;
4340c6c9df4Stb 
4350c6c9df4Stb 	*out_siglen = siglen;
4360c6c9df4Stb 
4370c6c9df4Stb 	ret = 1;
4380c6c9df4Stb  err:
4395cdd308eSdjm 	DSA_SIG_free(s);
4400c6c9df4Stb 
4410c6c9df4Stb 	return ret;
4425cdd308eSdjm }
44381dbdadeSbeck LCRYPTO_ALIAS(DSA_sign);
4445cdd308eSdjm 
445e85b1b81Smiod /*
446e85b1b81Smiod  * data has already been hashed (probably with SHA or SHA-1).
447e85b1b81Smiod  * returns
4485cdd308eSdjm  *      1: correct signature
4495cdd308eSdjm  *      0: incorrect signature
4505cdd308eSdjm  *     -1: error
4515cdd308eSdjm  */
452e85b1b81Smiod int
DSA_verify(int type,const unsigned char * dgst,int dgst_len,const unsigned char * sigbuf,int siglen,DSA * dsa)453e85b1b81Smiod DSA_verify(int type, const unsigned char *dgst, int dgst_len,
4545cdd308eSdjm     const unsigned char *sigbuf, int siglen, DSA *dsa)
4555cdd308eSdjm {
4560c6c9df4Stb 	DSA_SIG *s = NULL;
457df47532eSbeck 	unsigned char *der = NULL;
4580c6c9df4Stb 	const unsigned char *p;
4595cdd308eSdjm 	int ret = -1;
4605cdd308eSdjm 
4610c6c9df4Stb 	p = sigbuf;
4620c6c9df4Stb 	if ((s = d2i_DSA_SIG(NULL, &p, siglen)) == NULL)
463df47532eSbeck 		goto err;
4640c6c9df4Stb 
465df47532eSbeck 	/* Ensure signature uses DER and doesn't have trailing garbage */
4660c6c9df4Stb 	if (i2d_DSA_SIG(s, &der) != siglen)
467e85b1b81Smiod 		goto err;
4680c6c9df4Stb 
4690c6c9df4Stb 	if (memcmp(der, sigbuf, siglen) != 0)
4700c6c9df4Stb 		goto err;
4710c6c9df4Stb 
4725cdd308eSdjm 	ret = DSA_do_verify(dgst, dgst_len, s, dsa);
4735cdd308eSdjm  err:
4740c6c9df4Stb 	free(der);
4755cdd308eSdjm 	DSA_SIG_free(s);
4760c6c9df4Stb 
477e85b1b81Smiod 	return ret;
4785cdd308eSdjm }
47981dbdadeSbeck LCRYPTO_ALIAS(DSA_verify);
480