Line data Source code
1 : /* tasn_dec.c */
2 : /*
3 : * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 : * 2000.
5 : */
6 : /* ====================================================================
7 : * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : *
13 : * 1. Redistributions of source code must retain the above copyright
14 : * notice, this list of conditions and the following disclaimer.
15 : *
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in
18 : * the documentation and/or other materials provided with the
19 : * distribution.
20 : *
21 : * 3. All advertising materials mentioning features or use of this
22 : * software must display the following acknowledgment:
23 : * "This product includes software developed by the OpenSSL Project
24 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 : *
26 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 : * endorse or promote products derived from this software without
28 : * prior written permission. For written permission, please contact
29 : * licensing@OpenSSL.org.
30 : *
31 : * 5. Products derived from this software may not be called "OpenSSL"
32 : * nor may "OpenSSL" appear in their names without prior written
33 : * permission of the OpenSSL Project.
34 : *
35 : * 6. Redistributions of any form whatsoever must retain the following
36 : * acknowledgment:
37 : * "This product includes software developed by the OpenSSL Project
38 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 : *
40 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 : * OF THE POSSIBILITY OF SUCH DAMAGE.
52 : * ====================================================================
53 : *
54 : * This product includes cryptographic software written by Eric Young
55 : * (eay@cryptsoft.com). This product includes software written by Tim
56 : * Hudson (tjh@cryptsoft.com).
57 : *
58 : */
59 :
60 : #include <stddef.h>
61 : #include <string.h>
62 : #include <openssl/asn1.h>
63 : #include <openssl/asn1t.h>
64 : #include <openssl/objects.h>
65 : #include <openssl/buffer.h>
66 : #include <openssl/err.h>
67 :
68 : static int asn1_check_eoc(const unsigned char **in, long len);
69 : static int asn1_find_end(const unsigned char **in, long len, char inf);
70 :
71 : static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
72 : char inf, int tag, int aclass, int depth);
73 :
74 : static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
75 :
76 : static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
77 : char *inf, char *cst,
78 : const unsigned char **in, long len,
79 : int exptag, int expclass, char opt, ASN1_TLC *ctx);
80 :
81 : static int asn1_template_ex_d2i(ASN1_VALUE **pval,
82 : const unsigned char **in, long len,
83 : const ASN1_TEMPLATE *tt, char opt,
84 : ASN1_TLC *ctx);
85 : static int asn1_template_noexp_d2i(ASN1_VALUE **val,
86 : const unsigned char **in, long len,
87 : const ASN1_TEMPLATE *tt, char opt,
88 : ASN1_TLC *ctx);
89 : static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
90 : const unsigned char **in, long len,
91 : const ASN1_ITEM *it,
92 : int tag, int aclass, char opt,
93 : ASN1_TLC *ctx);
94 :
95 : /* Table to convert tags to bit values, used for MSTRING type */
96 : static const unsigned long tag2bit[32] = {
97 : /* tags 0 - 3 */
98 : 0, 0, 0, B_ASN1_BIT_STRING,
99 : /* tags 4- 7 */
100 : B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
101 : /* tags 8-11 */
102 : B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
103 : /* tags 12-15 */
104 : B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
105 : /* tags 16-19 */
106 : B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
107 : /* tags 20-22 */
108 : B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
109 : /* tags 23-24 */
110 : B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
111 : /* tags 25-27 */
112 : B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
113 : /* tags 28-31 */
114 : B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
115 : };
116 :
117 14692 : unsigned long ASN1_tag2bit(int tag)
118 : {
119 32746 : if ((tag < 0) || (tag > 30))
120 : return 0;
121 32746 : return tag2bit[tag];
122 : }
123 :
124 : /* Macro to initialize and invalidate the cache */
125 :
126 : #define asn1_tlc_clear(c) if (c) (c)->valid = 0
127 : /* Version to avoid compiler warning about 'c' always non-NULL */
128 : #define asn1_tlc_clear_nc(c) (c)->valid = 0
129 :
130 : /*
131 : * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
132 : * function. 'in' points to a buffer to read the data from, in future we
133 : * will have more advanced versions that can input data a piece at a time and
134 : * this will simply be a special case.
135 : */
136 :
137 10254 : ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
138 : const unsigned char **in, long len,
139 : const ASN1_ITEM *it)
140 : {
141 : ASN1_TLC c;
142 10254 : ASN1_VALUE *ptmpval = NULL;
143 10254 : if (!pval)
144 : pval = &ptmpval;
145 10254 : asn1_tlc_clear_nc(&c);
146 10254 : if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
147 10254 : return *pval;
148 : return NULL;
149 : }
150 :
151 0 : int ASN1_template_d2i(ASN1_VALUE **pval,
152 : const unsigned char **in, long len,
153 : const ASN1_TEMPLATE *tt)
154 : {
155 : ASN1_TLC c;
156 0 : asn1_tlc_clear_nc(&c);
157 0 : return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
158 : }
159 :
160 : /*
161 : * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
162 : * tag mismatch return -1 to handle OPTIONAL
163 : */
164 :
165 162581 : int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
166 : const ASN1_ITEM *it,
167 : int tag, int aclass, char opt, ASN1_TLC *ctx)
168 : {
169 : const ASN1_TEMPLATE *tt, *errtt = NULL;
170 : const ASN1_COMPAT_FUNCS *cf;
171 : const ASN1_EXTERN_FUNCS *ef;
172 162581 : const ASN1_AUX *aux = it->funcs;
173 : ASN1_aux_cb *asn1_cb;
174 162581 : const unsigned char *p = NULL, *q;
175 : unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */
176 : unsigned char imphack = 0, oclass;
177 : char seq_eoc, seq_nolen, cst, isopt;
178 : long tmplen;
179 : int i;
180 : int otag;
181 : int ret = 0;
182 : ASN1_VALUE **pchptr, *ptmpval;
183 162581 : if (!pval)
184 : return 0;
185 162581 : if (aux && aux->asn1_cb)
186 11291 : asn1_cb = aux->asn1_cb;
187 : else
188 : asn1_cb = 0;
189 :
190 162581 : switch (it->itype) {
191 : case ASN1_ITYPE_PRIMITIVE:
192 93568 : if (it->templates) {
193 : /*
194 : * tagging or OPTIONAL is currently illegal on an item template
195 : * because the flags can't get passed down. In practice this
196 : * isn't a problem: we include the relevant flags from the item
197 : * template in the template itself.
198 : */
199 19564 : if ((tag != -1) || opt) {
200 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
201 : ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
202 0 : goto err;
203 : }
204 19564 : return asn1_template_ex_d2i(pval, in, len,
205 : it->templates, opt, ctx);
206 : }
207 74004 : return asn1_d2i_ex_primitive(pval, in, len, it,
208 : tag, aclass, opt, ctx);
209 : break;
210 :
211 : case ASN1_ITYPE_MSTRING:
212 18054 : p = *in;
213 : /* Just read in tag and class */
214 18054 : ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
215 : &p, len, -1, 0, 1, ctx);
216 18054 : if (!ret) {
217 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
218 0 : goto err;
219 : }
220 :
221 : /* Must be UNIVERSAL class */
222 18054 : if (oclass != V_ASN1_UNIVERSAL) {
223 : /* If OPTIONAL, assume this is OK */
224 0 : if (opt)
225 : return -1;
226 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
227 0 : goto err;
228 : }
229 : /* Check tag matches bit map */
230 36108 : if (!(ASN1_tag2bit(otag) & it->utype)) {
231 : /* If OPTIONAL, assume this is OK */
232 0 : if (opt)
233 : return -1;
234 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG);
235 0 : goto err;
236 : }
237 18054 : return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
238 :
239 : case ASN1_ITYPE_EXTERN:
240 : /* Use new style d2i */
241 : ef = it->funcs;
242 3362 : return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
243 :
244 : case ASN1_ITYPE_COMPAT:
245 : /* we must resort to old style evil hackery */
246 : cf = it->funcs;
247 :
248 : /* If OPTIONAL see if it is there */
249 0 : if (opt) {
250 : int exptag;
251 0 : p = *in;
252 0 : if (tag == -1)
253 0 : exptag = it->utype;
254 : else
255 : exptag = tag;
256 : /*
257 : * Don't care about anything other than presence of expected tag
258 : */
259 :
260 0 : ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
261 : &p, len, exptag, aclass, 1, ctx);
262 0 : if (!ret) {
263 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
264 0 : goto err;
265 : }
266 0 : if (ret == -1)
267 : return -1;
268 : }
269 :
270 : /*
271 : * This is the old style evil hack IMPLICIT handling: since the
272 : * underlying code is expecting a tag and class other than the one
273 : * present we change the buffer temporarily then change it back
274 : * afterwards. This doesn't and never did work for tags > 30. Yes
275 : * this is *horrible* but it is only needed for old style d2i which
276 : * will hopefully not be around for much longer. FIXME: should copy
277 : * the buffer then modify it so the input buffer can be const: we
278 : * should *always* copy because the old style d2i might modify the
279 : * buffer.
280 : */
281 :
282 0 : if (tag != -1) {
283 0 : wp = *(unsigned char **)in;
284 0 : imphack = *wp;
285 0 : if (p == NULL) {
286 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
287 0 : goto err;
288 : }
289 0 : *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
290 0 : | it->utype);
291 : }
292 :
293 0 : ptmpval = cf->asn1_d2i(pval, in, len);
294 :
295 0 : if (tag != -1)
296 0 : *wp = imphack;
297 :
298 0 : if (ptmpval)
299 : return 1;
300 :
301 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
302 0 : goto err;
303 :
304 : case ASN1_ITYPE_CHOICE:
305 6040 : if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
306 : goto auxerr;
307 6040 : if (*pval) {
308 : /* Free up and zero CHOICE value if initialised */
309 0 : i = asn1_get_choice_selector(pval, it);
310 0 : if ((i >= 0) && (i < it->tcount)) {
311 0 : tt = it->templates + i;
312 0 : pchptr = asn1_get_field_ptr(pval, tt);
313 0 : ASN1_template_free(pchptr, tt);
314 0 : asn1_set_choice_selector(pval, -1, it);
315 : }
316 6040 : } else if (!ASN1_item_ex_new(pval, it)) {
317 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
318 0 : goto err;
319 : }
320 : /* CHOICE type, try each possibility in turn */
321 6040 : p = *in;
322 51340 : for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
323 25670 : pchptr = asn1_get_field_ptr(pval, tt);
324 : /*
325 : * We mark field as OPTIONAL so its absence can be recognised.
326 : */
327 25670 : ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
328 : /* If field not present, try the next one */
329 25670 : if (ret == -1)
330 19630 : continue;
331 : /* If positive return, read OK, break loop */
332 6040 : if (ret > 0)
333 : break;
334 : /* Otherwise must be an ASN1 parsing error */
335 : errtt = tt;
336 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
337 0 : goto err;
338 : }
339 :
340 : /* Did we fall off the end without reading anything? */
341 6040 : if (i == it->tcount) {
342 : /* If OPTIONAL, this is OK */
343 0 : if (opt) {
344 : /* Free and zero it */
345 0 : ASN1_item_ex_free(pval, it);
346 0 : return -1;
347 : }
348 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
349 0 : goto err;
350 : }
351 :
352 6040 : asn1_set_choice_selector(pval, i, it);
353 6040 : *in = p;
354 6040 : if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
355 : goto auxerr;
356 : return 1;
357 :
358 : case ASN1_ITYPE_NDEF_SEQUENCE:
359 : case ASN1_ITYPE_SEQUENCE:
360 41557 : p = *in;
361 41557 : tmplen = len;
362 :
363 : /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
364 41557 : if (tag == -1) {
365 : tag = V_ASN1_SEQUENCE;
366 : aclass = V_ASN1_UNIVERSAL;
367 : }
368 : /* Get SEQUENCE length and update len, p */
369 41557 : ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
370 : &p, len, tag, aclass, opt, ctx);
371 41557 : if (!ret) {
372 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
373 0 : goto err;
374 41557 : } else if (ret == -1)
375 : return -1;
376 34007 : if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
377 0 : len = tmplen - (p - *in);
378 0 : seq_nolen = 1;
379 : }
380 : /* If indefinite we don't do a length check */
381 : else
382 34007 : seq_nolen = seq_eoc;
383 34007 : if (!cst) {
384 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
385 0 : goto err;
386 : }
387 :
388 34007 : if (!*pval && !ASN1_item_ex_new(pval, it)) {
389 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
390 0 : goto err;
391 : }
392 :
393 34007 : if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
394 : goto auxerr;
395 :
396 : /* Free up and zero any ADB found */
397 124062 : for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
398 90055 : if (tt->flags & ASN1_TFLG_ADB_MASK) {
399 : const ASN1_TEMPLATE *seqtt;
400 : ASN1_VALUE **pseqval;
401 0 : seqtt = asn1_do_adb(pval, tt, 1);
402 0 : pseqval = asn1_get_field_ptr(pval, seqtt);
403 0 : ASN1_template_free(pseqval, seqtt);
404 : }
405 : }
406 :
407 : /* Get each field entry */
408 121331 : for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
409 : const ASN1_TEMPLATE *seqtt;
410 : ASN1_VALUE **pseqval;
411 88478 : seqtt = asn1_do_adb(pval, tt, 1);
412 88478 : if (!seqtt)
413 : goto err;
414 88478 : pseqval = asn1_get_field_ptr(pval, seqtt);
415 : /* Have we ran out of data? */
416 88478 : if (!len)
417 : break;
418 87324 : q = p;
419 87324 : if (asn1_check_eoc(&p, len)) {
420 0 : if (!seq_eoc) {
421 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC);
422 0 : goto err;
423 : }
424 0 : len -= p - q;
425 0 : seq_eoc = 0;
426 : q = p;
427 0 : break;
428 : }
429 : /*
430 : * This determines the OPTIONAL flag value. The field cannot be
431 : * omitted if it is the last of a SEQUENCE and there is still
432 : * data to be read. This isn't strictly necessary but it
433 : * increases efficiency in some cases.
434 : */
435 87324 : if (i == (it->tcount - 1))
436 : isopt = 0;
437 : else
438 54471 : isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
439 : /*
440 : * attempt to read in field, allowing each to be OPTIONAL
441 : */
442 :
443 87324 : ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
444 87324 : if (!ret) {
445 : errtt = seqtt;
446 : goto err;
447 87324 : } else if (ret == -1) {
448 : /*
449 : * OPTIONAL component absent. Free and zero the field.
450 : */
451 6665 : ASN1_template_free(pseqval, seqtt);
452 6665 : continue;
453 : }
454 : /* Update length */
455 80659 : len -= p - q;
456 : }
457 :
458 : /* Check for EOC if expecting one */
459 34007 : if (seq_eoc && !asn1_check_eoc(&p, len)) {
460 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
461 0 : goto err;
462 : }
463 : /* Check all data read */
464 34007 : if (!seq_nolen && len) {
465 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
466 0 : goto err;
467 : }
468 :
469 : /*
470 : * If we get here we've got no more data in the SEQUENCE, however we
471 : * may not have read all fields so check all remaining are OPTIONAL
472 : * and clear any that are.
473 : */
474 39469 : for (; i < it->tcount; tt++, i++) {
475 : const ASN1_TEMPLATE *seqtt;
476 2731 : seqtt = asn1_do_adb(pval, tt, 1);
477 2731 : if (!seqtt)
478 : goto err;
479 2731 : if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
480 : ASN1_VALUE **pseqval;
481 2731 : pseqval = asn1_get_field_ptr(pval, seqtt);
482 2731 : ASN1_template_free(pseqval, seqtt);
483 : } else {
484 : errtt = seqtt;
485 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
486 0 : goto err;
487 : }
488 : }
489 : /* Save encoding */
490 34007 : if (!asn1_enc_save(pval, *in, p - *in, it))
491 : goto auxerr;
492 34007 : *in = p;
493 34007 : if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
494 : goto auxerr;
495 : return 1;
496 :
497 : default:
498 : return 0;
499 : }
500 : auxerr:
501 0 : ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
502 : err:
503 0 : ASN1_item_ex_free(pval, it);
504 0 : if (errtt)
505 0 : ERR_add_error_data(4, "Field=", errtt->field_name,
506 : ", Type=", it->sname);
507 : else
508 0 : ERR_add_error_data(2, "Type=", it->sname);
509 : return 0;
510 : }
511 :
512 : /*
513 : * Templates are handled with two separate functions. One handles any
514 : * EXPLICIT tag and the other handles the rest.
515 : */
516 :
517 132558 : static int asn1_template_ex_d2i(ASN1_VALUE **val,
518 : const unsigned char **in, long inlen,
519 : const ASN1_TEMPLATE *tt, char opt,
520 : ASN1_TLC *ctx)
521 : {
522 : int flags, aclass;
523 : int ret;
524 : long len;
525 : const unsigned char *p, *q;
526 : char exp_eoc;
527 132558 : if (!val)
528 : return 0;
529 132558 : flags = tt->flags;
530 132558 : aclass = flags & ASN1_TFLG_TAG_CLASS;
531 :
532 132558 : p = *in;
533 :
534 : /* Check if EXPLICIT tag expected */
535 132558 : if (flags & ASN1_TFLG_EXPTAG) {
536 : char cst;
537 : /*
538 : * Need to work out amount of data available to the inner content and
539 : * where it starts: so read in EXPLICIT header to get the info.
540 : */
541 8874 : ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
542 4437 : &p, inlen, tt->tag, aclass, opt, ctx);
543 4437 : q = p;
544 4437 : if (!ret) {
545 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
546 0 : return 0;
547 4437 : } else if (ret == -1)
548 : return -1;
549 2492 : if (!cst) {
550 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
551 : ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
552 0 : return 0;
553 : }
554 : /* We've found the field so it can't be OPTIONAL now */
555 2492 : ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
556 2492 : if (!ret) {
557 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
558 0 : return 0;
559 : }
560 : /* We read the field in OK so update length */
561 2492 : len -= p - q;
562 2492 : if (exp_eoc) {
563 : /* If NDEF we must have an EOC here */
564 0 : if (!asn1_check_eoc(&p, len)) {
565 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC);
566 0 : goto err;
567 : }
568 : } else {
569 : /*
570 : * Otherwise we must hit the EXPLICIT tag end or its an error
571 : */
572 2492 : if (len) {
573 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
574 : ASN1_R_EXPLICIT_LENGTH_MISMATCH);
575 0 : goto err;
576 : }
577 : }
578 : } else
579 128121 : return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
580 :
581 2492 : *in = p;
582 2492 : return 1;
583 :
584 : err:
585 0 : ASN1_template_free(val, tt);
586 0 : return 0;
587 : }
588 :
589 130613 : static int asn1_template_noexp_d2i(ASN1_VALUE **val,
590 : const unsigned char **in, long len,
591 : const ASN1_TEMPLATE *tt, char opt,
592 : ASN1_TLC *ctx)
593 : {
594 : int flags, aclass;
595 : int ret;
596 : const unsigned char *p, *q;
597 130613 : if (!val)
598 : return 0;
599 130613 : flags = tt->flags;
600 130613 : aclass = flags & ASN1_TFLG_TAG_CLASS;
601 :
602 130613 : p = *in;
603 : q = p;
604 :
605 130613 : if (flags & ASN1_TFLG_SK_MASK) {
606 : /* SET OF, SEQUENCE OF */
607 : int sktag, skaclass;
608 : char sk_eoc;
609 : /* First work out expected inner tag value */
610 20810 : if (flags & ASN1_TFLG_IMPTAG) {
611 0 : sktag = tt->tag;
612 : skaclass = aclass;
613 : } else {
614 : skaclass = V_ASN1_UNIVERSAL;
615 20810 : if (flags & ASN1_TFLG_SET_OF)
616 : sktag = V_ASN1_SET;
617 : else
618 : sktag = V_ASN1_SEQUENCE;
619 : }
620 : /* Get the tag */
621 20810 : ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
622 : &p, len, sktag, skaclass, opt, ctx);
623 20810 : if (!ret) {
624 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
625 0 : return 0;
626 20810 : } else if (ret == -1)
627 : return -1;
628 20810 : if (!*val)
629 20810 : *val = (ASN1_VALUE *)sk_new_null();
630 : else {
631 : /*
632 : * We've got a valid STACK: free up any items present
633 : */
634 : STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
635 : ASN1_VALUE *vtmp;
636 0 : while (sk_ASN1_VALUE_num(sktmp) > 0) {
637 0 : vtmp = sk_ASN1_VALUE_pop(sktmp);
638 0 : ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
639 : }
640 : }
641 :
642 20810 : if (!*val) {
643 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
644 0 : goto err;
645 : }
646 :
647 : /* Read as many items as we can */
648 59972 : while (len > 0) {
649 : ASN1_VALUE *skfield;
650 39162 : q = p;
651 : /* See if EOC found */
652 39162 : if (asn1_check_eoc(&p, len)) {
653 0 : if (!sk_eoc) {
654 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
655 : ASN1_R_UNEXPECTED_EOC);
656 0 : goto err;
657 : }
658 0 : len -= p - q;
659 0 : sk_eoc = 0;
660 0 : break;
661 : }
662 39162 : skfield = NULL;
663 39162 : if (!ASN1_item_ex_d2i(&skfield, &p, len,
664 39162 : ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
665 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
666 : ERR_R_NESTED_ASN1_ERROR);
667 0 : goto err;
668 : }
669 39162 : len -= p - q;
670 39162 : if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
671 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
672 0 : goto err;
673 : }
674 : }
675 20810 : if (sk_eoc) {
676 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
677 0 : goto err;
678 : }
679 109803 : } else if (flags & ASN1_TFLG_IMPTAG) {
680 : /* IMPLICIT tagging */
681 79956 : ret = ASN1_item_ex_d2i(val, &p, len,
682 53304 : ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
683 : ctx);
684 26652 : if (!ret) {
685 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
686 0 : goto err;
687 26652 : } else if (ret == -1)
688 : return -1;
689 : } else {
690 : /* Nothing special */
691 83151 : ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
692 : -1, 0, opt, ctx);
693 83151 : if (!ret) {
694 0 : ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
695 0 : goto err;
696 83151 : } else if (ret == -1)
697 : return -1;
698 : }
699 :
700 106263 : *in = p;
701 106263 : return 1;
702 :
703 : err:
704 0 : ASN1_template_free(val, tt);
705 0 : return 0;
706 : }
707 :
708 92058 : static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
709 : const unsigned char **in, long inlen,
710 : const ASN1_ITEM *it,
711 : int tag, int aclass, char opt, ASN1_TLC *ctx)
712 : {
713 : int ret = 0, utype;
714 : long plen;
715 92058 : char cst, inf, free_cont = 0;
716 : const unsigned char *p;
717 : BUF_MEM buf;
718 : const unsigned char *cont = NULL;
719 : long len;
720 92058 : if (!pval) {
721 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
722 0 : return 0; /* Should never happen */
723 : }
724 :
725 92058 : if (it->itype == ASN1_ITYPE_MSTRING) {
726 18054 : utype = tag;
727 : tag = -1;
728 : } else
729 74004 : utype = it->utype;
730 :
731 92058 : if (utype == V_ASN1_ANY) {
732 : /* If type is ANY need to figure out type from tag */
733 : unsigned char oclass;
734 5812 : if (tag >= 0) {
735 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
736 0 : return 0;
737 : }
738 5812 : if (opt) {
739 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
740 : ASN1_R_ILLEGAL_OPTIONAL_ANY);
741 0 : return 0;
742 : }
743 5812 : p = *in;
744 5812 : ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
745 : &p, inlen, -1, 0, 0, ctx);
746 5812 : if (!ret) {
747 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
748 0 : return 0;
749 : }
750 5812 : if (oclass != V_ASN1_UNIVERSAL)
751 0 : utype = V_ASN1_OTHER;
752 : }
753 92058 : if (tag == -1) {
754 72956 : tag = utype;
755 : aclass = V_ASN1_UNIVERSAL;
756 : }
757 92058 : p = *in;
758 : /* Check header */
759 92058 : ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
760 : &p, inlen, tag, aclass, opt, ctx);
761 92058 : if (!ret) {
762 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
763 0 : return 0;
764 92058 : } else if (ret == -1)
765 : return -1;
766 : ret = 0;
767 : /* SEQUENCE, SET and "OTHER" are left in encoded form */
768 75258 : if ((utype == V_ASN1_SEQUENCE)
769 75258 : || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
770 : /*
771 : * Clear context cache for type OTHER because the auto clear when we
772 : * have a exact match wont work
773 : */
774 0 : if (utype == V_ASN1_OTHER) {
775 0 : asn1_tlc_clear(ctx);
776 : }
777 : /* SEQUENCE and SET must be constructed */
778 0 : else if (!cst) {
779 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
780 : ASN1_R_TYPE_NOT_CONSTRUCTED);
781 0 : return 0;
782 : }
783 :
784 0 : cont = *in;
785 : /* If indefinite length constructed find the real end */
786 0 : if (inf) {
787 0 : if (!asn1_find_end(&p, plen, inf))
788 : goto err;
789 0 : len = p - cont;
790 : } else {
791 0 : len = p - cont + plen;
792 0 : p += plen;
793 0 : buf.data = NULL;
794 : }
795 75258 : } else if (cst) {
796 0 : if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
797 0 : || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
798 0 : || utype == V_ASN1_ENUMERATED) {
799 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE);
800 0 : return 0;
801 : }
802 0 : buf.length = 0;
803 0 : buf.max = 0;
804 0 : buf.data = NULL;
805 : /*
806 : * Should really check the internal tags are correct but some things
807 : * may get this wrong. The relevant specs say that constructed string
808 : * types should be OCTET STRINGs internally irrespective of the type.
809 : * So instead just check for UNIVERSAL class and ignore the tag.
810 : */
811 0 : if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
812 0 : free_cont = 1;
813 0 : goto err;
814 : }
815 0 : len = buf.length;
816 : /* Append a final null to string */
817 0 : if (!BUF_MEM_grow_clean(&buf, len + 1)) {
818 0 : ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
819 0 : return 0;
820 : }
821 0 : buf.data[len] = 0;
822 0 : cont = (const unsigned char *)buf.data;
823 0 : free_cont = 1;
824 : } else {
825 75258 : cont = p;
826 75258 : len = plen;
827 75258 : p += plen;
828 : }
829 :
830 : /* We now have content length and type: translate into a structure */
831 75258 : if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
832 : goto err;
833 :
834 75258 : *in = p;
835 : ret = 1;
836 : err:
837 75258 : if (free_cont && buf.data)
838 0 : OPENSSL_free(buf.data);
839 75258 : return ret;
840 : }
841 :
842 : /* Translate ASN1 content octets into a structure */
843 :
844 75258 : int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
845 : int utype, char *free_cont, const ASN1_ITEM *it)
846 : {
847 : ASN1_VALUE **opval = NULL;
848 : ASN1_STRING *stmp;
849 : ASN1_TYPE *typ = NULL;
850 : int ret = 0;
851 : const ASN1_PRIMITIVE_FUNCS *pf;
852 : ASN1_INTEGER **tint;
853 75258 : pf = it->funcs;
854 :
855 75258 : if (pf && pf->prim_c2i)
856 6328 : return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
857 : /* If ANY type clear type and set pointer to internal value */
858 68930 : if (it->utype == V_ASN1_ANY) {
859 5812 : if (!*pval) {
860 5800 : typ = ASN1_TYPE_new();
861 5800 : if (typ == NULL)
862 : goto err;
863 5800 : *pval = (ASN1_VALUE *)typ;
864 : } else
865 : typ = (ASN1_TYPE *)*pval;
866 :
867 5812 : if (utype != typ->type)
868 5812 : ASN1_TYPE_set(typ, utype, NULL);
869 : opval = pval;
870 5812 : pval = &typ->value.asn1_value;
871 : }
872 68930 : switch (utype) {
873 : case V_ASN1_OBJECT:
874 24230 : if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
875 : goto err;
876 : break;
877 :
878 : case V_ASN1_NULL:
879 5800 : if (len) {
880 0 : ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH);
881 0 : goto err;
882 : }
883 5800 : *pval = (ASN1_VALUE *)1;
884 5800 : break;
885 :
886 : case V_ASN1_BOOLEAN:
887 0 : if (len != 1) {
888 0 : ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
889 0 : goto err;
890 : } else {
891 : ASN1_BOOLEAN *tbool;
892 : tbool = (ASN1_BOOLEAN *)pval;
893 0 : *tbool = *cont;
894 : }
895 0 : break;
896 :
897 : case V_ASN1_BIT_STRING:
898 4069 : if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
899 : goto err;
900 : break;
901 :
902 : case V_ASN1_INTEGER:
903 : case V_ASN1_NEG_INTEGER:
904 : case V_ASN1_ENUMERATED:
905 : case V_ASN1_NEG_ENUMERATED:
906 : tint = (ASN1_INTEGER **)pval;
907 4407 : if (!c2i_ASN1_INTEGER(tint, &cont, len))
908 : goto err;
909 : /* Fixup type to match the expected form */
910 4407 : (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
911 4407 : break;
912 :
913 : case V_ASN1_OCTET_STRING:
914 : case V_ASN1_NUMERICSTRING:
915 : case V_ASN1_PRINTABLESTRING:
916 : case V_ASN1_T61STRING:
917 : case V_ASN1_VIDEOTEXSTRING:
918 : case V_ASN1_IA5STRING:
919 : case V_ASN1_UTCTIME:
920 : case V_ASN1_GENERALIZEDTIME:
921 : case V_ASN1_GRAPHICSTRING:
922 : case V_ASN1_VISIBLESTRING:
923 : case V_ASN1_GENERALSTRING:
924 : case V_ASN1_UNIVERSALSTRING:
925 : case V_ASN1_BMPSTRING:
926 : case V_ASN1_UTF8STRING:
927 : case V_ASN1_OTHER:
928 : case V_ASN1_SET:
929 : case V_ASN1_SEQUENCE:
930 : default:
931 30424 : if (utype == V_ASN1_BMPSTRING && (len & 1)) {
932 0 : ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
933 0 : goto err;
934 : }
935 30424 : if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
936 0 : ASN1err(ASN1_F_ASN1_EX_C2I,
937 : ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
938 0 : goto err;
939 : }
940 : /* All based on ASN1_STRING and handled the same */
941 30424 : if (!*pval) {
942 6052 : stmp = ASN1_STRING_type_new(utype);
943 6052 : if (!stmp) {
944 0 : ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
945 0 : goto err;
946 : }
947 6052 : *pval = (ASN1_VALUE *)stmp;
948 : } else {
949 : stmp = (ASN1_STRING *)*pval;
950 24372 : stmp->type = utype;
951 : }
952 : /* If we've already allocated a buffer use it */
953 30424 : if (*free_cont) {
954 0 : if (stmp->data)
955 0 : OPENSSL_free(stmp->data);
956 0 : stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
957 0 : stmp->length = len;
958 0 : *free_cont = 0;
959 : } else {
960 30424 : if (!ASN1_STRING_set(stmp, cont, len)) {
961 0 : ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
962 0 : ASN1_STRING_free(stmp);
963 0 : *pval = NULL;
964 0 : goto err;
965 : }
966 : }
967 : break;
968 : }
969 : /* If ASN1_ANY and NULL type fix up value */
970 68930 : if (typ && (utype == V_ASN1_NULL))
971 5800 : typ->value.ptr = NULL;
972 :
973 : ret = 1;
974 : err:
975 68930 : if (!ret) {
976 0 : ASN1_TYPE_free(typ);
977 0 : if (opval)
978 0 : *opval = NULL;
979 : }
980 68930 : return ret;
981 : }
982 :
983 : /*
984 : * This function finds the end of an ASN1 structure when passed its maximum
985 : * length, whether it is indefinite length and a pointer to the content. This
986 : * is more efficient than calling asn1_collect because it does not recurse on
987 : * each indefinite length header.
988 : */
989 :
990 0 : static int asn1_find_end(const unsigned char **in, long len, char inf)
991 : {
992 : int expected_eoc;
993 : long plen;
994 0 : const unsigned char *p = *in, *q;
995 : /* If not indefinite length constructed just add length */
996 0 : if (inf == 0) {
997 0 : *in += len;
998 0 : return 1;
999 : }
1000 : expected_eoc = 1;
1001 : /*
1002 : * Indefinite length constructed form. Find the end when enough EOCs are
1003 : * found. If more indefinite length constructed headers are encountered
1004 : * increment the expected eoc count otherwise just skip to the end of the
1005 : * data.
1006 : */
1007 0 : while (len > 0) {
1008 0 : if (asn1_check_eoc(&p, len)) {
1009 0 : expected_eoc--;
1010 0 : if (expected_eoc == 0)
1011 : break;
1012 0 : len -= 2;
1013 0 : continue;
1014 : }
1015 0 : q = p;
1016 : /* Just read in a header: only care about the length */
1017 0 : if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
1018 : -1, 0, 0, NULL)) {
1019 0 : ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
1020 0 : return 0;
1021 : }
1022 0 : if (inf)
1023 0 : expected_eoc++;
1024 : else
1025 0 : p += plen;
1026 0 : len -= p - q;
1027 : }
1028 0 : if (expected_eoc) {
1029 0 : ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
1030 0 : return 0;
1031 : }
1032 0 : *in = p;
1033 0 : return 1;
1034 : }
1035 :
1036 : /*
1037 : * This function collects the asn1 data from a constructred string type into
1038 : * a buffer. The values of 'in' and 'len' should refer to the contents of the
1039 : * constructed type and 'inf' should be set if it is indefinite length.
1040 : */
1041 :
1042 : #ifndef ASN1_MAX_STRING_NEST
1043 : /*
1044 : * This determines how many levels of recursion are permitted in ASN1 string
1045 : * types. If it is not limited stack overflows can occur. If set to zero no
1046 : * recursion is allowed at all. Although zero should be adequate examples
1047 : * exist that require a value of 1. So 5 should be more than enough.
1048 : */
1049 : # define ASN1_MAX_STRING_NEST 5
1050 : #endif
1051 :
1052 0 : static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
1053 : char inf, int tag, int aclass, int depth)
1054 : {
1055 : const unsigned char *p, *q;
1056 : long plen;
1057 : char cst, ininf;
1058 0 : p = *in;
1059 0 : inf &= 1;
1060 : /*
1061 : * If no buffer and not indefinite length constructed just pass over the
1062 : * encoded data
1063 : */
1064 0 : if (!buf && !inf) {
1065 0 : *in += len;
1066 0 : return 1;
1067 : }
1068 0 : while (len > 0) {
1069 0 : q = p;
1070 : /* Check for EOC */
1071 0 : if (asn1_check_eoc(&p, len)) {
1072 : /*
1073 : * EOC is illegal outside indefinite length constructed form
1074 : */
1075 0 : if (!inf) {
1076 0 : ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
1077 0 : return 0;
1078 : }
1079 : inf = 0;
1080 : break;
1081 : }
1082 :
1083 0 : if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
1084 : len, tag, aclass, 0, NULL)) {
1085 0 : ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
1086 0 : return 0;
1087 : }
1088 :
1089 : /* If indefinite length constructed update max length */
1090 0 : if (cst) {
1091 0 : if (depth >= ASN1_MAX_STRING_NEST) {
1092 0 : ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
1093 0 : return 0;
1094 : }
1095 0 : if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
1096 : return 0;
1097 0 : } else if (plen && !collect_data(buf, &p, plen))
1098 : return 0;
1099 0 : len -= p - q;
1100 : }
1101 0 : if (inf) {
1102 0 : ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
1103 0 : return 0;
1104 : }
1105 0 : *in = p;
1106 0 : return 1;
1107 : }
1108 :
1109 0 : static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
1110 : {
1111 : int len;
1112 0 : if (buf) {
1113 0 : len = buf->length;
1114 0 : if (!BUF_MEM_grow_clean(buf, len + plen)) {
1115 0 : ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
1116 0 : return 0;
1117 : }
1118 0 : memcpy(buf->data + len, *p, plen);
1119 : }
1120 0 : *p += plen;
1121 0 : return 1;
1122 : }
1123 :
1124 : /* Check for ASN1 EOC and swallow it if found */
1125 :
1126 : static int asn1_check_eoc(const unsigned char **in, long len)
1127 : {
1128 : const unsigned char *p;
1129 126486 : if (len < 2)
1130 : return 0;
1131 0 : p = *in;
1132 126486 : if (!p[0] && !p[1]) {
1133 0 : *in += 2;
1134 : return 1;
1135 : }
1136 : return 0;
1137 : }
1138 :
1139 : /*
1140 : * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
1141 : * length for indefinite length constructed form, we don't know the exact
1142 : * length but we can set an upper bound to the amount of data available minus
1143 : * the header length just read.
1144 : */
1145 :
1146 182728 : static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
1147 : char *inf, char *cst,
1148 : const unsigned char **in, long len,
1149 : int exptag, int expclass, char opt, ASN1_TLC *ctx)
1150 : {
1151 : int i;
1152 : int ptag, pclass;
1153 : long plen;
1154 : const unsigned char *p, *q;
1155 182728 : p = *in;
1156 : q = p;
1157 :
1158 182728 : if (ctx && ctx->valid) {
1159 50161 : i = ctx->ret;
1160 50161 : plen = ctx->plen;
1161 50161 : pclass = ctx->pclass;
1162 50161 : ptag = ctx->ptag;
1163 50161 : p += ctx->hdrlen;
1164 : } else {
1165 132567 : i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
1166 132567 : if (ctx) {
1167 132567 : ctx->ret = i;
1168 132567 : ctx->plen = plen;
1169 132567 : ctx->pclass = pclass;
1170 132567 : ctx->ptag = ptag;
1171 132567 : ctx->hdrlen = p - q;
1172 132567 : ctx->valid = 1;
1173 : /*
1174 : * If definite length, and no error, length + header can't exceed
1175 : * total amount of data available.
1176 : */
1177 132567 : if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
1178 0 : ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
1179 0 : asn1_tlc_clear(ctx);
1180 : return 0;
1181 : }
1182 : }
1183 : }
1184 :
1185 182728 : if (i & 0x80) {
1186 0 : ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
1187 0 : asn1_tlc_clear(ctx);
1188 : return 0;
1189 : }
1190 182728 : if (exptag >= 0) {
1191 158862 : if ((exptag != ptag) || (expclass != pclass)) {
1192 : /*
1193 : * If type is OPTIONAL, not an error: indicate missing type.
1194 : */
1195 26295 : if (opt)
1196 : return -1;
1197 0 : asn1_tlc_clear(ctx);
1198 0 : ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
1199 0 : return 0;
1200 : }
1201 : /*
1202 : * We have a tag and class match: assume we are going to do something
1203 : * with it
1204 : */
1205 132567 : asn1_tlc_clear(ctx);
1206 : }
1207 :
1208 156433 : if (i & 1)
1209 0 : plen = len - (p - q);
1210 :
1211 156433 : if (inf)
1212 132567 : *inf = i & 1;
1213 :
1214 156433 : if (cst)
1215 111757 : *cst = i & V_ASN1_CONSTRUCTED;
1216 :
1217 156433 : if (olen)
1218 132567 : *olen = plen;
1219 :
1220 156433 : if (oclass)
1221 23866 : *oclass = pclass;
1222 :
1223 156433 : if (otag)
1224 23866 : *otag = ptag;
1225 :
1226 156433 : *in = p;
1227 156433 : return 1;
1228 : }
|