summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/tasn_dec.c510
1 files changed, 287 insertions, 223 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c
index 3cc2146e45..f9c5fa81b8 100644
--- a/src/lib/libcrypto/asn1/tasn_dec.c
+++ b/src/lib/libcrypto/asn1/tasn_dec.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tasn_dec.c,v 1.60 2022/05/07 10:13:56 jsing Exp $ */ 1/* $OpenBSD: tasn_dec.c,v 1.61 2022/05/07 15:50:25 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -121,38 +121,305 @@ ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
121 return asn1_template_ex_d2i(pval, in, len, tt, 0, 0); 121 return asn1_template_ex_d2i(pval, in, len, tt, 0, 0);
122} 122}
123 123
124/* Decode an item, taking care of IMPLICIT tagging, if any. 124static int
125 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 125asn1_item_ex_d2i_choice(ASN1_VALUE **pval, const unsigned char **in, long len,
126 */ 126 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth)
127{
128 const ASN1_TEMPLATE *tt, *errtt = NULL;
129 const ASN1_AUX *aux = it->funcs;
130 ASN1_aux_cb *asn1_cb = NULL;
131 ASN1_VALUE **pchptr;
132 const unsigned char *p = NULL;
133 int i;
134 int ret = 0;
135 int combine;
136
137 combine = aclass & ASN1_TFLG_COMBINE;
138 aclass &= ~ASN1_TFLG_COMBINE;
139
140 if (it->itype != ASN1_ITYPE_CHOICE)
141 goto err;
142
143 if (aux && aux->asn1_cb)
144 asn1_cb = aux->asn1_cb;
145
146 /*
147 * It never makes sense for CHOICE types to have implicit
148 * tagging, so if tag != -1, then this looks like an error in
149 * the template.
150 */
151 if (tag != -1) {
152 ASN1error(ASN1_R_BAD_TEMPLATE);
153 goto err;
154 }
155
156 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
157 goto auxerr;
158
159 if (*pval) {
160 /* Free up and zero CHOICE value if initialised */
161 i = asn1_get_choice_selector(pval, it);
162 if ((i >= 0) && (i < it->tcount)) {
163 tt = it->templates + i;
164 pchptr = asn1_get_field_ptr(pval, tt);
165 ASN1_template_free(pchptr, tt);
166 asn1_set_choice_selector(pval, -1, it);
167 }
168 } else if (!ASN1_item_ex_new(pval, it)) {
169 ASN1error(ERR_R_NESTED_ASN1_ERROR);
170 goto err;
171 }
172 /* CHOICE type, try each possibility in turn */
173 p = *in;
174 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
175 pchptr = asn1_get_field_ptr(pval, tt);
176 /* We mark field as OPTIONAL so its absence
177 * can be recognised.
178 */
179 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1,
180 depth);
181 /* If field not present, try the next one */
182 if (ret == -1)
183 continue;
184 /* If positive return, read OK, break loop */
185 if (ret > 0)
186 break;
187 /* Otherwise must be an ASN1 parsing error */
188 errtt = tt;
189 ASN1error(ERR_R_NESTED_ASN1_ERROR);
190 goto err;
191 }
192
193 /* Did we fall off the end without reading anything? */
194 if (i == it->tcount) {
195 /* If OPTIONAL, this is OK */
196 if (opt) {
197 /* Free and zero it */
198 ASN1_item_ex_free(pval, it);
199 return -1;
200 }
201 ASN1error(ASN1_R_NO_MATCHING_CHOICE_TYPE);
202 goto err;
203 }
204
205 asn1_set_choice_selector(pval, i, it);
206 *in = p;
207 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
208 goto auxerr;
209 return 1;
210
211 auxerr:
212 ASN1error(ASN1_R_AUX_ERROR);
213 err:
214 if (combine == 0)
215 ASN1_item_ex_free(pval, it);
216 if (errtt)
217 ERR_asprintf_error_data("Field=%s, Type=%s", errtt->field_name,
218 it->sname);
219 else
220 ERR_asprintf_error_data("Type=%s", it->sname);
221 return 0;
222}
127 223
128static int 224static int
129asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 225asn1_item_ex_d2i_sequence(ASN1_VALUE **pval, const unsigned char **in, long len,
130 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth) 226 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth)
131{ 227{
132 const ASN1_TEMPLATE *tt, *errtt = NULL; 228 const ASN1_TEMPLATE *tt, *errtt = NULL;
133 const ASN1_EXTERN_FUNCS *ef;
134 const ASN1_AUX *aux = it->funcs; 229 const ASN1_AUX *aux = it->funcs;
135 ASN1_aux_cb *asn1_cb = NULL; 230 ASN1_aux_cb *asn1_cb = NULL;
136 ASN1_TLC ctx = { 0 };
137 const unsigned char *p = NULL, *q;
138 unsigned char oclass;
139 char seq_eoc, seq_nolen, cst, isopt; 231 char seq_eoc, seq_nolen, cst, isopt;
232 const unsigned char *p = NULL, *q;
140 long tmplen; 233 long tmplen;
141 int i; 234 int i;
142 int otag;
143 int ret = 0; 235 int ret = 0;
144 ASN1_VALUE **pchptr;
145 int combine; 236 int combine;
146 237
147 combine = aclass & ASN1_TFLG_COMBINE; 238 combine = aclass & ASN1_TFLG_COMBINE;
148 aclass &= ~ASN1_TFLG_COMBINE; 239 aclass &= ~ASN1_TFLG_COMBINE;
149 240
150 if (!pval) 241 if (it->itype != ASN1_ITYPE_NDEF_SEQUENCE &&
151 return 0; 242 it->itype != ASN1_ITYPE_SEQUENCE)
243 goto err;
152 244
153 if (aux && aux->asn1_cb) 245 if (aux && aux->asn1_cb)
154 asn1_cb = aux->asn1_cb; 246 asn1_cb = aux->asn1_cb;
155 247
248 p = *in;
249 tmplen = len;
250
251 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
252 if (tag == -1) {
253 tag = V_ASN1_SEQUENCE;
254 aclass = V_ASN1_UNIVERSAL;
255 }
256 /* Get SEQUENCE length and update len, p */
257 ret = asn1_check_tag(&len, NULL, NULL, &seq_eoc, &cst, &p, len,
258 tag, aclass, opt);
259 if (!ret) {
260 ASN1error(ERR_R_NESTED_ASN1_ERROR);
261 goto err;
262 } else if (ret == -1)
263 return -1;
264 if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
265 len = tmplen - (p - *in);
266 seq_nolen = 1;
267 }
268 /* If indefinite we don't do a length check */
269 else
270 seq_nolen = seq_eoc;
271 if (!cst) {
272 ASN1error(ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
273 goto err;
274 }
275
276 if (!*pval && !ASN1_item_ex_new(pval, it)) {
277 ASN1error(ERR_R_NESTED_ASN1_ERROR);
278 goto err;
279 }
280
281 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
282 goto auxerr;
283
284 /* Free up and zero any ADB found */
285 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
286 if (tt->flags & ASN1_TFLG_ADB_MASK) {
287 const ASN1_TEMPLATE *seqtt;
288 ASN1_VALUE **pseqval;
289 seqtt = asn1_do_adb(pval, tt, 1);
290 if (!seqtt)
291 goto err;
292 pseqval = asn1_get_field_ptr(pval, seqtt);
293 ASN1_template_free(pseqval, seqtt);
294 }
295 }
296
297 /* Get each field entry */
298 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
299 const ASN1_TEMPLATE *seqtt;
300 ASN1_VALUE **pseqval;
301 seqtt = asn1_do_adb(pval, tt, 1);
302 if (!seqtt)
303 goto err;
304 pseqval = asn1_get_field_ptr(pval, seqtt);
305 /* Have we ran out of data? */
306 if (!len)
307 break;
308 q = p;
309 if (asn1_check_eoc(&p, len)) {
310 if (!seq_eoc) {
311 ASN1error(ASN1_R_UNEXPECTED_EOC);
312 goto err;
313 }
314 len -= p - q;
315 seq_eoc = 0;
316 q = p;
317 break;
318 }
319 /* This determines the OPTIONAL flag value. The field
320 * cannot be omitted if it is the last of a SEQUENCE
321 * and there is still data to be read. This isn't
322 * strictly necessary but it increases efficiency in
323 * some cases.
324 */
325 if (i == (it->tcount - 1))
326 isopt = 0;
327 else
328 isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
329 /* attempt to read in field, allowing each to be
330 * OPTIONAL */
331
332 ret = asn1_template_ex_d2i(pseqval, &p, len,
333 seqtt, isopt, depth);
334 if (!ret) {
335 errtt = seqtt;
336 goto err;
337 } else if (ret == -1) {
338 /* OPTIONAL component absent.
339 * Free and zero the field.
340 */
341 ASN1_template_free(pseqval, seqtt);
342 continue;
343 }
344 /* Update length */
345 len -= p - q;
346 }
347
348 /* Check for EOC if expecting one */
349 if (seq_eoc && !asn1_check_eoc(&p, len)) {
350 ASN1error(ASN1_R_MISSING_EOC);
351 goto err;
352 }
353 /* Check all data read */
354 if (!seq_nolen && len) {
355 ASN1error(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)
367 goto err;
368 if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
369 ASN1_VALUE **pseqval;
370 pseqval = asn1_get_field_ptr(pval, seqtt);
371 ASN1_template_free(pseqval, seqtt);
372 } else {
373 errtt = seqtt;
374 ASN1error(ASN1_R_FIELD_MISSING);
375 goto err;
376 }
377 }
378 /* Save encoding */
379 if (!asn1_enc_save(pval, *in, p - *in, it)) {
380 ASN1error(ERR_R_MALLOC_FAILURE);
381 goto auxerr;
382 }
383 *in = p;
384 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
385 goto auxerr;
386 return 1;
387
388 auxerr:
389 ASN1error(ASN1_R_AUX_ERROR);
390 err:
391 if (combine == 0)
392 ASN1_item_ex_free(pval, it);
393 if (errtt)
394 ERR_asprintf_error_data("Field=%s, Type=%s", errtt->field_name,
395 it->sname);
396 else
397 ERR_asprintf_error_data("Type=%s", it->sname);
398 return 0;
399}
400
401/*
402 * Decode an item, taking care of IMPLICIT tagging, if any.
403 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
404 */
405static int
406asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
407 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth)
408{
409 const ASN1_EXTERN_FUNCS *ef;
410 ASN1_TLC ctx = { 0 };
411 const unsigned char *p = NULL;
412 unsigned char oclass;
413 int otag;
414 int ret = 0;
415 int combine;
416
417 combine = aclass & ASN1_TFLG_COMBINE;
418 aclass &= ~ASN1_TFLG_COMBINE;
419
420 if (!pval)
421 return 0;
422
156 if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { 423 if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
157 ASN1error(ASN1_R_NESTED_TOO_DEEP); 424 ASN1error(ASN1_R_NESTED_TOO_DEEP);
158 goto err; 425 goto err;
@@ -223,227 +490,24 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
223 return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, &ctx); 490 return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, &ctx);
224 491
225 case ASN1_ITYPE_CHOICE: 492 case ASN1_ITYPE_CHOICE:
226 /* 493 return asn1_item_ex_d2i_choice(pval, in, len, it, tag,
227 * It never makes sense for CHOICE types to have implicit 494 aclass | combine, opt, depth);
228 * tagging, so if tag != -1, then this looks like an error in
229 * the template.
230 */
231 if (tag != -1) {
232 ASN1error(ASN1_R_BAD_TEMPLATE);
233 goto err;
234 }
235
236 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
237 goto auxerr;
238
239 if (*pval) {
240 /* Free up and zero CHOICE value if initialised */
241 i = asn1_get_choice_selector(pval, it);
242 if ((i >= 0) && (i < it->tcount)) {
243 tt = it->templates + i;
244 pchptr = asn1_get_field_ptr(pval, tt);
245 ASN1_template_free(pchptr, tt);
246 asn1_set_choice_selector(pval, -1, it);
247 }
248 } else if (!ASN1_item_ex_new(pval, it)) {
249 ASN1error(ERR_R_NESTED_ASN1_ERROR);
250 goto err;
251 }
252 /* CHOICE type, try each possibility in turn */
253 p = *in;
254 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
255 pchptr = asn1_get_field_ptr(pval, tt);
256 /* We mark field as OPTIONAL so its absence
257 * can be recognised.
258 */
259 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1,
260 depth);
261 /* If field not present, try the next one */
262 if (ret == -1)
263 continue;
264 /* If positive return, read OK, break loop */
265 if (ret > 0)
266 break;
267 /* Otherwise must be an ASN1 parsing error */
268 errtt = tt;
269 ASN1error(ERR_R_NESTED_ASN1_ERROR);
270 goto err;
271 }
272
273 /* Did we fall off the end without reading anything? */
274 if (i == it->tcount) {
275 /* If OPTIONAL, this is OK */
276 if (opt) {
277 /* Free and zero it */
278 ASN1_item_ex_free(pval, it);
279 return -1;
280 }
281 ASN1error(ASN1_R_NO_MATCHING_CHOICE_TYPE);
282 goto err;
283 }
284
285 asn1_set_choice_selector(pval, i, it);
286 *in = p;
287 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
288 goto auxerr;
289 return 1;
290 495
291 case ASN1_ITYPE_NDEF_SEQUENCE: 496 case ASN1_ITYPE_NDEF_SEQUENCE:
292 case ASN1_ITYPE_SEQUENCE: 497 case ASN1_ITYPE_SEQUENCE:
293 p = *in; 498 return asn1_item_ex_d2i_sequence(pval, in, len, it, tag,
294 tmplen = len; 499 aclass | combine, opt, depth);
295
296 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
297 if (tag == -1) {
298 tag = V_ASN1_SEQUENCE;
299 aclass = V_ASN1_UNIVERSAL;
300 }
301 /* Get SEQUENCE length and update len, p */
302 ret = asn1_check_tag(&len, NULL, NULL, &seq_eoc, &cst, &p, len,
303 tag, aclass, opt);
304 if (!ret) {
305 ASN1error(ERR_R_NESTED_ASN1_ERROR);
306 goto err;
307 } else if (ret == -1)
308 return -1;
309 if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
310 len = tmplen - (p - *in);
311 seq_nolen = 1;
312 }
313 /* If indefinite we don't do a length check */
314 else
315 seq_nolen = seq_eoc;
316 if (!cst) {
317 ASN1error(ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
318 goto err;
319 }
320
321 if (!*pval && !ASN1_item_ex_new(pval, it)) {
322 ASN1error(ERR_R_NESTED_ASN1_ERROR);
323 goto err;
324 }
325
326 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
327 goto auxerr;
328
329 /* Free up and zero any ADB found */
330 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
331 if (tt->flags & ASN1_TFLG_ADB_MASK) {
332 const ASN1_TEMPLATE *seqtt;
333 ASN1_VALUE **pseqval;
334 seqtt = asn1_do_adb(pval, tt, 1);
335 if (!seqtt)
336 goto err;
337 pseqval = asn1_get_field_ptr(pval, seqtt);
338 ASN1_template_free(pseqval, seqtt);
339 }
340 }
341
342 /* Get each field entry */
343 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
344 const ASN1_TEMPLATE *seqtt;
345 ASN1_VALUE **pseqval;
346 seqtt = asn1_do_adb(pval, tt, 1);
347 if (!seqtt)
348 goto err;
349 pseqval = asn1_get_field_ptr(pval, seqtt);
350 /* Have we ran out of data? */
351 if (!len)
352 break;
353 q = p;
354 if (asn1_check_eoc(&p, len)) {
355 if (!seq_eoc) {
356 ASN1error(ASN1_R_UNEXPECTED_EOC);
357 goto err;
358 }
359 len -= p - q;
360 seq_eoc = 0;
361 q = p;
362 break;
363 }
364 /* This determines the OPTIONAL flag value. The field
365 * cannot be omitted if it is the last of a SEQUENCE
366 * and there is still data to be read. This isn't
367 * strictly necessary but it increases efficiency in
368 * some cases.
369 */
370 if (i == (it->tcount - 1))
371 isopt = 0;
372 else
373 isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
374 /* attempt to read in field, allowing each to be
375 * OPTIONAL */
376
377 ret = asn1_template_ex_d2i(pseqval, &p, len,
378 seqtt, isopt, depth);
379 if (!ret) {
380 errtt = seqtt;
381 goto err;
382 } else if (ret == -1) {
383 /* OPTIONAL component absent.
384 * Free and zero the field.
385 */
386 ASN1_template_free(pseqval, seqtt);
387 continue;
388 }
389 /* Update length */
390 len -= p - q;
391 }
392
393 /* Check for EOC if expecting one */
394 if (seq_eoc && !asn1_check_eoc(&p, len)) {
395 ASN1error(ASN1_R_MISSING_EOC);
396 goto err;
397 }
398 /* Check all data read */
399 if (!seq_nolen && len) {
400 ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH);
401 goto err;
402 }
403
404 /* If we get here we've got no more data in the SEQUENCE,
405 * however we may not have read all fields so check all
406 * remaining are OPTIONAL and clear any that are.
407 */
408 for (; i < it->tcount; tt++, i++) {
409 const ASN1_TEMPLATE *seqtt;
410 seqtt = asn1_do_adb(pval, tt, 1);
411 if (!seqtt)
412 goto err;
413 if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
414 ASN1_VALUE **pseqval;
415 pseqval = asn1_get_field_ptr(pval, seqtt);
416 ASN1_template_free(pseqval, seqtt);
417 } else {
418 errtt = seqtt;
419 ASN1error(ASN1_R_FIELD_MISSING);
420 goto err;
421 }
422 }
423 /* Save encoding */
424 if (!asn1_enc_save(pval, *in, p - *in, it)) {
425 ASN1error(ERR_R_MALLOC_FAILURE);
426 goto auxerr;
427 }
428 *in = p;
429 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
430 goto auxerr;
431 return 1;
432 500
433 default: 501 default:
434 return 0; 502 return 0;
435 } 503 }
436 504
437 auxerr:
438 ASN1error(ASN1_R_AUX_ERROR);
439 err: 505 err:
440 if (combine == 0) 506 if (combine == 0)
441 ASN1_item_ex_free(pval, it); 507 ASN1_item_ex_free(pval, it);
442 if (errtt) 508
443 ERR_asprintf_error_data("Field=%s, Type=%s", errtt->field_name, 509 ERR_asprintf_error_data("Type=%s", it->sname);
444 it->sname); 510
445 else
446 ERR_asprintf_error_data("Type=%s", it->sname);
447 return 0; 511 return 0;
448} 512}
449 513