Don't use 'tt' uninitialized when reporting an error
[openssl.git] / crypto / asn1 / tasn_dec.c
1 /* tasn_dec.c */
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 2000 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
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(unsigned char **in, long len);
69 static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass);
70 static int collect_data(BUF_MEM *buf, unsigned char **p, long plen);
71 static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst,
72                         unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx);
73 static int asn1_template_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx);
74 static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx);
75 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len,
76                                         const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx);
77
78 /* Macro to initialize and invalidate the cache */
79
80 #define asn1_tlc_clear(c)       if(c) (c)->valid = 0
81
82 /* Decode an ASN1 item, this currently behaves just 
83  * like a standard 'd2i' function. 'in' points to 
84  * a buffer to read the data from, in future we will
85  * have more advanced versions that can input data
86  * a piece at a time and this will simply be a special
87  * case.
88  */
89
90 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it)
91 {
92         ASN1_TLC c;
93         ASN1_VALUE *ptmpval = NULL;
94         if(!pval) pval = &ptmpval;
95         asn1_tlc_clear(&c);
96         if(ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
97                 return *pval;
98         return NULL;
99 }
100
101 int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt)
102 {
103         ASN1_TLC c;
104         asn1_tlc_clear(&c);
105         return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
106 }
107
108
109 /* Decode an item, taking care of IMPLICIT tagging, if any.
110  * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
111  */
112
113 int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it,
114                                 int tag, int aclass, char opt, ASN1_TLC *ctx)
115 {
116         const ASN1_TEMPLATE *tt, *errtt = NULL;
117         const ASN1_COMPAT_FUNCS *cf;
118         const ASN1_EXTERN_FUNCS *ef;
119         const ASN1_AUX *aux = it->funcs;
120         ASN1_aux_cb *asn1_cb;
121         unsigned char *p, *q, imphack = 0, oclass;
122         char seq_eoc, seq_nolen, cst, isopt;
123         long tmplen;
124         int i;
125         int otag;
126         int ret = 0;
127         ASN1_VALUE *pchval, **pchptr, *ptmpval;
128         if(!pval) return 0;
129         if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb;
130         else asn1_cb = 0;
131
132         switch(it->itype) {
133
134                 case ASN1_ITYPE_PRIMITIVE:
135                 if(it->templates) {
136                         /* tagging or OPTIONAL is currently illegal on an item template
137                          * because the flags can't get passed down. In practice this isn't
138                          * a problem: we include the relevant flags from the item template
139                          * in the template itself.
140                          */
141                         if ((tag != -1) || opt) {
142                                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
143                                 goto err;
144                         }
145                         return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx);
146                 }
147                 return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx);
148                 break;
149
150                 case ASN1_ITYPE_MSTRING:
151                 p = *in;
152                 /* Just read in tag and class */
153                 ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx);
154                 if(!ret) {
155                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
156                         goto err;
157                 } 
158                 /* Must be UNIVERSAL class */
159                 if(oclass != V_ASN1_UNIVERSAL) {
160                         /* If OPTIONAL, assume this is OK */
161                         if(opt) return -1;
162                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
163                         goto err;
164                 } 
165                 /* Check tag matches bit map */
166                 if(!(ASN1_tag2bit(otag) & it->utype)) {
167                         /* If OPTIONAL, assume this is OK */
168                         if(opt) return -1;
169                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG);
170                         goto err;
171                 } 
172                 return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
173
174                 case ASN1_ITYPE_EXTERN:
175                 /* Use new style d2i */
176                 ef = it->funcs;
177                 return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
178
179                 case ASN1_ITYPE_COMPAT:
180                 /* we must resort to old style evil hackery */
181                 cf = it->funcs;
182
183                 /* If OPTIONAL see if it is there */
184                 if(opt) {
185                         int exptag;
186                         p = *in;
187                         if(tag == -1) exptag = it->utype;
188                         else exptag = tag;
189                         /* Don't care about anything other than presence of expected tag */
190                         ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, &p, len, exptag, aclass, 1, ctx);
191                         if(!ret) {
192                                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
193                                 goto err;
194                         }
195                         if(ret == -1) return -1;
196                 }
197                 /* This is the old style evil hack IMPLICIT handling:
198                  * since the underlying code is expecting a tag and
199                  * class other than the one present we change the
200                  * buffer temporarily then change it back afterwards.
201                  * This doesn't and never did work for tags > 30.
202                  *
203                  * Yes this is *horrible* but it is only needed for
204                  * old style d2i which will hopefully not be around
205                  * for much longer.
206                  * FIXME: should copy the buffer then modify it so
207                  * the input buffer can be const: we should *always*
208                  * copy because the old style d2i might modify the
209                  * buffer.
210                  */
211
212                 if(tag != -1) {
213                         p = *in;
214                         imphack = *p;
215                         *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype);
216                 }
217
218                 ptmpval = cf->asn1_d2i(pval, in, len);
219
220                 if(tag != -1) *p = imphack;
221
222                 if(ptmpval) return 1;
223                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
224                 goto err;
225
226
227                 case ASN1_ITYPE_CHOICE:
228                 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
229                                 goto auxerr;
230
231                 /* Allocate structure */
232                 if(!*pval) {
233                         if(!ASN1_item_ex_new(pval, it)) {
234                                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
235                                 goto err;
236                         }
237                 }
238                 /* CHOICE type, try each possibility in turn */
239                 pchval = NULL;
240                 p = *in;
241                 for(i = 0, tt=it->templates; i < it->tcount; i++, tt++) {
242                         pchptr = asn1_get_field_ptr(pval, tt);
243                         /* We mark field as OPTIONAL so its absence
244                          * can be recognised.
245                          */
246                         ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
247                         /* If field not present, try the next one */
248                         if(ret == -1) continue;
249                         /* If positive return, read OK, break loop */
250                         if(ret > 0) break;
251                         /* Otherwise must be an ASN1 parsing error */
252                         errtt = tt;
253                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
254                         goto err;
255                 }
256                 /* Did we fall off the end without reading anything? */
257                 if(i == it->tcount) {
258                         /* If OPTIONAL, this is OK */
259                         if(opt) {
260                                 /* Free and zero it */
261                                 ASN1_item_ex_free(pval, it);
262                                 return -1;
263                         }
264                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
265                         goto err;
266                 }
267                 asn1_set_choice_selector(pval, i, it);
268                 *in = p;
269                 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
270                                 goto auxerr;
271                 return 1;
272
273                 case ASN1_ITYPE_SEQUENCE:
274                 p = *in;
275                 tmplen = len;
276
277                 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
278                 if(tag == -1) {
279                         tag = V_ASN1_SEQUENCE;
280                         aclass = V_ASN1_UNIVERSAL;
281                 }
282                 /* Get SEQUENCE length and update len, p */
283                 ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx);
284                 if(!ret) {
285                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
286                         goto err;
287                 } else if(ret == -1) return -1;
288                 if(aux && (aux->flags & ASN1_AFLG_BROKEN)) {
289                         len = tmplen - (p - *in);
290                         seq_nolen = 1;
291                 } else seq_nolen = seq_eoc;     /* If indefinite we don't do a length check */
292                 if(!cst) {
293                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
294                         goto err;
295                 }
296
297                 if(!*pval) {
298                         if(!ASN1_item_ex_new(pval, it)) {
299                                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
300                                 goto err;
301                         }
302                 }
303                 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
304                                 goto auxerr;
305
306                 /* Get each field entry */
307                 for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
308                         const ASN1_TEMPLATE *seqtt;
309                         ASN1_VALUE **pseqval;
310                         seqtt = asn1_do_adb(pval, tt, 1);
311                         if(!seqtt) goto err;
312                         pseqval = asn1_get_field_ptr(pval, seqtt);
313                         /* Have we ran out of data? */
314                         if(!len) break;
315                         q = p;
316                         if(asn1_check_eoc(&p, len)) {
317                                 if(!seq_eoc) {
318                                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC);
319                                         goto err;
320                                 }
321                                 len -= p - q;
322                                 seq_eoc = 0;
323                                 q = p;
324                                 break;
325                         }
326                         /* This determines the OPTIONAL flag value. The field cannot
327                          * be omitted if it is the last of a SEQUENCE and there is
328                          * still data to be read. This isn't strictly necessary but
329                          * it increases efficiency in some cases.
330                          */
331                         if(i == (it->tcount - 1)) isopt = 0;
332                         else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
333                         /* attempt to read in field, allowing each to be OPTIONAL */
334                         ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
335                         if(!ret) {
336                                 errtt = seqtt;
337                                 goto err;
338                         } else if(ret == -1) {
339                                 /* OPTIONAL component absent. Free and zero the field
340                                  */
341                                 ASN1_template_free(pseqval, seqtt);
342                                 continue;
343                         }
344                         /* Update length */
345                         len -= p - q;
346                 }
347                 /* Check for EOC if expecting one */
348                 if(seq_eoc && !asn1_check_eoc(&p, len)) {
349                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
350                         goto err;
351                 }
352                 /* Check all data read */
353                 if(!seq_nolen && len) {
354                         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
355                         goto err;
356                 }
357
358                 /* If we get here we've got no more data in the SEQUENCE,
359                  * however we may not have read all fields so check all
360                  * remaining are OPTIONAL and clear any that are.
361                  */
362                 for(; i < it->tcount; tt++, i++) {
363                         const ASN1_TEMPLATE *seqtt;
364                         seqtt = asn1_do_adb(pval, tt, 1);
365                         if(!seqtt) goto err;
366                         if(seqtt->flags & ASN1_TFLG_OPTIONAL) {
367                                 ASN1_VALUE **pseqval;
368                                 pseqval = asn1_get_field_ptr(pval, seqtt);
369                                 ASN1_template_free(pseqval, seqtt);
370                         } else {
371                                 errtt = seqtt;
372                                 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
373                                 goto err;
374                         }
375                 }
376                 /* Save encoding */
377                 if(!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr;
378                 *in = p;
379                 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
380                                 goto auxerr;
381                 return 1;
382
383                 default:
384                 return 0;
385         }
386         auxerr:
387         ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
388         err:
389         ASN1_item_ex_free(pval, it);
390         if(errtt) ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname);
391         else ERR_add_error_data(2, "Type=", it->sname);
392         return 0;
393 }
394
395 /* Templates are handled with two separate functions. One handles any EXPLICIT tag and the other handles the
396  * rest.
397  */
398
399 int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
400 {
401         int flags, aclass;
402         int ret;
403         long len;
404         unsigned char *p, *q;
405         char exp_eoc;
406         if(!val) return 0;
407         flags = tt->flags;
408         aclass = flags & ASN1_TFLG_TAG_CLASS;
409
410         p = *in;
411
412         /* Check if EXPLICIT tag expected */
413         if(flags & ASN1_TFLG_EXPTAG) {
414                 char cst;
415                 /* Need to work out amount of data available to the inner content and where it
416                  * starts: so read in EXPLICIT header to get the info.
417                  */
418                 ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, &p, inlen, tt->tag, aclass, opt, ctx);
419                 q = p;
420                 if(!ret) {
421                         ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
422                         return 0;
423                 } else if(ret == -1) return -1;
424                 if(!cst) {
425                         ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
426                         return 0;
427                 }
428                 /* We've found the field so it can't be OPTIONAL now */
429                 ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
430                 if(!ret) {
431                         ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
432                         return 0;
433                 }
434                 /* We read the field in OK so update length */
435                 len -= p - q;
436                 if(exp_eoc) {
437                         /* If NDEF we must have an EOC here */
438                         if(!asn1_check_eoc(&p, len)) {
439                                 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
440                                 goto err;
441                         }
442                 } else {
443                         /* Otherwise we must hit the EXPLICIT tag end or its an error */
444                         if(len) {
445                                 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
446                                 goto err;
447                         }
448                 }
449         } else 
450                 return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
451
452         *in = p;
453         return 1;
454
455         err:
456         ASN1_template_free(val, tt);
457         *val = NULL;
458         return 0;
459 }
460
461 static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
462 {
463         int flags, aclass;
464         int ret;
465         unsigned char *p, *q;
466         if(!val) return 0;
467         flags = tt->flags;
468         aclass = flags & ASN1_TFLG_TAG_CLASS;
469
470         p = *in;
471         q = p;
472
473         if(flags & ASN1_TFLG_SK_MASK) {
474                 /* SET OF, SEQUENCE OF */
475                 int sktag, skaclass;
476                 char sk_eoc;
477                 /* First work out expected inner tag value */
478                 if(flags & ASN1_TFLG_IMPTAG) {
479                         sktag = tt->tag;
480                         skaclass = aclass;
481                 } else {
482                         skaclass = V_ASN1_UNIVERSAL;
483                         if(flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET;
484                         else sktag = V_ASN1_SEQUENCE;
485                 }
486                 /* Get the tag */
487                 ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx);
488                 if(!ret) {
489                         ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
490                         return 0;
491                 } else if(ret == -1) return -1;
492                 if(!*val) *val = (ASN1_VALUE *)sk_new_null();
493                 else {
494                         /* We've got a valid STACK: free up any items present */
495                         STACK *sktmp = (STACK *)*val;
496                         ASN1_VALUE *vtmp;
497                         while(sk_num(sktmp) > 0) {
498                                 vtmp = (ASN1_VALUE *)sk_pop(sktmp);
499                                 ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
500                         }
501                 }
502                                 
503                 if(!*val) {
504                         ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE);
505                         goto err;
506                 }
507                 /* Read as many items as we can */
508                 while(len > 0) {
509                         ASN1_VALUE *skfield;
510                         q = p;
511                         /* See if EOC found */
512                         if(asn1_check_eoc(&p, len)) {
513                                 if(!sk_eoc) {
514                                         ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_UNEXPECTED_EOC);
515                                         goto err;
516                                 }
517                                 len -= p - q;
518                                 sk_eoc = 0;
519                                 break;
520                         }
521                         skfield = NULL;
522                         if(!ASN1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
523                                 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
524                                 goto err;
525                         }
526                         len -= p - q;
527                         if(!sk_push((STACK *)*val, (char *)skfield)) {
528                                 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_MALLOC_FAILURE);
529                                 goto err;
530                         }
531                 }
532                 if(sk_eoc) {
533                         ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
534                         goto err;
535                 }
536         } else if(flags & ASN1_TFLG_IMPTAG) {
537                 /* IMPLICIT tagging */
538                 ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
539                 if(!ret) {
540                         ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
541                         goto err;
542                 } else if(ret == -1) return -1;
543         } else {
544                 /* Nothing special */
545                 ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, opt, ctx);
546                 if(!ret) {
547                         ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
548                         goto err;
549                 } else if(ret == -1) return -1;
550         }
551
552         *in = p;
553         return 1;
554
555         err:
556         ASN1_template_free(val, tt);
557         *val = NULL;
558         return 0;
559 }
560
561 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, 
562                                                 const ASN1_ITEM *it,
563                                                 int tag, int aclass, char opt, ASN1_TLC *ctx)
564 {
565         int ret = 0, utype;
566         long plen;
567         char cst, inf, free_cont = 0;
568         unsigned char *p;
569         BUF_MEM buf;
570         unsigned char *cont = NULL;
571         long len; 
572         if(!pval) {
573                 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
574                 return 0; /* Should never happen */
575         }
576
577         if(it->itype == ASN1_ITYPE_MSTRING) {
578                 utype = tag;
579                 tag = -1;
580         } else utype = it->utype;
581
582         if(utype == V_ASN1_ANY) {
583                 /* If type is ANY need to figure out type from tag */
584                 unsigned char oclass;
585                 if(tag >= 0) {
586                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
587                         return 0;
588                 }
589                 if(opt) {
590                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_OPTIONAL_ANY);
591                         return 0;
592                 }
593                 p = *in;
594                 ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx);
595                 if(!ret) {
596                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
597                         return 0;
598                 }
599                 if(oclass != V_ASN1_UNIVERSAL) utype = V_ASN1_OTHER;
600         }
601         if(tag == -1) {
602                 tag = utype;
603                 aclass = V_ASN1_UNIVERSAL;
604         }
605         p = *in;
606         /* Check header */
607         ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx);
608         if(!ret) {
609                 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
610                 return 0;
611         } else if(ret == -1) return -1;
612         /* SEQUENCE, SET and "OTHER" are left in encoded form */
613         if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
614                 /* SEQUENCE and SET must be constructed */
615                 if((utype != V_ASN1_OTHER) && !cst) {
616                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_CONSTRUCTED);
617                         return 0;
618                 }
619
620                 cont = *in;
621                 /* If indefinite length constructed find the real end */
622                 if(inf) {
623                         if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err;
624                         len = p - cont;
625                 } else {
626                         len = p - cont + plen;
627                         p += plen;
628                         buf.data = NULL;
629                 }
630         } else if(cst) {
631                 buf.length = 0;
632                 buf.max = 0;
633                 buf.data = NULL;
634                 /* Should really check the internal tags are correct but
635                  * some things may get this wrong. The relevant specs
636                  * say that constructed string types should be OCTET STRINGs
637                  * internally irrespective of the type. So instead just check
638                  * for UNIVERSAL class and ignore the tag.
639                  */
640                 if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err;
641                 len = buf.length;
642                 /* Append a final null to string */
643                 if(!BUF_MEM_grow(&buf, len + 1)) {
644                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
645                         return 0;
646                 }
647                 buf.data[len] = 0;
648                 cont = (unsigned char *)buf.data;
649                 free_cont = 1;
650         } else {
651                 cont = p;
652                 len = plen;
653                 p += plen;
654         }
655
656         /* We now have content length and type: translate into a structure */
657         if(!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) goto err;
658
659         *in = p;
660         ret = 1;
661         err:
662         if(free_cont && buf.data) OPENSSL_free(buf.data);
663         return ret;
664 }
665
666 /* Translate ASN1 content octets into a structure */
667
668 int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it)
669 {
670         ASN1_STRING *stmp;
671         ASN1_TYPE *typ = NULL;
672         int ret = 0;
673         const ASN1_PRIMITIVE_FUNCS *pf;
674         ASN1_INTEGER **tint;
675         pf = it->funcs;
676         if(pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
677         /* If ANY type clear type and set pointer to internal value */
678         if(it->utype == V_ASN1_ANY) {
679                 if(!*pval) {
680                         typ = ASN1_TYPE_new();
681                         *pval = (ASN1_VALUE *)typ;
682                 } else typ = (ASN1_TYPE *)*pval;
683                 if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL);
684                 pval = (ASN1_VALUE **)&typ->value.ptr;
685         }
686         switch(utype) {
687                 case V_ASN1_OBJECT:
688                 if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err;
689                 break;
690
691                 case V_ASN1_NULL:
692                 if(len) {
693                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH);
694                         goto err;
695                 }
696                 *pval = (ASN1_VALUE *)1;
697                 break;
698
699                 case V_ASN1_BOOLEAN:
700                 if(len != 1) {
701                         ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
702                         goto err;
703                 } else {
704                         ASN1_BOOLEAN *tbool;
705                         tbool = (ASN1_BOOLEAN *)pval;
706                         *tbool = *cont;
707                 }
708                 break;
709
710                 case V_ASN1_BIT_STRING:
711                 if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err;
712                 break;
713
714                 case V_ASN1_INTEGER:
715                 case V_ASN1_NEG_INTEGER:
716                 case V_ASN1_ENUMERATED:
717                 case V_ASN1_NEG_ENUMERATED:
718                 tint = (ASN1_INTEGER **)pval;
719                 if(!c2i_ASN1_INTEGER(tint, &cont, len)) goto err;
720                 /* Fixup type to match the expected form */
721                 (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
722                 break;
723
724                 case V_ASN1_OCTET_STRING:
725                 case V_ASN1_NUMERICSTRING:
726                 case V_ASN1_PRINTABLESTRING:
727                 case V_ASN1_T61STRING:
728                 case V_ASN1_VIDEOTEXSTRING:
729                 case V_ASN1_IA5STRING:
730                 case V_ASN1_UTCTIME:
731                 case V_ASN1_GENERALIZEDTIME:
732                 case V_ASN1_GRAPHICSTRING:
733                 case V_ASN1_VISIBLESTRING:
734                 case V_ASN1_GENERALSTRING:
735                 case V_ASN1_UNIVERSALSTRING:
736                 case V_ASN1_BMPSTRING:
737                 case V_ASN1_UTF8STRING:
738                 case V_ASN1_OTHER:
739                 case V_ASN1_SET:
740                 case V_ASN1_SEQUENCE:
741                 default:
742                 /* All based on ASN1_STRING and handled the same */
743                 if(!*pval) {
744                         stmp = ASN1_STRING_type_new(utype);
745                         if(!stmp) {
746                                 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
747                                 goto err;
748                         }
749                         *pval = (ASN1_VALUE *)stmp;
750                 } else {
751                         stmp = (ASN1_STRING *)*pval;
752                         stmp->type = utype;
753                 }
754                 /* If we've already allocated a buffer use it */
755                 if(*free_cont) {
756                         if(stmp->data) OPENSSL_free(stmp->data);
757                         stmp->data = cont;
758                         stmp->length = len;
759                         *free_cont = 0;
760                 } else {
761                         if(!ASN1_STRING_set(stmp, cont, len)) {
762                                 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
763                                 ASN1_STRING_free(stmp); 
764                                 *pval = NULL;
765                                 goto err;
766                         }
767                 }
768                 break;
769         }
770         /* If ASN1_ANY and NULL type fix up value */
771         if(typ && utype==V_ASN1_NULL) typ->value.ptr = NULL;
772
773         ret = 1;
774         err:
775         if(!ret) ASN1_TYPE_free(typ);
776         return ret;
777 }
778
779 /* This function collects the asn1 data from a constructred string
780  * type into a buffer. The values of 'in' and 'len' should refer
781  * to the contents of the constructed type and 'inf' should be set
782  * if it is indefinite length. If 'buf' is NULL then we just want
783  * to find the end of the current structure: useful for indefinite
784  * length constructed stuff.
785  */
786
787 static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass)
788 {
789         unsigned char *p, *q;
790         long plen;
791         char cst, ininf;
792         p = *in;
793         inf &= 1;
794         /* If no buffer and not indefinite length constructed just pass over the encoded data */
795         if(!buf && !inf) {
796                 *in += len;
797                 return 1;
798         }
799         while(len > 0) {
800                 q = p;
801                 /* Check for EOC */
802                 if(asn1_check_eoc(&p, len)) {
803                         /* EOC is illegal outside indefinite length constructed form */
804                         if(!inf) {
805                                 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
806                                 return 0;
807                         }
808                         inf = 0;
809                         break;
810                 }
811                 if(!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, len, tag, aclass, 0, NULL)) {
812                         ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
813                         return 0;
814                 }
815                 /* If indefinite length constructed update max length */
816                 if(cst) {
817                         if(!asn1_collect(buf, &p, plen, ininf, tag, aclass)) return 0;
818                 } else {
819                         if(!collect_data(buf, &p, plen)) return 0;
820                 }
821                 len -= p - q;
822         }
823         if(inf) {
824                 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
825                 return 0;
826         }
827         *in = p;
828         return 1;
829 }
830
831 static int collect_data(BUF_MEM *buf, unsigned char **p, long plen)
832 {
833                 int len;
834                 if(buf) {
835                         len = buf->length;
836                         if(!BUF_MEM_grow(buf, len + plen)) {
837                                 ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
838                                 return 0;
839                         }
840                         memcpy(buf->data + len, *p, plen);
841                 }
842                 *p += plen;
843                 return 1;
844 }
845
846 /* Check for ASN1 EOC and swallow it if found */
847
848 static int asn1_check_eoc(unsigned char **in, long len)
849 {
850         unsigned char *p;
851         if(len < 2) return 0;
852         p = *in;
853         if(!p[0] && !p[1]) {
854                 *in += 2;
855                 return 1;
856         }
857         return 0;
858 }
859
860 /* Check an ASN1 tag and length: a bit like ASN1_get_object
861  * but it sets the length for indefinite length constructed
862  * form, we don't know the exact length but we can set an
863  * upper bound to the amount of data available minus the
864  * header length just read.
865  */
866
867 static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst,
868                 unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx)
869 {
870         int i;
871         int ptag, pclass;
872         long plen;
873         unsigned char *p, *q;
874         p = *in;
875         q = p;
876
877         if(ctx && ctx->valid) {
878                 i = ctx->ret;
879                 plen = ctx->plen;
880                 pclass = ctx->pclass;
881                 ptag = ctx->ptag;
882                 p += ctx->hdrlen;
883         } else {
884                 i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
885                 if(ctx) {
886                         ctx->ret = i;
887                         ctx->plen = plen;
888                         ctx->pclass = pclass;
889                         ctx->ptag = ptag;
890                         ctx->hdrlen = p - q;
891                         ctx->valid = 1;
892                         /* If definite length, length + header can't exceed total
893                          * amount of data available.
894                          */
895                         if(!(i & 1) && ((plen + ctx->hdrlen) > len)) {
896                                 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
897                                 asn1_tlc_clear(ctx);
898                                 return 0;
899                         }
900                 }
901         }
902                 
903         if(i & 0x80) {
904                 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
905                 asn1_tlc_clear(ctx);
906                 return 0;
907         }
908         if(exptag >= 0) {
909                 if((exptag != ptag) || (expclass != pclass)) {
910                         /* If type is OPTIONAL, not an error, but indicate missing
911                          * type.
912                          */
913                         if(opt) return -1;
914                         asn1_tlc_clear(ctx);
915                         ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
916                         return 0;
917                 }
918                 /* We have a tag and class match, so assume we are going to do something with it */
919                 asn1_tlc_clear(ctx);
920         }
921
922         if(i & 1) plen = len - (p - q);
923
924         if(inf) *inf = i & 1;
925
926         if(cst) *cst = i & V_ASN1_CONSTRUCTED;
927
928         if(olen) *olen = plen;
929         if(oclass) *oclass = pclass;
930         if(otag) *otag = ptag;
931
932         *in = p;
933         return 1;
934 }