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