• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 2000. */
3 /* ====================================================================
4  * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this
19  *    software must display the following acknowledgment:
20  *    "This product includes software developed by the OpenSSL Project
21  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
22  *
23  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24  *    endorse or promote products derived from this software without
25  *    prior written permission. For written permission, please contact
26  *    licensing@OpenSSL.org.
27  *
28  * 5. Products derived from this software may not be called "OpenSSL"
29  *    nor may "OpenSSL" appear in their names without prior written
30  *    permission of the OpenSSL Project.
31  *
32  * 6. Redistributions of any form whatsoever must retain the following
33  *    acknowledgment:
34  *    "This product includes software developed by the OpenSSL Project
35  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48  * OF THE POSSIBILITY OF SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This product includes cryptographic software written by Eric Young
52  * (eay@cryptsoft.com).  This product includes software written by Tim
53  * Hudson (tjh@cryptsoft.com). */
54 
55 #include <openssl/dsa.h>
56 
57 #include <assert.h>
58 
59 #include <openssl/bn.h>
60 #include <openssl/bytestring.h>
61 #include <openssl/err.h>
62 #include <openssl/mem.h>
63 
64 #include "../bytestring/internal.h"
65 
66 
parse_integer(CBS * cbs,BIGNUM ** out)67 static int parse_integer(CBS *cbs, BIGNUM **out) {
68   assert(*out == NULL);
69   *out = BN_new();
70   if (*out == NULL) {
71     return 0;
72   }
73   return BN_parse_asn1_unsigned(cbs, *out);
74 }
75 
marshal_integer(CBB * cbb,BIGNUM * bn)76 static int marshal_integer(CBB *cbb, BIGNUM *bn) {
77   if (bn == NULL) {
78     // A DSA object may be missing some components.
79     OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER);
80     return 0;
81   }
82   return BN_marshal_asn1(cbb, bn);
83 }
84 
DSA_SIG_parse(CBS * cbs)85 DSA_SIG *DSA_SIG_parse(CBS *cbs) {
86   DSA_SIG *ret = DSA_SIG_new();
87   if (ret == NULL) {
88     return NULL;
89   }
90   CBS child;
91   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
92       !parse_integer(&child, &ret->r) ||
93       !parse_integer(&child, &ret->s) ||
94       CBS_len(&child) != 0) {
95     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
96     DSA_SIG_free(ret);
97     return NULL;
98   }
99   return ret;
100 }
101 
DSA_SIG_marshal(CBB * cbb,const DSA_SIG * sig)102 int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) {
103   CBB child;
104   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
105       !marshal_integer(&child, sig->r) ||
106       !marshal_integer(&child, sig->s) ||
107       !CBB_flush(cbb)) {
108     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
109     return 0;
110   }
111   return 1;
112 }
113 
DSA_parse_public_key(CBS * cbs)114 DSA *DSA_parse_public_key(CBS *cbs) {
115   DSA *ret = DSA_new();
116   if (ret == NULL) {
117     return NULL;
118   }
119   CBS child;
120   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
121       !parse_integer(&child, &ret->pub_key) ||
122       !parse_integer(&child, &ret->p) ||
123       !parse_integer(&child, &ret->q) ||
124       !parse_integer(&child, &ret->g) ||
125       CBS_len(&child) != 0) {
126     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
127     DSA_free(ret);
128     return NULL;
129   }
130   return ret;
131 }
132 
DSA_marshal_public_key(CBB * cbb,const DSA * dsa)133 int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) {
134   CBB child;
135   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
136       !marshal_integer(&child, dsa->pub_key) ||
137       !marshal_integer(&child, dsa->p) ||
138       !marshal_integer(&child, dsa->q) ||
139       !marshal_integer(&child, dsa->g) ||
140       !CBB_flush(cbb)) {
141     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
142     return 0;
143   }
144   return 1;
145 }
146 
DSA_parse_parameters(CBS * cbs)147 DSA *DSA_parse_parameters(CBS *cbs) {
148   DSA *ret = DSA_new();
149   if (ret == NULL) {
150     return NULL;
151   }
152   CBS child;
153   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
154       !parse_integer(&child, &ret->p) ||
155       !parse_integer(&child, &ret->q) ||
156       !parse_integer(&child, &ret->g) ||
157       CBS_len(&child) != 0) {
158     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
159     DSA_free(ret);
160     return NULL;
161   }
162   return ret;
163 }
164 
DSA_marshal_parameters(CBB * cbb,const DSA * dsa)165 int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) {
166   CBB child;
167   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
168       !marshal_integer(&child, dsa->p) ||
169       !marshal_integer(&child, dsa->q) ||
170       !marshal_integer(&child, dsa->g) ||
171       !CBB_flush(cbb)) {
172     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
173     return 0;
174   }
175   return 1;
176 }
177 
DSA_parse_private_key(CBS * cbs)178 DSA *DSA_parse_private_key(CBS *cbs) {
179   DSA *ret = DSA_new();
180   if (ret == NULL) {
181     return NULL;
182   }
183 
184   CBS child;
185   uint64_t version;
186   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
187       !CBS_get_asn1_uint64(&child, &version)) {
188     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
189     goto err;
190   }
191 
192   if (version != 0) {
193     OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION);
194     goto err;
195   }
196 
197   if (!parse_integer(&child, &ret->p) ||
198       !parse_integer(&child, &ret->q) ||
199       !parse_integer(&child, &ret->g) ||
200       !parse_integer(&child, &ret->pub_key) ||
201       !parse_integer(&child, &ret->priv_key) ||
202       CBS_len(&child) != 0) {
203     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
204     goto err;
205   }
206   return ret;
207 
208 err:
209   DSA_free(ret);
210   return NULL;
211 }
212 
DSA_marshal_private_key(CBB * cbb,const DSA * dsa)213 int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) {
214   CBB child;
215   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
216       !CBB_add_asn1_uint64(&child, 0 /* version */) ||
217       !marshal_integer(&child, dsa->p) ||
218       !marshal_integer(&child, dsa->q) ||
219       !marshal_integer(&child, dsa->g) ||
220       !marshal_integer(&child, dsa->pub_key) ||
221       !marshal_integer(&child, dsa->priv_key) ||
222       !CBB_flush(cbb)) {
223     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
224     return 0;
225   }
226   return 1;
227 }
228 
d2i_DSA_SIG(DSA_SIG ** out_sig,const uint8_t ** inp,long len)229 DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) {
230   if (len < 0) {
231     return NULL;
232   }
233   CBS cbs;
234   CBS_init(&cbs, *inp, (size_t)len);
235   DSA_SIG *ret = DSA_SIG_parse(&cbs);
236   if (ret == NULL) {
237     return NULL;
238   }
239   if (out_sig != NULL) {
240     DSA_SIG_free(*out_sig);
241     *out_sig = ret;
242   }
243   *inp = CBS_data(&cbs);
244   return ret;
245 }
246 
i2d_DSA_SIG(const DSA_SIG * in,uint8_t ** outp)247 int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) {
248   CBB cbb;
249   if (!CBB_init(&cbb, 0) ||
250       !DSA_SIG_marshal(&cbb, in)) {
251     CBB_cleanup(&cbb);
252     return -1;
253   }
254   return CBB_finish_i2d(&cbb, outp);
255 }
256 
d2i_DSAPublicKey(DSA ** out,const uint8_t ** inp,long len)257 DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) {
258   if (len < 0) {
259     return NULL;
260   }
261   CBS cbs;
262   CBS_init(&cbs, *inp, (size_t)len);
263   DSA *ret = DSA_parse_public_key(&cbs);
264   if (ret == NULL) {
265     return NULL;
266   }
267   if (out != NULL) {
268     DSA_free(*out);
269     *out = ret;
270   }
271   *inp = CBS_data(&cbs);
272   return ret;
273 }
274 
i2d_DSAPublicKey(const DSA * in,uint8_t ** outp)275 int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) {
276   CBB cbb;
277   if (!CBB_init(&cbb, 0) ||
278       !DSA_marshal_public_key(&cbb, in)) {
279     CBB_cleanup(&cbb);
280     return -1;
281   }
282   return CBB_finish_i2d(&cbb, outp);
283 }
284 
d2i_DSAPrivateKey(DSA ** out,const uint8_t ** inp,long len)285 DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) {
286   if (len < 0) {
287     return NULL;
288   }
289   CBS cbs;
290   CBS_init(&cbs, *inp, (size_t)len);
291   DSA *ret = DSA_parse_private_key(&cbs);
292   if (ret == NULL) {
293     return NULL;
294   }
295   if (out != NULL) {
296     DSA_free(*out);
297     *out = ret;
298   }
299   *inp = CBS_data(&cbs);
300   return ret;
301 }
302 
i2d_DSAPrivateKey(const DSA * in,uint8_t ** outp)303 int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) {
304   CBB cbb;
305   if (!CBB_init(&cbb, 0) ||
306       !DSA_marshal_private_key(&cbb, in)) {
307     CBB_cleanup(&cbb);
308     return -1;
309   }
310   return CBB_finish_i2d(&cbb, outp);
311 }
312 
d2i_DSAparams(DSA ** out,const uint8_t ** inp,long len)313 DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) {
314   if (len < 0) {
315     return NULL;
316   }
317   CBS cbs;
318   CBS_init(&cbs, *inp, (size_t)len);
319   DSA *ret = DSA_parse_parameters(&cbs);
320   if (ret == NULL) {
321     return NULL;
322   }
323   if (out != NULL) {
324     DSA_free(*out);
325     *out = ret;
326   }
327   *inp = CBS_data(&cbs);
328   return ret;
329 }
330 
i2d_DSAparams(const DSA * in,uint8_t ** outp)331 int i2d_DSAparams(const DSA *in, uint8_t **outp) {
332   CBB cbb;
333   if (!CBB_init(&cbb, 0) ||
334       !DSA_marshal_parameters(&cbb, in)) {
335     CBB_cleanup(&cbb);
336     return -1;
337   }
338   return CBB_finish_i2d(&cbb, outp);
339 }
340