Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / boringssl / crypto / dsa / dsa_asn1.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }