1 /* $OpenBSD: dsa_asn1.c,v 1.33 2024/07/08 17:11:05 beck Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000.
4 */
5 /* ====================================================================
6 * Copyright (c) 2000-2005 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 #include <string.h>
61
62 #include <openssl/asn1.h>
63 #include <openssl/asn1t.h>
64 #include <openssl/bn.h>
65 #include <openssl/dsa.h>
66 #include <openssl/err.h>
67
68 #include "dsa_local.h"
69
70 /* Override the default new methods */
71 static int
sig_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)72 sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
73 {
74 if (operation == ASN1_OP_NEW_PRE) {
75 DSA_SIG *sig;
76
77 if ((sig = DSA_SIG_new()) == NULL) {
78 DSAerror(ERR_R_MALLOC_FAILURE);
79 return 0;
80 }
81 *pval = (ASN1_VALUE *)sig;
82 return 2;
83 }
84 return 1;
85 }
86
87 static const ASN1_AUX DSA_SIG_aux = {
88 .app_data = NULL,
89 .flags = 0,
90 .ref_offset = 0,
91 .ref_lock = 0,
92 .asn1_cb = sig_cb,
93 .enc_offset = 0,
94 };
95 static const ASN1_TEMPLATE DSA_SIG_seq_tt[] = {
96 {
97 .flags = 0,
98 .tag = 0,
99 .offset = offsetof(DSA_SIG, r),
100 .field_name = "r",
101 .item = &BIGNUM_it,
102 },
103 {
104 .flags = 0,
105 .tag = 0,
106 .offset = offsetof(DSA_SIG, s),
107 .field_name = "s",
108 .item = &BIGNUM_it,
109 },
110 };
111
112 static const ASN1_ITEM DSA_SIG_it = {
113 .itype = ASN1_ITYPE_SEQUENCE,
114 .utype = V_ASN1_SEQUENCE,
115 .templates = DSA_SIG_seq_tt,
116 .tcount = sizeof(DSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
117 .funcs = &DSA_SIG_aux,
118 .size = sizeof(DSA_SIG),
119 .sname = "DSA_SIG",
120 };
121
122
123 DSA_SIG *
d2i_DSA_SIG(DSA_SIG ** a,const unsigned char ** in,long len)124 d2i_DSA_SIG(DSA_SIG **a, const unsigned char **in, long len)
125 {
126 return (DSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
127 &DSA_SIG_it);
128 }
129 LCRYPTO_ALIAS(d2i_DSA_SIG);
130
131 int
i2d_DSA_SIG(const DSA_SIG * a,unsigned char ** out)132 i2d_DSA_SIG(const DSA_SIG *a, unsigned char **out)
133 {
134 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSA_SIG_it);
135 }
136 LCRYPTO_ALIAS(i2d_DSA_SIG);
137
138 void
DSA_SIG_get0(const DSA_SIG * sig,const BIGNUM ** pr,const BIGNUM ** ps)139 DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
140 {
141 if (pr != NULL)
142 *pr = sig->r;
143 if (ps != NULL)
144 *ps = sig->s;
145 }
146 LCRYPTO_ALIAS(DSA_SIG_get0);
147
148 int
DSA_SIG_set0(DSA_SIG * sig,BIGNUM * r,BIGNUM * s)149 DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
150 {
151 if (r == NULL || s == NULL)
152 return 0;
153
154 BN_free(sig->r);
155 sig->r = r;
156 BN_free(sig->s);
157 sig->s = s;
158
159 return 1;
160 }
161 LCRYPTO_ALIAS(DSA_SIG_set0);
162
163 /* Override the default free and new methods */
164 static int
dsa_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)165 dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
166 {
167 if (operation == ASN1_OP_NEW_PRE) {
168 *pval = (ASN1_VALUE *)DSA_new();
169 if (*pval)
170 return 2;
171 return 0;
172 } else if (operation == ASN1_OP_FREE_PRE) {
173 DSA_free((DSA *)*pval);
174 *pval = NULL;
175 return 2;
176 }
177 return 1;
178 }
179
180 static const ASN1_AUX DSAPrivateKey_aux = {
181 .app_data = NULL,
182 .flags = 0,
183 .ref_offset = 0,
184 .ref_lock = 0,
185 .asn1_cb = dsa_cb,
186 .enc_offset = 0,
187 };
188 static const ASN1_TEMPLATE DSAPrivateKey_seq_tt[] = {
189 {
190 .flags = 0,
191 .tag = 0,
192 .offset = offsetof(DSA, version),
193 .field_name = "version",
194 .item = &LONG_it,
195 },
196 {
197 .flags = 0,
198 .tag = 0,
199 .offset = offsetof(DSA, p),
200 .field_name = "p",
201 .item = &BIGNUM_it,
202 },
203 {
204 .flags = 0,
205 .tag = 0,
206 .offset = offsetof(DSA, q),
207 .field_name = "q",
208 .item = &BIGNUM_it,
209 },
210 {
211 .flags = 0,
212 .tag = 0,
213 .offset = offsetof(DSA, g),
214 .field_name = "g",
215 .item = &BIGNUM_it,
216 },
217 {
218 .flags = 0,
219 .tag = 0,
220 .offset = offsetof(DSA, pub_key),
221 .field_name = "pub_key",
222 .item = &BIGNUM_it,
223 },
224 {
225 .flags = 0,
226 .tag = 0,
227 .offset = offsetof(DSA, priv_key),
228 .field_name = "priv_key",
229 .item = &BIGNUM_it,
230 },
231 };
232
233 const ASN1_ITEM DSAPrivateKey_it = {
234 .itype = ASN1_ITYPE_SEQUENCE,
235 .utype = V_ASN1_SEQUENCE,
236 .templates = DSAPrivateKey_seq_tt,
237 .tcount = sizeof(DSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE),
238 .funcs = &DSAPrivateKey_aux,
239 .size = sizeof(DSA),
240 .sname = "DSA",
241 };
242 LCRYPTO_ALIAS(DSAPrivateKey_it);
243
244
245 DSA *
d2i_DSAPrivateKey(DSA ** a,const unsigned char ** in,long len)246 d2i_DSAPrivateKey(DSA **a, const unsigned char **in, long len)
247 {
248 return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
249 &DSAPrivateKey_it);
250 }
251 LCRYPTO_ALIAS(d2i_DSAPrivateKey);
252
253 int
i2d_DSAPrivateKey(const DSA * a,unsigned char ** out)254 i2d_DSAPrivateKey(const DSA *a, unsigned char **out)
255 {
256 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPrivateKey_it);
257 }
258 LCRYPTO_ALIAS(i2d_DSAPrivateKey);
259
260 static const ASN1_AUX DSAparams_aux = {
261 .app_data = NULL,
262 .flags = 0,
263 .ref_offset = 0,
264 .ref_lock = 0,
265 .asn1_cb = dsa_cb,
266 .enc_offset = 0,
267 };
268 static const ASN1_TEMPLATE DSAparams_seq_tt[] = {
269 {
270 .flags = 0,
271 .tag = 0,
272 .offset = offsetof(DSA, p),
273 .field_name = "p",
274 .item = &BIGNUM_it,
275 },
276 {
277 .flags = 0,
278 .tag = 0,
279 .offset = offsetof(DSA, q),
280 .field_name = "q",
281 .item = &BIGNUM_it,
282 },
283 {
284 .flags = 0,
285 .tag = 0,
286 .offset = offsetof(DSA, g),
287 .field_name = "g",
288 .item = &BIGNUM_it,
289 },
290 };
291
292 const ASN1_ITEM DSAparams_it = {
293 .itype = ASN1_ITYPE_SEQUENCE,
294 .utype = V_ASN1_SEQUENCE,
295 .templates = DSAparams_seq_tt,
296 .tcount = sizeof(DSAparams_seq_tt) / sizeof(ASN1_TEMPLATE),
297 .funcs = &DSAparams_aux,
298 .size = sizeof(DSA),
299 .sname = "DSA",
300 };
301 LCRYPTO_ALIAS(DSAparams_it);
302
303
304 DSA *
d2i_DSAparams(DSA ** a,const unsigned char ** in,long len)305 d2i_DSAparams(DSA **a, const unsigned char **in, long len)
306 {
307 return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
308 &DSAparams_it);
309 }
310 LCRYPTO_ALIAS(d2i_DSAparams);
311
312 int
i2d_DSAparams(const DSA * a,unsigned char ** out)313 i2d_DSAparams(const DSA *a, unsigned char **out)
314 {
315 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAparams_it);
316 }
317 LCRYPTO_ALIAS(i2d_DSAparams);
318
319 DSA *
d2i_DSAparams_bio(BIO * bp,DSA ** a)320 d2i_DSAparams_bio(BIO *bp, DSA **a)
321 {
322 return ASN1_item_d2i_bio(&DSAparams_it, bp, a);
323 }
324 LCRYPTO_ALIAS(d2i_DSAparams_bio);
325
326 int
i2d_DSAparams_bio(BIO * bp,DSA * a)327 i2d_DSAparams_bio(BIO *bp, DSA *a)
328 {
329 return ASN1_item_i2d_bio(&DSAparams_it, bp, a);
330 }
331 LCRYPTO_ALIAS(i2d_DSAparams_bio);
332
333 DSA *
d2i_DSAparams_fp(FILE * fp,DSA ** a)334 d2i_DSAparams_fp(FILE *fp, DSA **a)
335 {
336 return ASN1_item_d2i_fp(&DSAparams_it, fp, a);
337 }
338 LCRYPTO_ALIAS(d2i_DSAparams_fp);
339
340 int
i2d_DSAparams_fp(FILE * fp,DSA * a)341 i2d_DSAparams_fp(FILE *fp, DSA *a)
342 {
343 return ASN1_item_i2d_fp(&DSAparams_it, fp, a);
344 }
345 LCRYPTO_ALIAS(i2d_DSAparams_fp);
346
347 static const ASN1_AUX DSAPublicKey_aux = {
348 .app_data = NULL,
349 .flags = 0,
350 .ref_offset = 0,
351 .ref_lock = 0,
352 .asn1_cb = dsa_cb,
353 .enc_offset = 0,
354 };
355 static const ASN1_TEMPLATE DSAPublicKey_seq_tt[] = {
356 {
357 .flags = 0,
358 .tag = 0,
359 .offset = offsetof(DSA, pub_key),
360 .field_name = "pub_key",
361 .item = &BIGNUM_it,
362 },
363 {
364 .flags = 0,
365 .tag = 0,
366 .offset = offsetof(DSA, p),
367 .field_name = "p",
368 .item = &BIGNUM_it,
369 },
370 {
371 .flags = 0,
372 .tag = 0,
373 .offset = offsetof(DSA, q),
374 .field_name = "q",
375 .item = &BIGNUM_it,
376 },
377 {
378 .flags = 0,
379 .tag = 0,
380 .offset = offsetof(DSA, g),
381 .field_name = "g",
382 .item = &BIGNUM_it,
383 },
384 };
385
386 const ASN1_ITEM DSAPublicKey_it = {
387 .itype = ASN1_ITYPE_SEQUENCE,
388 .utype = V_ASN1_SEQUENCE,
389 .templates = DSAPublicKey_seq_tt,
390 .tcount = sizeof(DSAPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE),
391 .funcs = &DSAPublicKey_aux,
392 .size = sizeof(DSA),
393 .sname = "DSA",
394 };
395 LCRYPTO_ALIAS(DSAPublicKey_it);
396
397 DSA *
d2i_DSAPublicKey(DSA ** a,const unsigned char ** in,long len)398 d2i_DSAPublicKey(DSA **a, const unsigned char **in, long len)
399 {
400 return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
401 &DSAPublicKey_it);
402 }
403 LCRYPTO_ALIAS(d2i_DSAPublicKey);
404
405 int
i2d_DSAPublicKey(const DSA * a,unsigned char ** out)406 i2d_DSAPublicKey(const DSA *a, unsigned char **out)
407 {
408 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPublicKey_it);
409 }
410 LCRYPTO_ALIAS(i2d_DSAPublicKey);
411
412 DSA *
DSAparams_dup(DSA * dsa)413 DSAparams_dup(DSA *dsa)
414 {
415 return ASN1_item_dup(&DSAparams_it, dsa);
416 }
417 LCRYPTO_ALIAS(DSAparams_dup);
418
419 int
DSA_sign(int type,const unsigned char * dgst,int dlen,unsigned char * sig,unsigned int * out_siglen,DSA * dsa)420 DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
421 unsigned int *out_siglen, DSA *dsa)
422 {
423 DSA_SIG *s;
424 int siglen;
425 int ret = 0;
426
427 *out_siglen = 0;
428
429 if ((s = DSA_do_sign(dgst, dlen, dsa)) == NULL)
430 goto err;
431
432 if ((siglen = i2d_DSA_SIG(s, &sig)) < 0)
433 goto err;
434
435 *out_siglen = siglen;
436
437 ret = 1;
438 err:
439 DSA_SIG_free(s);
440
441 return ret;
442 }
443 LCRYPTO_ALIAS(DSA_sign);
444
445 /*
446 * data has already been hashed (probably with SHA or SHA-1).
447 * returns
448 * 1: correct signature
449 * 0: incorrect signature
450 * -1: error
451 */
452 int
DSA_verify(int type,const unsigned char * dgst,int dgst_len,const unsigned char * sigbuf,int siglen,DSA * dsa)453 DSA_verify(int type, const unsigned char *dgst, int dgst_len,
454 const unsigned char *sigbuf, int siglen, DSA *dsa)
455 {
456 DSA_SIG *s = NULL;
457 unsigned char *der = NULL;
458 const unsigned char *p;
459 int ret = -1;
460
461 p = sigbuf;
462 if ((s = d2i_DSA_SIG(NULL, &p, siglen)) == NULL)
463 goto err;
464
465 /* Ensure signature uses DER and doesn't have trailing garbage */
466 if (i2d_DSA_SIG(s, &der) != siglen)
467 goto err;
468
469 if (memcmp(der, sigbuf, siglen) != 0)
470 goto err;
471
472 ret = DSA_do_verify(dgst, dgst_len, s, dsa);
473 err:
474 free(der);
475 DSA_SIG_free(s);
476
477 return ret;
478 }
479 LCRYPTO_ALIAS(DSA_verify);
480