OLD | NEW |
1 /* tasn_dec.c */ | 1 /* tasn_dec.c */ |
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 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 107 |
108 unsigned long ASN1_tag2bit(int tag) | 108 unsigned long ASN1_tag2bit(int tag) |
109 { | 109 { |
110 if ((tag < 0) || (tag > 30)) return 0; | 110 if ((tag < 0) || (tag > 30)) return 0; |
111 return tag2bit[tag]; | 111 return tag2bit[tag]; |
112 } | 112 } |
113 | 113 |
114 /* Macro to initialize and invalidate the cache */ | 114 /* Macro to initialize and invalidate the cache */ |
115 | 115 |
116 #define asn1_tlc_clear(c) if (c) (c)->valid = 0 | 116 #define asn1_tlc_clear(c) if (c) (c)->valid = 0 |
| 117 /* Version to avoid compiler warning about 'c' always non-NULL */ |
| 118 #define asn1_tlc_clear_nc(c) (c)->valid = 0 |
117 | 119 |
118 /* Decode an ASN1 item, this currently behaves just | 120 /* Decode an ASN1 item, this currently behaves just |
119 * like a standard 'd2i' function. 'in' points to | 121 * like a standard 'd2i' function. 'in' points to |
120 * a buffer to read the data from, in future we will | 122 * a buffer to read the data from, in future we will |
121 * have more advanced versions that can input data | 123 * have more advanced versions that can input data |
122 * a piece at a time and this will simply be a special | 124 * a piece at a time and this will simply be a special |
123 * case. | 125 * case. |
124 */ | 126 */ |
125 | 127 |
126 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, | 128 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, |
127 const unsigned char **in, long len, const ASN1_ITEM *it) | 129 const unsigned char **in, long len, const ASN1_ITEM *it) |
128 { | 130 { |
129 ASN1_TLC c; | 131 ASN1_TLC c; |
130 ASN1_VALUE *ptmpval = NULL; | 132 ASN1_VALUE *ptmpval = NULL; |
131 if (!pval) | 133 if (!pval) |
132 pval = &ptmpval; | 134 pval = &ptmpval; |
133 » c.valid = 0; | 135 » asn1_tlc_clear_nc(&c); |
134 if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) | 136 if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) |
135 return *pval; | 137 return *pval; |
136 return NULL; | 138 return NULL; |
137 } | 139 } |
138 | 140 |
139 int ASN1_template_d2i(ASN1_VALUE **pval, | 141 int ASN1_template_d2i(ASN1_VALUE **pval, |
140 const unsigned char **in, long len, const ASN1_TEMPLATE *tt) | 142 const unsigned char **in, long len, const ASN1_TEMPLATE *tt) |
141 { | 143 { |
142 ASN1_TLC c; | 144 ASN1_TLC c; |
143 » c.valid = 0; | 145 » asn1_tlc_clear_nc(&c); |
144 return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); | 146 return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); |
145 } | 147 } |
146 | 148 |
147 | 149 |
148 /* Decode an item, taking care of IMPLICIT tagging, if any. | 150 /* Decode an item, taking care of IMPLICIT tagging, if any. |
149 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL | 151 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL |
150 */ | 152 */ |
151 | 153 |
152 int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | 154 int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
153 const ASN1_ITEM *it, | 155 const ASN1_ITEM *it, |
154 int tag, int aclass, char opt, ASN1_TLC *ctx) | 156 int tag, int aclass, char opt, ASN1_TLC *ctx) |
155 { | 157 { |
156 const ASN1_TEMPLATE *tt, *errtt = NULL; | 158 const ASN1_TEMPLATE *tt, *errtt = NULL; |
157 const ASN1_COMPAT_FUNCS *cf; | 159 const ASN1_COMPAT_FUNCS *cf; |
158 const ASN1_EXTERN_FUNCS *ef; | 160 const ASN1_EXTERN_FUNCS *ef; |
159 const ASN1_AUX *aux = it->funcs; | 161 const ASN1_AUX *aux = it->funcs; |
160 ASN1_aux_cb *asn1_cb; | 162 ASN1_aux_cb *asn1_cb; |
161 const unsigned char *p = NULL, *q; | 163 const unsigned char *p = NULL, *q; |
162 unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ | 164 unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ |
163 unsigned char imphack = 0, oclass; | 165 unsigned char imphack = 0, oclass; |
164 char seq_eoc, seq_nolen, cst, isopt; | 166 char seq_eoc, seq_nolen, cst, isopt; |
165 long tmplen; | 167 long tmplen; |
166 int i; | 168 int i; |
167 int otag; | 169 int otag; |
168 int ret = 0; | 170 int ret = 0; |
169 » ASN1_VALUE *pchval, **pchptr, *ptmpval; | 171 » ASN1_VALUE **pchptr, *ptmpval; |
170 if (!pval) | 172 if (!pval) |
171 return 0; | 173 return 0; |
172 if (aux && aux->asn1_cb) | 174 if (aux && aux->asn1_cb) |
173 asn1_cb = aux->asn1_cb; | 175 asn1_cb = aux->asn1_cb; |
174 else asn1_cb = 0; | 176 else asn1_cb = 0; |
175 | 177 |
176 switch(it->itype) | 178 switch(it->itype) |
177 { | 179 { |
178 case ASN1_ITYPE_PRIMITIVE: | 180 case ASN1_ITYPE_PRIMITIVE: |
179 if (it->templates) | 181 if (it->templates) |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 *wp = imphack; | 301 *wp = imphack; |
300 | 302 |
301 if (ptmpval) | 303 if (ptmpval) |
302 return 1; | 304 return 1; |
303 | 305 |
304 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | 306 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); |
305 goto err; | 307 goto err; |
306 | 308 |
307 | 309 |
308 case ASN1_ITYPE_CHOICE: | 310 case ASN1_ITYPE_CHOICE: |
309 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) | 311 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) |
310 goto auxerr; | 312 goto auxerr; |
311 | 313 |
312 /* Allocate structure */ | 314 /* Allocate structure */ |
313 if (!*pval && !ASN1_item_ex_new(pval, it)) | 315 if (!*pval && !ASN1_item_ex_new(pval, it)) |
314 { | 316 { |
315 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, | 317 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, |
316 ERR_R_NESTED_ASN1_ERROR); | 318 ERR_R_NESTED_ASN1_ERROR); |
317 goto err; | 319 goto err; |
318 } | 320 } |
319 /* CHOICE type, try each possibility in turn */ | 321 /* CHOICE type, try each possibility in turn */ |
320 pchval = NULL; | |
321 p = *in; | 322 p = *in; |
322 for (i = 0, tt=it->templates; i < it->tcount; i++, tt++) | 323 for (i = 0, tt=it->templates; i < it->tcount; i++, tt++) |
323 { | 324 { |
324 pchptr = asn1_get_field_ptr(pval, tt); | 325 pchptr = asn1_get_field_ptr(pval, tt); |
325 /* We mark field as OPTIONAL so its absence | 326 /* We mark field as OPTIONAL so its absence |
326 * can be recognised. | 327 * can be recognised. |
327 */ | 328 */ |
328 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); | 329 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); |
329 /* If field not present, try the next one */ | 330 /* If field not present, try the next one */ |
330 if (ret == -1) | 331 if (ret == -1) |
(...skipping 18 matching lines...) Expand all Loading... |
349 ASN1_item_ex_free(pval, it); | 350 ASN1_item_ex_free(pval, it); |
350 return -1; | 351 return -1; |
351 } | 352 } |
352 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, | 353 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, |
353 ASN1_R_NO_MATCHING_CHOICE_TYPE); | 354 ASN1_R_NO_MATCHING_CHOICE_TYPE); |
354 goto err; | 355 goto err; |
355 } | 356 } |
356 | 357 |
357 asn1_set_choice_selector(pval, i, it); | 358 asn1_set_choice_selector(pval, i, it); |
358 *in = p; | 359 *in = p; |
359 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) | 360 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) |
360 goto auxerr; | 361 goto auxerr; |
361 return 1; | 362 return 1; |
362 | 363 |
363 case ASN1_ITYPE_NDEF_SEQUENCE: | 364 case ASN1_ITYPE_NDEF_SEQUENCE: |
364 case ASN1_ITYPE_SEQUENCE: | 365 case ASN1_ITYPE_SEQUENCE: |
365 p = *in; | 366 p = *in; |
366 tmplen = len; | 367 tmplen = len; |
367 | 368 |
368 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ | 369 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ |
369 if (tag == -1) | 370 if (tag == -1) |
(...skipping 26 matching lines...) Expand all Loading... |
396 goto err; | 397 goto err; |
397 } | 398 } |
398 | 399 |
399 if (!*pval && !ASN1_item_ex_new(pval, it)) | 400 if (!*pval && !ASN1_item_ex_new(pval, it)) |
400 { | 401 { |
401 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, | 402 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, |
402 ERR_R_NESTED_ASN1_ERROR); | 403 ERR_R_NESTED_ASN1_ERROR); |
403 goto err; | 404 goto err; |
404 } | 405 } |
405 | 406 |
406 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) | 407 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) |
407 goto auxerr; | 408 goto auxerr; |
408 | 409 |
409 /* Get each field entry */ | 410 /* Get each field entry */ |
410 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) | 411 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) |
411 { | 412 { |
412 const ASN1_TEMPLATE *seqtt; | 413 const ASN1_TEMPLATE *seqtt; |
413 ASN1_VALUE **pseqval; | 414 ASN1_VALUE **pseqval; |
414 seqtt = asn1_do_adb(pval, tt, 1); | 415 seqtt = asn1_do_adb(pval, tt, 1); |
415 if (!seqtt) | 416 if (!seqtt) |
416 goto err; | 417 goto err; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 errtt = seqtt; | 499 errtt = seqtt; |
499 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, | 500 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, |
500 ASN1_R_FIELD_MISSING); | 501 ASN1_R_FIELD_MISSING); |
501 goto err; | 502 goto err; |
502 } | 503 } |
503 } | 504 } |
504 /* Save encoding */ | 505 /* Save encoding */ |
505 if (!asn1_enc_save(pval, *in, p - *in, it)) | 506 if (!asn1_enc_save(pval, *in, p - *in, it)) |
506 goto auxerr; | 507 goto auxerr; |
507 *in = p; | 508 *in = p; |
508 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) | 509 » » if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) |
509 goto auxerr; | 510 goto auxerr; |
510 return 1; | 511 return 1; |
511 | 512 |
512 default: | 513 default: |
513 return 0; | 514 return 0; |
514 } | 515 } |
515 auxerr: | 516 auxerr: |
516 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); | 517 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); |
517 err: | 518 err: |
518 ASN1_item_ex_free(pval, it); | 519 ASN1_item_ex_free(pval, it); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 ERR_R_NESTED_ASN1_ERROR); | 659 ERR_R_NESTED_ASN1_ERROR); |
659 return 0; | 660 return 0; |
660 } | 661 } |
661 else if (ret == -1) | 662 else if (ret == -1) |
662 return -1; | 663 return -1; |
663 if (!*val) | 664 if (!*val) |
664 *val = (ASN1_VALUE *)sk_new_null(); | 665 *val = (ASN1_VALUE *)sk_new_null(); |
665 else | 666 else |
666 { | 667 { |
667 /* We've got a valid STACK: free up any items present */ | 668 /* We've got a valid STACK: free up any items present */ |
668 » » » STACK *sktmp = (STACK *)*val; | 669 » » » STACK_OF(ASN1_VALUE) *sktmp |
| 670 » » » = (STACK_OF(ASN1_VALUE) *)*val; |
669 ASN1_VALUE *vtmp; | 671 ASN1_VALUE *vtmp; |
670 » » » while(sk_num(sktmp) > 0) | 672 » » » while(sk_ASN1_VALUE_num(sktmp) > 0) |
671 { | 673 { |
672 » » » » vtmp = (ASN1_VALUE *)sk_pop(sktmp); | 674 » » » » vtmp = sk_ASN1_VALUE_pop(sktmp); |
673 ASN1_item_ex_free(&vtmp, | 675 ASN1_item_ex_free(&vtmp, |
674 ASN1_ITEM_ptr(tt->item)); | 676 ASN1_ITEM_ptr(tt->item)); |
675 } | 677 } |
676 } | 678 } |
677 | 679 |
678 if (!*val) | 680 if (!*val) |
679 { | 681 { |
680 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, | 682 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, |
681 ERR_R_MALLOC_FAILURE); | 683 ERR_R_MALLOC_FAILURE); |
682 goto err; | 684 goto err; |
(...skipping 20 matching lines...) Expand all Loading... |
703 skfield = NULL; | 705 skfield = NULL; |
704 if (!ASN1_item_ex_d2i(&skfield, &p, len, | 706 if (!ASN1_item_ex_d2i(&skfield, &p, len, |
705 ASN1_ITEM_ptr(tt->item), | 707 ASN1_ITEM_ptr(tt->item), |
706 -1, 0, 0, ctx)) | 708 -1, 0, 0, ctx)) |
707 { | 709 { |
708 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, | 710 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, |
709 ERR_R_NESTED_ASN1_ERROR); | 711 ERR_R_NESTED_ASN1_ERROR); |
710 goto err; | 712 goto err; |
711 } | 713 } |
712 len -= p - q; | 714 len -= p - q; |
713 » » » if (!sk_push((STACK *)*val, (char *)skfield)) | 715 » » » if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, |
| 716 » » » » » » skfield)) |
714 { | 717 { |
715 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, | 718 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, |
716 ERR_R_MALLOC_FAILURE); | 719 ERR_R_MALLOC_FAILURE); |
717 goto err; | 720 goto err; |
718 } | 721 } |
719 } | 722 } |
720 if (sk_eoc) | 723 if (sk_eoc) |
721 { | 724 { |
722 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_E
OC); | 725 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_E
OC); |
723 goto err; | 726 goto err; |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 | 1338 |
1336 if (oclass) | 1339 if (oclass) |
1337 *oclass = pclass; | 1340 *oclass = pclass; |
1338 | 1341 |
1339 if (otag) | 1342 if (otag) |
1340 *otag = ptag; | 1343 *otag = ptag; |
1341 | 1344 |
1342 *in = p; | 1345 *in = p; |
1343 return 1; | 1346 return 1; |
1344 } | 1347 } |
OLD | NEW |