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