File: | src/lib/libcrypto/asn1/tasn_dec.c |
Warning: | line 233, column 10 Access to field 'asn1_ex_d2i' results in a dereference of a null pointer (loaded from variable 'ef') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: tasn_dec.c,v 1.48 2022/01/07 12:24:17 tb Exp $ */ | |||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | |||
3 | * project 2000. | |||
4 | */ | |||
5 | /* ==================================================================== | |||
6 | * Copyright (c) 2000-2005 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 | #include <limits.h> | |||
60 | #include <stddef.h> | |||
61 | #include <string.h> | |||
62 | ||||
63 | #include <openssl/asn1.h> | |||
64 | #include <openssl/asn1t.h> | |||
65 | #include <openssl/buffer.h> | |||
66 | #include <openssl/err.h> | |||
67 | #include <openssl/objects.h> | |||
68 | ||||
69 | #include "asn1_locl.h" | |||
70 | #include "bytestring.h" | |||
71 | ||||
72 | /* Constructed types with a recursive definition (such as can be found in PKCS7) | |||
73 | * could eventually exceed the stack given malicious input with excessive | |||
74 | * recursion. Therefore we limit the stack depth. | |||
75 | */ | |||
76 | #define ASN1_MAX_CONSTRUCTED_NEST30 30 | |||
77 | ||||
78 | static int asn1_check_eoc(const unsigned char **in, long len); | |||
79 | static int asn1_find_end(const unsigned char **in, long len, char inf); | |||
80 | ||||
81 | static int asn1_collect(CBB *cbb, const unsigned char **in, long len, | |||
82 | char inf, int tag, int aclass, int depth); | |||
83 | ||||
84 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, | |||
85 | char *inf, char *cst, const unsigned char **in, long len, int exptag, | |||
86 | int expclass, char opt, ASN1_TLC *ctx); | |||
87 | ||||
88 | static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, | |||
89 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, | |||
90 | int depth); | |||
91 | static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, | |||
92 | long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth); | |||
93 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, | |||
94 | long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth); | |||
95 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, | |||
96 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, | |||
97 | ASN1_TLC *ctx); | |||
98 | ||||
99 | static void | |||
100 | asn1_tlc_invalidate(ASN1_TLC *ctx) | |||
101 | { | |||
102 | if (ctx != NULL((void*)0)) | |||
103 | ctx->valid = 0; | |||
104 | } | |||
105 | ||||
106 | ASN1_VALUE * | |||
107 | ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
108 | const ASN1_ITEM *it) | |||
109 | { | |||
110 | ASN1_VALUE *ptmpval = NULL((void*)0); | |||
111 | ASN1_TLC ctx; | |||
112 | ||||
113 | asn1_tlc_invalidate(&ctx); | |||
114 | ||||
115 | if (pval == NULL((void*)0)) | |||
116 | pval = &ptmpval; | |||
117 | if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &ctx, 0) <= 0) | |||
118 | return NULL((void*)0); | |||
119 | ||||
120 | return *pval; | |||
121 | } | |||
122 | ||||
123 | int | |||
124 | ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
125 | const ASN1_TEMPLATE *tt) | |||
126 | { | |||
127 | ASN1_TLC ctx; | |||
128 | ||||
129 | asn1_tlc_invalidate(&ctx); | |||
130 | ||||
131 | return asn1_template_ex_d2i(pval, in, len, tt, 0, &ctx, 0); | |||
132 | } | |||
133 | ||||
134 | /* Decode an item, taking care of IMPLICIT tagging, if any. | |||
135 | * If 'opt' set and tag mismatch return -1 to handle OPTIONAL | |||
136 | */ | |||
137 | ||||
138 | static int | |||
139 | asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
140 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, | |||
141 | int depth) | |||
142 | { | |||
143 | const ASN1_TEMPLATE *tt, *errtt = NULL((void*)0); | |||
144 | const ASN1_EXTERN_FUNCS *ef; | |||
145 | const ASN1_AUX *aux = it->funcs; | |||
146 | ASN1_aux_cb *asn1_cb = NULL((void*)0); | |||
147 | const unsigned char *p = NULL((void*)0), *q; | |||
148 | unsigned char oclass; | |||
149 | char seq_eoc, seq_nolen, cst, isopt; | |||
150 | long tmplen; | |||
151 | int i; | |||
152 | int otag; | |||
153 | int ret = 0; | |||
154 | ASN1_VALUE **pchptr; | |||
155 | int combine; | |||
156 | ||||
157 | combine = aclass & ASN1_TFLG_COMBINE(0x1<<10); | |||
158 | aclass &= ~ASN1_TFLG_COMBINE(0x1<<10); | |||
159 | ||||
160 | if (!pval) | |||
| ||||
161 | return 0; | |||
162 | ||||
163 | if (aux && aux->asn1_cb) | |||
164 | asn1_cb = aux->asn1_cb; | |||
165 | ||||
166 | if (++depth > ASN1_MAX_CONSTRUCTED_NEST30) { | |||
167 | ASN1error(ASN1_R_NESTED_TOO_DEEP)ERR_put_error(13,(0xfff),(219),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,167); | |||
168 | goto err; | |||
169 | } | |||
170 | ||||
171 | switch (it->itype) { | |||
172 | case ASN1_ITYPE_PRIMITIVE0x0: | |||
173 | if (it->templates) { | |||
174 | /* tagging or OPTIONAL is currently illegal on an item | |||
175 | * template because the flags can't get passed down. | |||
176 | * In practice this isn't a problem: we include the | |||
177 | * relevant flags from the item template in the | |||
178 | * template itself. | |||
179 | */ | |||
180 | if ((tag != -1) || opt) { | |||
181 | ASN1error(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE)ERR_put_error(13,(0xfff),(170),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,181); | |||
182 | goto err; | |||
183 | } | |||
184 | return asn1_template_ex_d2i(pval, in, len, | |||
185 | it->templates, opt, ctx, depth); | |||
186 | } | |||
187 | return asn1_d2i_ex_primitive(pval, in, len, it, | |||
188 | tag, aclass, opt, ctx); | |||
189 | break; | |||
190 | ||||
191 | case ASN1_ITYPE_MSTRING0x5: | |||
192 | /* | |||
193 | * It never makes sense for multi-strings to have implicit | |||
194 | * tagging, so if tag != -1, then this looks like an error in | |||
195 | * the template. | |||
196 | */ | |||
197 | if (tag != -1) { | |||
198 | ASN1error(ASN1_R_BAD_TEMPLATE)ERR_put_error(13,(0xfff),(230),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,198); | |||
199 | goto err; | |||
200 | } | |||
201 | ||||
202 | p = *in; | |||
203 | /* Just read in tag and class */ | |||
204 | ret = asn1_check_tlen(NULL((void*)0), &otag, &oclass, NULL((void*)0), NULL((void*)0), | |||
205 | &p, len, -1, 0, 1, ctx); | |||
206 | if (!ret) { | |||
207 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,207); | |||
208 | goto err; | |||
209 | } | |||
210 | ||||
211 | /* Must be UNIVERSAL class */ | |||
212 | if (oclass != V_ASN1_UNIVERSAL0x00) { | |||
213 | /* If OPTIONAL, assume this is OK */ | |||
214 | if (opt) | |||
215 | return -1; | |||
216 | ASN1error(ASN1_R_MSTRING_NOT_UNIVERSAL)ERR_put_error(13,(0xfff),(139),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,216); | |||
217 | goto err; | |||
218 | } | |||
219 | /* Check tag matches bit map */ | |||
220 | if (!(ASN1_tag2bit(otag) & it->utype)) { | |||
221 | /* If OPTIONAL, assume this is OK */ | |||
222 | if (opt) | |||
223 | return -1; | |||
224 | ASN1error(ASN1_R_MSTRING_WRONG_TAG)ERR_put_error(13,(0xfff),(140),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,224); | |||
225 | goto err; | |||
226 | } | |||
227 | return asn1_d2i_ex_primitive(pval, in, len, | |||
228 | it, otag, 0, 0, ctx); | |||
229 | ||||
230 | case ASN1_ITYPE_EXTERN0x4: | |||
231 | /* Use new style d2i */ | |||
232 | ef = it->funcs; | |||
233 | return ef->asn1_ex_d2i(pval, in, len, | |||
| ||||
234 | it, tag, aclass, opt, ctx); | |||
235 | ||||
236 | case ASN1_ITYPE_CHOICE0x2: | |||
237 | /* | |||
238 | * It never makes sense for CHOICE types to have implicit | |||
239 | * tagging, so if tag != -1, then this looks like an error in | |||
240 | * the template. | |||
241 | */ | |||
242 | if (tag != -1) { | |||
243 | ASN1error(ASN1_R_BAD_TEMPLATE)ERR_put_error(13,(0xfff),(230),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,243); | |||
244 | goto err; | |||
245 | } | |||
246 | ||||
247 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE4, pval, it, NULL((void*)0))) | |||
248 | goto auxerr; | |||
249 | ||||
250 | if (*pval) { | |||
251 | /* Free up and zero CHOICE value if initialised */ | |||
252 | i = asn1_get_choice_selector(pval, it); | |||
253 | if ((i >= 0) && (i < it->tcount)) { | |||
254 | tt = it->templates + i; | |||
255 | pchptr = asn1_get_field_ptr(pval, tt); | |||
256 | ASN1_template_free(pchptr, tt); | |||
257 | asn1_set_choice_selector(pval, -1, it); | |||
258 | } | |||
259 | } else if (!ASN1_item_ex_new(pval, it)) { | |||
260 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,260); | |||
261 | goto err; | |||
262 | } | |||
263 | /* CHOICE type, try each possibility in turn */ | |||
264 | p = *in; | |||
265 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { | |||
266 | pchptr = asn1_get_field_ptr(pval, tt); | |||
267 | /* We mark field as OPTIONAL so its absence | |||
268 | * can be recognised. | |||
269 | */ | |||
270 | ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, | |||
271 | depth); | |||
272 | /* If field not present, try the next one */ | |||
273 | if (ret == -1) | |||
274 | continue; | |||
275 | /* If positive return, read OK, break loop */ | |||
276 | if (ret > 0) | |||
277 | break; | |||
278 | /* Otherwise must be an ASN1 parsing error */ | |||
279 | errtt = tt; | |||
280 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,280); | |||
281 | goto err; | |||
282 | } | |||
283 | ||||
284 | /* Did we fall off the end without reading anything? */ | |||
285 | if (i == it->tcount) { | |||
286 | /* If OPTIONAL, this is OK */ | |||
287 | if (opt) { | |||
288 | /* Free and zero it */ | |||
289 | ASN1_item_ex_free(pval, it); | |||
290 | return -1; | |||
291 | } | |||
292 | ASN1error(ASN1_R_NO_MATCHING_CHOICE_TYPE)ERR_put_error(13,(0xfff),(143),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,292); | |||
293 | goto err; | |||
294 | } | |||
295 | ||||
296 | asn1_set_choice_selector(pval, i, it); | |||
297 | *in = p; | |||
298 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST5, pval, it, NULL((void*)0))) | |||
299 | goto auxerr; | |||
300 | return 1; | |||
301 | ||||
302 | case ASN1_ITYPE_NDEF_SEQUENCE0x6: | |||
303 | case ASN1_ITYPE_SEQUENCE0x1: | |||
304 | p = *in; | |||
305 | tmplen = len; | |||
306 | ||||
307 | /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ | |||
308 | if (tag == -1) { | |||
309 | tag = V_ASN1_SEQUENCE16; | |||
310 | aclass = V_ASN1_UNIVERSAL0x00; | |||
311 | } | |||
312 | /* Get SEQUENCE length and update len, p */ | |||
313 | ret = asn1_check_tlen(&len, NULL((void*)0), NULL((void*)0), &seq_eoc, &cst, | |||
314 | &p, len, tag, aclass, opt, ctx); | |||
315 | if (!ret) { | |||
316 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,316); | |||
317 | goto err; | |||
318 | } else if (ret == -1) | |||
319 | return -1; | |||
320 | if (aux && (aux->flags & ASN1_AFLG_BROKEN4)) { | |||
321 | len = tmplen - (p - *in); | |||
322 | seq_nolen = 1; | |||
323 | } | |||
324 | /* If indefinite we don't do a length check */ | |||
325 | else | |||
326 | seq_nolen = seq_eoc; | |||
327 | if (!cst) { | |||
328 | ASN1error(ASN1_R_SEQUENCE_NOT_CONSTRUCTED)ERR_put_error(13,(0xfff),(149),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,328); | |||
329 | goto err; | |||
330 | } | |||
331 | ||||
332 | if (!*pval && !ASN1_item_ex_new(pval, it)) { | |||
333 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,333); | |||
334 | goto err; | |||
335 | } | |||
336 | ||||
337 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE4, pval, it, NULL((void*)0))) | |||
338 | goto auxerr; | |||
339 | ||||
340 | /* Free up and zero any ADB found */ | |||
341 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { | |||
342 | if (tt->flags & ASN1_TFLG_ADB_MASK(0x3<<8)) { | |||
343 | const ASN1_TEMPLATE *seqtt; | |||
344 | ASN1_VALUE **pseqval; | |||
345 | seqtt = asn1_do_adb(pval, tt, 1); | |||
346 | if (!seqtt) | |||
347 | goto err; | |||
348 | pseqval = asn1_get_field_ptr(pval, seqtt); | |||
349 | ASN1_template_free(pseqval, seqtt); | |||
350 | } | |||
351 | } | |||
352 | ||||
353 | /* Get each field entry */ | |||
354 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { | |||
355 | const ASN1_TEMPLATE *seqtt; | |||
356 | ASN1_VALUE **pseqval; | |||
357 | seqtt = asn1_do_adb(pval, tt, 1); | |||
358 | if (!seqtt) | |||
359 | goto err; | |||
360 | pseqval = asn1_get_field_ptr(pval, seqtt); | |||
361 | /* Have we ran out of data? */ | |||
362 | if (!len) | |||
363 | break; | |||
364 | q = p; | |||
365 | if (asn1_check_eoc(&p, len)) { | |||
366 | if (!seq_eoc) { | |||
367 | ASN1error(ASN1_R_UNEXPECTED_EOC)ERR_put_error(13,(0xfff),(159),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,367); | |||
368 | goto err; | |||
369 | } | |||
370 | len -= p - q; | |||
371 | seq_eoc = 0; | |||
372 | q = p; | |||
373 | break; | |||
374 | } | |||
375 | /* This determines the OPTIONAL flag value. The field | |||
376 | * cannot be omitted if it is the last of a SEQUENCE | |||
377 | * and there is still data to be read. This isn't | |||
378 | * strictly necessary but it increases efficiency in | |||
379 | * some cases. | |||
380 | */ | |||
381 | if (i == (it->tcount - 1)) | |||
382 | isopt = 0; | |||
383 | else | |||
384 | isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL(0x1)); | |||
385 | /* attempt to read in field, allowing each to be | |||
386 | * OPTIONAL */ | |||
387 | ||||
388 | ret = asn1_template_ex_d2i(pseqval, &p, len, | |||
389 | seqtt, isopt, ctx, depth); | |||
390 | if (!ret) { | |||
391 | errtt = seqtt; | |||
392 | goto err; | |||
393 | } else if (ret == -1) { | |||
394 | /* OPTIONAL component absent. | |||
395 | * Free and zero the field. | |||
396 | */ | |||
397 | ASN1_template_free(pseqval, seqtt); | |||
398 | continue; | |||
399 | } | |||
400 | /* Update length */ | |||
401 | len -= p - q; | |||
402 | } | |||
403 | ||||
404 | /* Check for EOC if expecting one */ | |||
405 | if (seq_eoc && !asn1_check_eoc(&p, len)) { | |||
406 | ASN1error(ASN1_R_MISSING_EOC)ERR_put_error(13,(0xfff),(137),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,406); | |||
407 | goto err; | |||
408 | } | |||
409 | /* Check all data read */ | |||
410 | if (!seq_nolen && len) { | |||
411 | ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH)ERR_put_error(13,(0xfff),(148),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,411); | |||
412 | goto err; | |||
413 | } | |||
414 | ||||
415 | /* If we get here we've got no more data in the SEQUENCE, | |||
416 | * however we may not have read all fields so check all | |||
417 | * remaining are OPTIONAL and clear any that are. | |||
418 | */ | |||
419 | for (; i < it->tcount; tt++, i++) { | |||
420 | const ASN1_TEMPLATE *seqtt; | |||
421 | seqtt = asn1_do_adb(pval, tt, 1); | |||
422 | if (!seqtt) | |||
423 | goto err; | |||
424 | if (seqtt->flags & ASN1_TFLG_OPTIONAL(0x1)) { | |||
425 | ASN1_VALUE **pseqval; | |||
426 | pseqval = asn1_get_field_ptr(pval, seqtt); | |||
427 | ASN1_template_free(pseqval, seqtt); | |||
428 | } else { | |||
429 | errtt = seqtt; | |||
430 | ASN1error(ASN1_R_FIELD_MISSING)ERR_put_error(13,(0xfff),(121),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,430); | |||
431 | goto err; | |||
432 | } | |||
433 | } | |||
434 | /* Save encoding */ | |||
435 | if (!asn1_enc_save(pval, *in, p - *in, it)) { | |||
436 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,436); | |||
437 | goto auxerr; | |||
438 | } | |||
439 | *in = p; | |||
440 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST5, pval, it, NULL((void*)0))) | |||
441 | goto auxerr; | |||
442 | return 1; | |||
443 | ||||
444 | default: | |||
445 | return 0; | |||
446 | } | |||
447 | ||||
448 | auxerr: | |||
449 | ASN1error(ASN1_R_AUX_ERROR)ERR_put_error(13,(0xfff),(100),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,449); | |||
450 | err: | |||
451 | if (combine == 0) | |||
452 | ASN1_item_ex_free(pval, it); | |||
453 | if (errtt) | |||
454 | ERR_asprintf_error_data("Field=%s, Type=%s", errtt->field_name, | |||
455 | it->sname); | |||
456 | else | |||
457 | ERR_asprintf_error_data("Type=%s", it->sname); | |||
458 | return 0; | |||
459 | } | |||
460 | ||||
461 | int | |||
462 | ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
463 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) | |||
464 | { | |||
465 | return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); | |||
466 | } | |||
467 | ||||
468 | /* Templates are handled with two separate functions. | |||
469 | * One handles any EXPLICIT tag and the other handles the rest. | |||
470 | */ | |||
471 | ||||
472 | static int | |||
473 | asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, | |||
474 | const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth) | |||
475 | { | |||
476 | int flags, aclass; | |||
477 | int ret; | |||
478 | long len; | |||
479 | const unsigned char *p, *q; | |||
480 | char exp_eoc; | |||
481 | ||||
482 | if (!val) | |||
483 | return 0; | |||
484 | flags = tt->flags; | |||
485 | aclass = flags & ASN1_TFLG_TAG_CLASS(0x3<<6); | |||
486 | ||||
487 | p = *in; | |||
488 | ||||
489 | /* Check if EXPLICIT tag expected */ | |||
490 | if (flags & ASN1_TFLG_EXPTAG(0x2 << 3)) { | |||
491 | char cst; | |||
492 | /* Need to work out amount of data available to the inner | |||
493 | * content and where it starts: so read in EXPLICIT header to | |||
494 | * get the info. | |||
495 | */ | |||
496 | ret = asn1_check_tlen(&len, NULL((void*)0), NULL((void*)0), &exp_eoc, &cst, | |||
497 | &p, inlen, tt->tag, aclass, opt, ctx); | |||
498 | q = p; | |||
499 | if (!ret) { | |||
500 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,500); | |||
501 | return 0; | |||
502 | } else if (ret == -1) | |||
503 | return -1; | |||
504 | if (!cst) { | |||
505 | ASN1error(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED)ERR_put_error(13,(0xfff),(120),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,505); | |||
506 | return 0; | |||
507 | } | |||
508 | /* We've found the field so it can't be OPTIONAL now */ | |||
509 | ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); | |||
510 | if (!ret) { | |||
511 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,511); | |||
512 | return 0; | |||
513 | } | |||
514 | /* We read the field in OK so update length */ | |||
515 | len -= p - q; | |||
516 | if (exp_eoc) { | |||
517 | /* If NDEF we must have an EOC here */ | |||
518 | if (!asn1_check_eoc(&p, len)) { | |||
519 | ASN1error(ASN1_R_MISSING_EOC)ERR_put_error(13,(0xfff),(137),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,519); | |||
520 | goto err; | |||
521 | } | |||
522 | } else { | |||
523 | /* Otherwise we must hit the EXPLICIT tag end or its | |||
524 | * an error */ | |||
525 | if (len) { | |||
526 | ASN1error(ASN1_R_EXPLICIT_LENGTH_MISMATCH)ERR_put_error(13,(0xfff),(119),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,526); | |||
527 | goto err; | |||
528 | } | |||
529 | } | |||
530 | } else | |||
531 | return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, | |||
532 | depth); | |||
533 | ||||
534 | *in = p; | |||
535 | return 1; | |||
536 | ||||
537 | err: | |||
538 | ASN1_template_free(val, tt); | |||
539 | return 0; | |||
540 | } | |||
541 | ||||
542 | static int | |||
543 | asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
544 | const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth) | |||
545 | { | |||
546 | int flags, aclass; | |||
547 | int ret; | |||
548 | const unsigned char *p, *q; | |||
549 | ||||
550 | if (!val) | |||
551 | return 0; | |||
552 | flags = tt->flags; | |||
553 | aclass = flags & ASN1_TFLG_TAG_CLASS(0x3<<6); | |||
554 | ||||
555 | p = *in; | |||
556 | q = p; | |||
557 | ||||
558 | if (flags & ASN1_TFLG_SK_MASK(0x3 << 1)) { | |||
559 | /* SET OF, SEQUENCE OF */ | |||
560 | int sktag, skaclass; | |||
561 | char sk_eoc; | |||
562 | /* First work out expected inner tag value */ | |||
563 | if (flags & ASN1_TFLG_IMPTAG(0x1 << 3)) { | |||
564 | sktag = tt->tag; | |||
565 | skaclass = aclass; | |||
566 | } else { | |||
567 | skaclass = V_ASN1_UNIVERSAL0x00; | |||
568 | if (flags & ASN1_TFLG_SET_OF(0x1 << 1)) | |||
569 | sktag = V_ASN1_SET17; | |||
570 | else | |||
571 | sktag = V_ASN1_SEQUENCE16; | |||
572 | } | |||
573 | /* Get the tag */ | |||
574 | ret = asn1_check_tlen(&len, NULL((void*)0), NULL((void*)0), &sk_eoc, NULL((void*)0), | |||
575 | &p, len, sktag, skaclass, opt, ctx); | |||
576 | if (!ret) { | |||
577 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,577); | |||
578 | return 0; | |||
579 | } else if (ret == -1) | |||
580 | return -1; | |||
581 | if (!*val) | |||
582 | *val = (ASN1_VALUE *)sk_new_null(); | |||
583 | else { | |||
584 | /* We've got a valid STACK: free up any items present */ | |||
585 | STACK_OF(ASN1_VALUE)struct stack_st_ASN1_VALUE *sktmp = | |||
586 | (STACK_OF(ASN1_VALUE)struct stack_st_ASN1_VALUE *)*val; | |||
587 | ASN1_VALUE *vtmp; | |||
588 | while (sk_ASN1_VALUE_num(sktmp)sk_num(((_STACK*) (1 ? (sktmp) : (struct stack_st_ASN1_VALUE* )0))) > 0) { | |||
589 | vtmp = sk_ASN1_VALUE_pop(sktmp)(ASN1_VALUE *)sk_pop(((_STACK*) (1 ? (sktmp) : (struct stack_st_ASN1_VALUE *)0))); | |||
590 | ASN1_item_ex_free(&vtmp, | |||
591 | tt->item); | |||
592 | } | |||
593 | } | |||
594 | ||||
595 | if (!*val) { | |||
596 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,596); | |||
597 | goto err; | |||
598 | } | |||
599 | ||||
600 | /* Read as many items as we can */ | |||
601 | while (len > 0) { | |||
602 | ASN1_VALUE *skfield; | |||
603 | q = p; | |||
604 | /* See if EOC found */ | |||
605 | if (asn1_check_eoc(&p, len)) { | |||
606 | if (!sk_eoc) { | |||
607 | ASN1error(ASN1_R_UNEXPECTED_EOC)ERR_put_error(13,(0xfff),(159),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,607); | |||
608 | goto err; | |||
609 | } | |||
610 | len -= p - q; | |||
611 | sk_eoc = 0; | |||
612 | break; | |||
613 | } | |||
614 | skfield = NULL((void*)0); | |||
615 | if (!asn1_item_ex_d2i(&skfield, &p, len, | |||
616 | tt->item, -1, 0, 0, ctx, depth)) { | |||
617 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,617); | |||
618 | goto err; | |||
619 | } | |||
620 | len -= p - q; | |||
621 | if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,sk_push(((_STACK*) (1 ? ((struct stack_st_ASN1_VALUE *)*val) : (struct stack_st_ASN1_VALUE*)0)), ((void*) (1 ? (skfield) : ( ASN1_VALUE*)0))) | |||
622 | skfield)sk_push(((_STACK*) (1 ? ((struct stack_st_ASN1_VALUE *)*val) : (struct stack_st_ASN1_VALUE*)0)), ((void*) (1 ? (skfield) : ( ASN1_VALUE*)0)))) { | |||
623 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,623); | |||
624 | goto err; | |||
625 | } | |||
626 | } | |||
627 | if (sk_eoc) { | |||
628 | ASN1error(ASN1_R_MISSING_EOC)ERR_put_error(13,(0xfff),(137),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,628); | |||
629 | goto err; | |||
630 | } | |||
631 | } else if (flags & ASN1_TFLG_IMPTAG(0x1 << 3)) { | |||
632 | /* IMPLICIT tagging */ | |||
633 | ret = asn1_item_ex_d2i(val, &p, len, | |||
634 | tt->item, tt->tag, aclass, opt, ctx, depth); | |||
635 | if (!ret) { | |||
636 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,636); | |||
637 | goto err; | |||
638 | } else if (ret == -1) | |||
639 | return -1; | |||
640 | } else { | |||
641 | /* Nothing special */ | |||
642 | ret = asn1_item_ex_d2i(val, &p, len, tt->item, | |||
643 | -1, tt->flags & ASN1_TFLG_COMBINE(0x1<<10), opt, ctx, depth); | |||
644 | if (!ret) { | |||
645 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,645); | |||
646 | goto err; | |||
647 | } else if (ret == -1) | |||
648 | return -1; | |||
649 | } | |||
650 | ||||
651 | *in = p; | |||
652 | return 1; | |||
653 | ||||
654 | err: | |||
655 | ASN1_template_free(val, tt); | |||
656 | return 0; | |||
657 | } | |||
658 | ||||
659 | static int | |||
660 | asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
661 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) | |||
662 | { | |||
663 | int ret = 0, utype; | |||
664 | long plen; | |||
665 | char cst, inf, free_cont = 0; | |||
666 | const unsigned char *p; | |||
667 | const unsigned char *cont = NULL((void*)0); | |||
668 | uint8_t *data = NULL((void*)0); | |||
669 | size_t data_len = 0; | |||
670 | CBB cbb; | |||
671 | long len; | |||
672 | ||||
673 | memset(&cbb, 0, sizeof(cbb)); | |||
674 | ||||
675 | if (!pval) { | |||
676 | ASN1error(ASN1_R_ILLEGAL_NULL)ERR_put_error(13,(0xfff),(125),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,676); | |||
677 | return 0; /* Should never happen */ | |||
678 | } | |||
679 | ||||
680 | if (it->itype == ASN1_ITYPE_MSTRING0x5) { | |||
681 | utype = tag; | |||
682 | tag = -1; | |||
683 | } else | |||
684 | utype = it->utype; | |||
685 | ||||
686 | if (utype == V_ASN1_ANY-4) { | |||
687 | /* If type is ANY need to figure out type from tag */ | |||
688 | unsigned char oclass; | |||
689 | if (tag >= 0) { | |||
690 | ASN1error(ASN1_R_ILLEGAL_TAGGED_ANY)ERR_put_error(13,(0xfff),(127),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,690); | |||
691 | return 0; | |||
692 | } | |||
693 | if (opt) { | |||
694 | ASN1error(ASN1_R_ILLEGAL_OPTIONAL_ANY)ERR_put_error(13,(0xfff),(126),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,694); | |||
695 | return 0; | |||
696 | } | |||
697 | p = *in; | |||
698 | ret = asn1_check_tlen(NULL((void*)0), &utype, &oclass, NULL((void*)0), NULL((void*)0), | |||
699 | &p, inlen, -1, 0, 0, ctx); | |||
700 | if (!ret) { | |||
701 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,701); | |||
702 | return 0; | |||
703 | } | |||
704 | if (oclass != V_ASN1_UNIVERSAL0x00) | |||
705 | utype = V_ASN1_OTHER-3; | |||
706 | } | |||
707 | if (tag == -1) { | |||
708 | tag = utype; | |||
709 | aclass = V_ASN1_UNIVERSAL0x00; | |||
710 | } | |||
711 | p = *in; | |||
712 | /* Check header */ | |||
713 | ret = asn1_check_tlen(&plen, NULL((void*)0), NULL((void*)0), &inf, &cst, | |||
714 | &p, inlen, tag, aclass, opt, ctx); | |||
715 | if (!ret) { | |||
716 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,716); | |||
717 | return 0; | |||
718 | } else if (ret == -1) | |||
719 | return -1; | |||
720 | ret = 0; | |||
721 | /* SEQUENCE, SET and "OTHER" are left in encoded form */ | |||
722 | if ((utype == V_ASN1_SEQUENCE16) || (utype == V_ASN1_SET17) || | |||
723 | (utype == V_ASN1_OTHER-3)) { | |||
724 | /* Clear context cache for type OTHER because the auto clear | |||
725 | * when we have a exact match wont work | |||
726 | */ | |||
727 | if (utype == V_ASN1_OTHER-3) { | |||
728 | asn1_tlc_invalidate(ctx); | |||
729 | } else if (!cst) { | |||
730 | /* SEQUENCE and SET must be constructed */ | |||
731 | ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED)ERR_put_error(13,(0xfff),(156),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,731); | |||
732 | return 0; | |||
733 | } | |||
734 | ||||
735 | cont = *in; | |||
736 | /* If indefinite length constructed find the real end */ | |||
737 | if (inf) { | |||
738 | if (!asn1_find_end(&p, plen, inf)) | |||
739 | goto err; | |||
740 | len = p - cont; | |||
741 | } else { | |||
742 | len = p - cont + plen; | |||
743 | p += plen; | |||
744 | } | |||
745 | } else if (cst) { | |||
746 | /* | |||
747 | * Should really check the internal tags are correct but | |||
748 | * some things may get this wrong. The relevant specs | |||
749 | * say that constructed string types should be OCTET STRINGs | |||
750 | * internally irrespective of the type. So instead just check | |||
751 | * for UNIVERSAL class and ignore the tag. | |||
752 | */ | |||
753 | if (!CBB_init(&cbb, 0)) | |||
754 | goto err; | |||
755 | if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL0x00, 0)) | |||
756 | goto err; | |||
757 | ||||
758 | /* Append a final NUL to string. */ | |||
759 | if (!CBB_add_u8(&cbb, 0)) | |||
760 | goto err; | |||
761 | ||||
762 | if (!CBB_finish(&cbb, &data, &data_len)) | |||
763 | goto err; | |||
764 | ||||
765 | free_cont = 1; | |||
766 | ||||
767 | if (data_len < 1 || data_len > LONG_MAX9223372036854775807L) | |||
768 | goto err; | |||
769 | ||||
770 | cont = data; | |||
771 | len = data_len - 1; | |||
772 | } else { | |||
773 | cont = p; | |||
774 | len = plen; | |||
775 | p += plen; | |||
776 | } | |||
777 | ||||
778 | /* We now have content length and type: translate into a structure */ | |||
779 | if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) | |||
780 | goto err; | |||
781 | ||||
782 | *in = p; | |||
783 | ret = 1; | |||
784 | ||||
785 | err: | |||
786 | CBB_cleanup(&cbb); | |||
787 | ||||
788 | if (free_cont) | |||
789 | freezero(data, data_len); | |||
790 | ||||
791 | return ret; | |||
792 | } | |||
793 | ||||
794 | /* Translate ASN1 content octets into a structure */ | |||
795 | ||||
796 | int | |||
797 | asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
798 | char *free_cont, const ASN1_ITEM *it) | |||
799 | { | |||
800 | ASN1_VALUE **opval = NULL((void*)0); | |||
801 | ASN1_STRING *stmp; | |||
802 | ASN1_TYPE *typ = NULL((void*)0); | |||
803 | ASN1_INTEGER **tint; | |||
804 | int ret = 0; | |||
805 | ||||
806 | if (it->funcs != NULL((void*)0)) { | |||
807 | const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; | |||
808 | ||||
809 | if (pf->prim_c2i == NULL((void*)0)) | |||
810 | return 0; | |||
811 | return pf->prim_c2i(pval, cont, len, utype, free_cont, it); | |||
812 | } | |||
813 | ||||
814 | /* If ANY type clear type and set pointer to internal value */ | |||
815 | if (it->utype == V_ASN1_ANY-4) { | |||
816 | if (!*pval) { | |||
817 | typ = ASN1_TYPE_new(); | |||
818 | if (typ == NULL((void*)0)) | |||
819 | goto err; | |||
820 | *pval = (ASN1_VALUE *)typ; | |||
821 | } else | |||
822 | typ = (ASN1_TYPE *)*pval; | |||
823 | ||||
824 | if (utype != typ->type) | |||
825 | ASN1_TYPE_set(typ, utype, NULL((void*)0)); | |||
826 | opval = pval; | |||
827 | pval = &typ->value.asn1_value; | |||
828 | } | |||
829 | switch (utype) { | |||
830 | case V_ASN1_OBJECT6: | |||
831 | if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) | |||
832 | goto err; | |||
833 | break; | |||
834 | ||||
835 | case V_ASN1_NULL5: | |||
836 | if (len) { | |||
837 | ASN1error(ASN1_R_NULL_IS_WRONG_LENGTH)ERR_put_error(13,(0xfff),(144),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,837); | |||
838 | goto err; | |||
839 | } | |||
840 | *pval = (ASN1_VALUE *)1; | |||
841 | break; | |||
842 | ||||
843 | case V_ASN1_BOOLEAN1: | |||
844 | if (len != 1) { | |||
845 | ASN1error(ASN1_R_BOOLEAN_IS_WRONG_LENGTH)ERR_put_error(13,(0xfff),(106),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,845); | |||
846 | goto err; | |||
847 | } else { | |||
848 | ASN1_BOOLEAN *tbool; | |||
849 | tbool = (ASN1_BOOLEAN *)pval; | |||
850 | *tbool = *cont; | |||
851 | } | |||
852 | break; | |||
853 | ||||
854 | case V_ASN1_BIT_STRING3: | |||
855 | if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) | |||
856 | goto err; | |||
857 | break; | |||
858 | ||||
859 | case V_ASN1_INTEGER2: | |||
860 | case V_ASN1_ENUMERATED10: | |||
861 | tint = (ASN1_INTEGER **)pval; | |||
862 | if (!c2i_ASN1_INTEGER(tint, &cont, len)) | |||
863 | goto err; | |||
864 | /* Fixup type to match the expected form */ | |||
865 | (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG0x100); | |||
866 | break; | |||
867 | ||||
868 | case V_ASN1_OCTET_STRING4: | |||
869 | case V_ASN1_NUMERICSTRING18: | |||
870 | case V_ASN1_PRINTABLESTRING19: | |||
871 | case V_ASN1_T61STRING20: | |||
872 | case V_ASN1_VIDEOTEXSTRING21: | |||
873 | case V_ASN1_IA5STRING22: | |||
874 | case V_ASN1_UTCTIME23: | |||
875 | case V_ASN1_GENERALIZEDTIME24: | |||
876 | case V_ASN1_GRAPHICSTRING25: | |||
877 | case V_ASN1_VISIBLESTRING26: | |||
878 | case V_ASN1_GENERALSTRING27: | |||
879 | case V_ASN1_UNIVERSALSTRING28: | |||
880 | case V_ASN1_BMPSTRING30: | |||
881 | case V_ASN1_UTF8STRING12: | |||
882 | case V_ASN1_OTHER-3: | |||
883 | case V_ASN1_SET17: | |||
884 | case V_ASN1_SEQUENCE16: | |||
885 | default: | |||
886 | if (utype == V_ASN1_BMPSTRING30 && (len & 1)) { | |||
887 | ASN1error(ASN1_R_BMPSTRING_IS_WRONG_LENGTH)ERR_put_error(13,(0xfff),(214),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,887); | |||
888 | goto err; | |||
889 | } | |||
890 | if (utype == V_ASN1_UNIVERSALSTRING28 && (len & 3)) { | |||
891 | ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH)ERR_put_error(13,(0xfff),(215),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,891); | |||
892 | goto err; | |||
893 | } | |||
894 | /* All based on ASN1_STRING and handled the same */ | |||
895 | if (!*pval) { | |||
896 | stmp = ASN1_STRING_type_new(utype); | |||
897 | if (!stmp) { | |||
898 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,898); | |||
899 | goto err; | |||
900 | } | |||
901 | *pval = (ASN1_VALUE *)stmp; | |||
902 | } else { | |||
903 | stmp = (ASN1_STRING *)*pval; | |||
904 | stmp->type = utype; | |||
905 | } | |||
906 | /* If we've already allocated a buffer use it */ | |||
907 | if (*free_cont) { | |||
908 | free(stmp->data); | |||
909 | stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ | |||
910 | stmp->length = len; | |||
911 | *free_cont = 0; | |||
912 | } else { | |||
913 | if (!ASN1_STRING_set(stmp, cont, len)) { | |||
914 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,914); | |||
915 | ASN1_STRING_free(stmp); | |||
916 | *pval = NULL((void*)0); | |||
917 | goto err; | |||
918 | } | |||
919 | } | |||
920 | break; | |||
921 | } | |||
922 | /* If ASN1_ANY and NULL type fix up value */ | |||
923 | if (typ && (utype == V_ASN1_NULL5)) | |||
924 | typ->value.ptr = NULL((void*)0); | |||
925 | ||||
926 | ret = 1; | |||
927 | ||||
928 | err: | |||
929 | if (!ret) { | |||
930 | ASN1_TYPE_free(typ); | |||
931 | if (opval) | |||
932 | *opval = NULL((void*)0); | |||
933 | } | |||
934 | return ret; | |||
935 | } | |||
936 | ||||
937 | ||||
938 | /* This function finds the end of an ASN1 structure when passed its maximum | |||
939 | * length, whether it is indefinite length and a pointer to the content. | |||
940 | * This is more efficient than calling asn1_collect because it does not | |||
941 | * recurse on each indefinite length header. | |||
942 | */ | |||
943 | ||||
944 | static int | |||
945 | asn1_find_end(const unsigned char **in, long len, char inf) | |||
946 | { | |||
947 | int expected_eoc; | |||
948 | long plen; | |||
949 | const unsigned char *p = *in, *q; | |||
950 | ||||
951 | /* If not indefinite length constructed just add length */ | |||
952 | if (inf == 0) { | |||
953 | *in += len; | |||
954 | return 1; | |||
955 | } | |||
956 | expected_eoc = 1; | |||
957 | /* Indefinite length constructed form. Find the end when enough EOCs | |||
958 | * are found. If more indefinite length constructed headers | |||
959 | * are encountered increment the expected eoc count otherwise just | |||
960 | * skip to the end of the data. | |||
961 | */ | |||
962 | while (len > 0) { | |||
963 | if (asn1_check_eoc(&p, len)) { | |||
964 | expected_eoc--; | |||
965 | if (expected_eoc == 0) | |||
966 | break; | |||
967 | len -= 2; | |||
968 | continue; | |||
969 | } | |||
970 | q = p; | |||
971 | /* Just read in a header: only care about the length */ | |||
972 | if (!asn1_check_tlen(&plen, NULL((void*)0), NULL((void*)0), &inf, NULL((void*)0), &p, len, | |||
973 | -1, 0, 0, NULL((void*)0))) { | |||
974 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,974); | |||
975 | return 0; | |||
976 | } | |||
977 | if (inf) | |||
978 | expected_eoc++; | |||
979 | else | |||
980 | p += plen; | |||
981 | len -= p - q; | |||
982 | } | |||
983 | if (expected_eoc) { | |||
984 | ASN1error(ASN1_R_MISSING_EOC)ERR_put_error(13,(0xfff),(137),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,984); | |||
985 | return 0; | |||
986 | } | |||
987 | *in = p; | |||
988 | return 1; | |||
989 | } | |||
990 | /* This function collects the asn1 data from a constructred string | |||
991 | * type into a buffer. The values of 'in' and 'len' should refer | |||
992 | * to the contents of the constructed type and 'inf' should be set | |||
993 | * if it is indefinite length. | |||
994 | */ | |||
995 | ||||
996 | #ifndef ASN1_MAX_STRING_NEST5 | |||
997 | /* This determines how many levels of recursion are permitted in ASN1 | |||
998 | * string types. If it is not limited stack overflows can occur. If set | |||
999 | * to zero no recursion is allowed at all. Although zero should be adequate | |||
1000 | * examples exist that require a value of 1. So 5 should be more than enough. | |||
1001 | */ | |||
1002 | #define ASN1_MAX_STRING_NEST5 5 | |||
1003 | #endif | |||
1004 | ||||
1005 | static int | |||
1006 | asn1_collect(CBB *cbb, const unsigned char **in, long len, char inf, | |||
1007 | int tag, int aclass, int depth) | |||
1008 | { | |||
1009 | const unsigned char *p, *q; | |||
1010 | long plen; | |||
1011 | char cst, ininf; | |||
1012 | ||||
1013 | if (depth > ASN1_MAX_STRING_NEST5) { | |||
1014 | ASN1error(ASN1_R_NESTED_ASN1_STRING)ERR_put_error(13,(0xfff),(197),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1014); | |||
1015 | return 0; | |||
1016 | } | |||
1017 | ||||
1018 | p = *in; | |||
1019 | inf &= 1; | |||
1020 | ||||
1021 | while (len > 0) { | |||
1022 | q = p; | |||
1023 | /* Check for EOC */ | |||
1024 | if (asn1_check_eoc(&p, len)) { | |||
1025 | /* EOC is illegal outside indefinite length | |||
1026 | * constructed form */ | |||
1027 | if (!inf) { | |||
1028 | ASN1error(ASN1_R_UNEXPECTED_EOC)ERR_put_error(13,(0xfff),(159),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1028); | |||
1029 | return 0; | |||
1030 | } | |||
1031 | inf = 0; | |||
1032 | break; | |||
1033 | } | |||
1034 | ||||
1035 | if (!asn1_check_tlen(&plen, NULL((void*)0), NULL((void*)0), &ininf, &cst, &p, | |||
1036 | len, tag, aclass, 0, NULL((void*)0))) { | |||
1037 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1037); | |||
1038 | return 0; | |||
1039 | } | |||
1040 | ||||
1041 | /* If indefinite length constructed update max length */ | |||
1042 | if (cst) { | |||
1043 | if (!asn1_collect(cbb, &p, plen, ininf, tag, aclass, | |||
1044 | depth + 1)) | |||
1045 | return 0; | |||
1046 | } else if (plen > 0) { | |||
1047 | if (!CBB_add_bytes(cbb, p, plen)) | |||
1048 | return 0; | |||
1049 | p += plen; | |||
1050 | } | |||
1051 | len -= p - q; | |||
1052 | } | |||
1053 | if (inf) { | |||
1054 | ASN1error(ASN1_R_MISSING_EOC)ERR_put_error(13,(0xfff),(137),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1054); | |||
1055 | return 0; | |||
1056 | } | |||
1057 | *in = p; | |||
1058 | return 1; | |||
1059 | } | |||
1060 | ||||
1061 | /* Check for ASN1 EOC and swallow it if found */ | |||
1062 | ||||
1063 | static int | |||
1064 | asn1_check_eoc(const unsigned char **in, long len) | |||
1065 | { | |||
1066 | const unsigned char *p; | |||
1067 | ||||
1068 | if (len < 2) | |||
1069 | return 0; | |||
1070 | p = *in; | |||
1071 | if (!p[0] && !p[1]) { | |||
1072 | *in += 2; | |||
1073 | return 1; | |||
1074 | } | |||
1075 | return 0; | |||
1076 | } | |||
1077 | ||||
1078 | /* Check an ASN1 tag and length: a bit like ASN1_get_object | |||
1079 | * but it sets the length for indefinite length constructed | |||
1080 | * form, we don't know the exact length but we can set an | |||
1081 | * upper bound to the amount of data available minus the | |||
1082 | * header length just read. | |||
1083 | */ | |||
1084 | ||||
1085 | static int | |||
1086 | asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, | |||
1087 | char *cst, const unsigned char **in, long len, int exptag, int expclass, | |||
1088 | char opt, ASN1_TLC *ctx) | |||
1089 | { | |||
1090 | int i; | |||
1091 | int ptag, pclass; | |||
1092 | long plen; | |||
1093 | const unsigned char *p, *q; | |||
1094 | ||||
1095 | p = *in; | |||
1096 | q = p; | |||
1097 | ||||
1098 | if (ctx && ctx->valid) { | |||
1099 | i = ctx->ret; | |||
1100 | plen = ctx->plen; | |||
1101 | pclass = ctx->pclass; | |||
1102 | ptag = ctx->ptag; | |||
1103 | p += ctx->hdrlen; | |||
1104 | } else { | |||
1105 | i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); | |||
1106 | if (ctx) { | |||
1107 | ctx->ret = i; | |||
1108 | ctx->plen = plen; | |||
1109 | ctx->pclass = pclass; | |||
1110 | ctx->ptag = ptag; | |||
1111 | ctx->hdrlen = p - q; | |||
1112 | ctx->valid = 1; | |||
1113 | /* If definite length, and no error, length + | |||
1114 | * header can't exceed total amount of data available. | |||
1115 | */ | |||
1116 | if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { | |||
1117 | ASN1error(ASN1_R_TOO_LONG)ERR_put_error(13,(0xfff),(155),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1117); | |||
1118 | asn1_tlc_invalidate(ctx); | |||
1119 | return 0; | |||
1120 | } | |||
1121 | } | |||
1122 | } | |||
1123 | ||||
1124 | if (i & 0x80) { | |||
1125 | ASN1error(ASN1_R_BAD_OBJECT_HEADER)ERR_put_error(13,(0xfff),(102),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1125); | |||
1126 | asn1_tlc_invalidate(ctx); | |||
1127 | return 0; | |||
1128 | } | |||
1129 | if (exptag >= 0) { | |||
1130 | if ((exptag != ptag) || (expclass != pclass)) { | |||
1131 | /* If type is OPTIONAL, not an error: | |||
1132 | * indicate missing type. | |||
1133 | */ | |||
1134 | if (opt) | |||
1135 | return -1; | |||
1136 | asn1_tlc_invalidate(ctx); | |||
1137 | ASN1error(ASN1_R_WRONG_TAG)ERR_put_error(13,(0xfff),(168),"/usr/src/lib/libcrypto/asn1/tasn_dec.c" ,1137); | |||
1138 | return 0; | |||
1139 | } | |||
1140 | /* We have a tag and class match: | |||
1141 | * assume we are going to do something with it */ | |||
1142 | asn1_tlc_invalidate(ctx); | |||
1143 | } | |||
1144 | ||||
1145 | if (i & 1) | |||
1146 | plen = len - (p - q); | |||
1147 | if (inf) | |||
1148 | *inf = i & 1; | |||
1149 | if (cst) | |||
1150 | *cst = i & V_ASN1_CONSTRUCTED0x20; | |||
1151 | if (olen) | |||
1152 | *olen = plen; | |||
1153 | if (oclass) | |||
1154 | *oclass = pclass; | |||
1155 | if (otag) | |||
1156 | *otag = ptag; | |||
1157 | ||||
1158 | *in = p; | |||
1159 | return 1; | |||
1160 | } |