| 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 |