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