00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <int.h>
00030 #include "parser_aux.h"
00031 #include <gstr.h>
00032 #include "structure.h"
00033 #include "element.h"
00034
00035
00036 static void
00037 MHD__asn1_error_description_tag_error (node_asn * node,
00038 char *ErrorDescription)
00039 {
00040
00041 Estrcpy (ErrorDescription, ":: tag error near element '");
00042 MHD__asn1_hierarchical_name (node,
00043 ErrorDescription + strlen (ErrorDescription),
00044 MAX_ERROR_DESCRIPTION_SIZE - 40);
00045 Estrcat (ErrorDescription, "'");
00046
00047 }
00048
00060 signed long
00061 MHD__asn1_get_length_der (const unsigned char *der, int der_len, int *len)
00062 {
00063 unsigned long ans;
00064 int k, punt;
00065
00066 *len = 0;
00067 if (der_len <= 0)
00068 return 0;
00069
00070 if (!(der[0] & 128))
00071 {
00072
00073 *len = 1;
00074 return der[0];
00075 }
00076 else
00077 {
00078
00079 k = der[0] & 0x7F;
00080 punt = 1;
00081 if (k)
00082 {
00083 ans = 0;
00084 while (punt <= k && punt < der_len)
00085 {
00086 unsigned long last = ans;
00087
00088 ans = ans * 256 + der[punt++];
00089 if (ans < last)
00090
00091 return -2;
00092 }
00093 }
00094 else
00095 {
00096 ans = -1;
00097 }
00098
00099 *len = punt;
00100 return ans;
00101 }
00102 }
00103
00104
00105
00106
00119 int
00120 MHD__asn1_get_tag_der (const unsigned char *der, int der_len,
00121 unsigned char *cls, int *len, unsigned long *tag)
00122 {
00123 int punt, ris;
00124
00125 if (der == NULL || der_len <= 0 || len == NULL)
00126 return ASN1_DER_ERROR;
00127
00128 *cls = der[0] & 0xE0;
00129 if ((der[0] & 0x1F) != 0x1F)
00130 {
00131
00132 *len = 1;
00133 ris = der[0] & 0x1F;
00134 }
00135 else
00136 {
00137
00138 punt = 1;
00139 ris = 0;
00140 while (punt <= der_len && der[punt] & 128)
00141 {
00142 int last = ris;
00143 ris = ris * 128 + (der[punt++] & 0x7F);
00144 if (ris < last)
00145
00146 return ASN1_DER_ERROR;
00147 }
00148 if (punt >= der_len)
00149 return ASN1_DER_ERROR;
00150 {
00151 int last = ris;
00152 ris = ris * 128 + (der[punt++] & 0x7F);
00153 if (ris < last)
00154
00155 return ASN1_DER_ERROR;
00156 }
00157 *len = punt;
00158 }
00159 if (tag)
00160 *tag = ris;
00161 return ASN1_SUCCESS;
00162 }
00163
00164
00165
00166
00180 int
00181 MHD__asn1_get_octet_der (const unsigned char *der, int der_len,
00182 int *ret_len, unsigned char *str, int str_size,
00183 int *str_len)
00184 {
00185 int len_len;
00186
00187 if (der_len <= 0)
00188 return ASN1_GENERIC_ERROR;
00189
00190
00191 *str_len = MHD__asn1_get_length_der (der, der_len, &len_len);
00192
00193 if (*str_len < 0)
00194 return ASN1_DER_ERROR;
00195
00196 *ret_len = *str_len + len_len;
00197 if (str_size >= *str_len)
00198 memcpy (str, der + len_len, *str_len);
00199 else
00200 {
00201 return ASN1_MEM_ERROR;
00202 }
00203
00204 return ASN1_SUCCESS;
00205 }
00206
00207
00208
00209
00210
00211 static int
00212 MHD__asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
00213 char *str, int str_size)
00214 {
00215 int len_len, str_len;
00216
00217 if (der_len <= 0 || str == NULL)
00218 return ASN1_DER_ERROR;
00219 str_len = MHD__asn1_get_length_der (der, der_len, &len_len);
00220 if (str_len < 0 || str_size < str_len)
00221 return ASN1_DER_ERROR;
00222 memcpy (str, der + len_len, str_len);
00223 str[str_len] = 0;
00224 *ret_len = str_len + len_len;
00225
00226 return ASN1_SUCCESS;
00227 }
00228
00229
00230
00231 static void
00232 MHD__asn1_get_objectid_der (const unsigned char *der, int der_len,
00233 int *ret_len, char *str, int str_size)
00234 {
00235 int len_len, len, k;
00236 char temp[20];
00237 unsigned long val, val1;
00238
00239 *ret_len = 0;
00240 if (str && str_size > 0)
00241 str[0] = 0;
00242
00243 if (str == NULL || der_len <= 0)
00244 return;
00245 len = MHD__asn1_get_length_der (der, der_len, &len_len);
00246
00247 if (len < 0 || len > der_len || len_len > der_len)
00248 return;
00249
00250 val1 = der[len_len] / 40;
00251 val = der[len_len] - val1 * 40;
00252
00253 MHD__asn1_str_cpy (str, str_size, MHD__asn1_ltostr (val1, temp));
00254 MHD__asn1_str_cat (str, str_size, ".");
00255 MHD__asn1_str_cat (str, str_size, MHD__asn1_ltostr (val, temp));
00256
00257 val = 0;
00258 for (k = 1; k < len; k++)
00259 {
00260 val = val << 7;
00261 val |= der[len_len + k] & 0x7F;
00262 if (!(der[len_len + k] & 0x80))
00263 {
00264 MHD__asn1_str_cat (str, str_size, ".");
00265 MHD__asn1_str_cat (str, str_size, MHD__asn1_ltostr (val, temp));
00266 val = 0;
00267 }
00268 }
00269 *ret_len = len + len_len;
00270 }
00271
00272
00273
00274
00288 int
00289 MHD__asn1_get_bit_der (const unsigned char *der, int der_len,
00290 int *ret_len, unsigned char *str, int str_size,
00291 int *bit_len)
00292 {
00293 int len_len, len_byte;
00294
00295 if (der_len <= 0)
00296 return ASN1_GENERIC_ERROR;
00297 len_byte = MHD__asn1_get_length_der (der, der_len, &len_len) - 1;
00298 if (len_byte < 0)
00299 return ASN1_DER_ERROR;
00300
00301 *ret_len = len_byte + len_len + 1;
00302 *bit_len = len_byte * 8 - der[len_len];
00303
00304 if (str_size >= len_byte)
00305 memcpy (str, der + len_len + 1, len_byte);
00306 else
00307 {
00308 return ASN1_MEM_ERROR;
00309 }
00310
00311 return ASN1_SUCCESS;
00312 }
00313
00314
00315
00316
00317 static int
00318 MHD__asn1_extract_tag_der (node_asn * node, const unsigned char *der,
00319 int der_len, int *ret_len)
00320 {
00321 node_asn *p;
00322 int counter, len2, len3, is_tag_implicit;
00323 unsigned long tag, tag_implicit = 0;
00324 unsigned char class, class2, class_implicit = 0;
00325
00326 if (der_len <= 0)
00327 return ASN1_GENERIC_ERROR;
00328
00329 counter = is_tag_implicit = 0;
00330
00331 if (node->type & CONST_TAG)
00332 {
00333 p = node->down;
00334 while (p)
00335 {
00336 if (type_field (p->type) == TYPE_TAG)
00337 {
00338 if (p->type & CONST_APPLICATION)
00339 class2 = ASN1_CLASS_APPLICATION;
00340 else if (p->type & CONST_UNIVERSAL)
00341 class2 = ASN1_CLASS_UNIVERSAL;
00342 else if (p->type & CONST_PRIVATE)
00343 class2 = ASN1_CLASS_PRIVATE;
00344 else
00345 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
00346
00347 if (p->type & CONST_EXPLICIT)
00348 {
00349 if (MHD__asn1_get_tag_der
00350 (der + counter, der_len - counter, &class, &len2,
00351 &tag) != ASN1_SUCCESS)
00352 return ASN1_DER_ERROR;
00353 if (counter + len2 > der_len)
00354 return ASN1_DER_ERROR;
00355 counter += len2;
00356 len3 =
00357 MHD__asn1_get_length_der (der + counter,
00358 der_len - counter, &len2);
00359 if (len3 < 0)
00360 return ASN1_DER_ERROR;
00361 counter += len2;
00362 if (!is_tag_implicit)
00363 {
00364 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
00365 (tag != strtoul ((char *) p->value, NULL, 10)))
00366 return ASN1_TAG_ERROR;
00367 }
00368 else
00369 {
00370 if ((class != class_implicit) || (tag != tag_implicit))
00371 return ASN1_TAG_ERROR;
00372 }
00373
00374 is_tag_implicit = 0;
00375 }
00376 else
00377 {
00378 if (!is_tag_implicit)
00379 {
00380 if ((type_field (node->type) == TYPE_SEQUENCE) ||
00381 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
00382 (type_field (node->type) == TYPE_SET) ||
00383 (type_field (node->type) == TYPE_SET_OF))
00384 class2 |= ASN1_CLASS_STRUCTURED;
00385 class_implicit = class2;
00386 tag_implicit = strtoul ((char *) p->value, NULL, 10);
00387 is_tag_implicit = 1;
00388 }
00389 }
00390 }
00391 p = p->right;
00392 }
00393 }
00394
00395 if (is_tag_implicit)
00396 {
00397 if (MHD__asn1_get_tag_der
00398 (der + counter, der_len - counter, &class, &len2,
00399 &tag) != ASN1_SUCCESS)
00400 return ASN1_DER_ERROR;
00401 if (counter + len2 > der_len)
00402 return ASN1_DER_ERROR;
00403
00404 if ((class != class_implicit) || (tag != tag_implicit))
00405 {
00406 if (type_field (node->type) == TYPE_OCTET_STRING)
00407 {
00408 class_implicit |= ASN1_CLASS_STRUCTURED;
00409 if ((class != class_implicit) || (tag != tag_implicit))
00410 return ASN1_TAG_ERROR;
00411 }
00412 else
00413 return ASN1_TAG_ERROR;
00414 }
00415 }
00416 else
00417 {
00418 if (type_field (node->type) == TYPE_TAG)
00419 {
00420 counter = 0;
00421 *ret_len = counter;
00422 return ASN1_SUCCESS;
00423 }
00424
00425 if (MHD__asn1_get_tag_der
00426 (der + counter, der_len - counter, &class, &len2,
00427 &tag) != ASN1_SUCCESS)
00428 return ASN1_DER_ERROR;
00429 if (counter + len2 > der_len)
00430 return ASN1_DER_ERROR;
00431
00432 switch (type_field (node->type))
00433 {
00434 case TYPE_NULL:
00435 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
00436 return ASN1_DER_ERROR;
00437 break;
00438 case TYPE_BOOLEAN:
00439 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
00440 return ASN1_DER_ERROR;
00441 break;
00442 case TYPE_INTEGER:
00443 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
00444 return ASN1_DER_ERROR;
00445 break;
00446 case TYPE_ENUMERATED:
00447 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
00448 return ASN1_DER_ERROR;
00449 break;
00450 case TYPE_OBJECT_ID:
00451 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
00452 return ASN1_DER_ERROR;
00453 break;
00454 case TYPE_TIME:
00455 if (node->type & CONST_UTC)
00456 {
00457 if ((class != ASN1_CLASS_UNIVERSAL)
00458 || (tag != ASN1_TAG_UTCTime))
00459 return ASN1_DER_ERROR;
00460 }
00461 else
00462 {
00463 if ((class != ASN1_CLASS_UNIVERSAL)
00464 || (tag != ASN1_TAG_GENERALIZEDTime))
00465 return ASN1_DER_ERROR;
00466 }
00467 break;
00468 case TYPE_OCTET_STRING:
00469 if (((class != ASN1_CLASS_UNIVERSAL)
00470 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
00471 || (tag != ASN1_TAG_OCTET_STRING))
00472 return ASN1_DER_ERROR;
00473 break;
00474 case TYPE_GENERALSTRING:
00475 if ((class != ASN1_CLASS_UNIVERSAL)
00476 || (tag != ASN1_TAG_GENERALSTRING))
00477 return ASN1_DER_ERROR;
00478 break;
00479 case TYPE_BIT_STRING:
00480 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
00481 return ASN1_DER_ERROR;
00482 break;
00483 case TYPE_SEQUENCE:
00484 case TYPE_SEQUENCE_OF:
00485 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
00486 || (tag != ASN1_TAG_SEQUENCE))
00487 return ASN1_DER_ERROR;
00488 break;
00489 case TYPE_SET:
00490 case TYPE_SET_OF:
00491 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
00492 || (tag != ASN1_TAG_SET))
00493 return ASN1_DER_ERROR;
00494 break;
00495 case TYPE_ANY:
00496 counter -= len2;
00497 break;
00498 default:
00499 return ASN1_DER_ERROR;
00500 break;
00501 }
00502 }
00503
00504 counter += len2;
00505 *ret_len = counter;
00506 return ASN1_SUCCESS;
00507 }
00508
00509
00510 static int
00511 MHD__asn1_delete_not_used (node_asn * node)
00512 {
00513 node_asn *p, *p2;
00514
00515 if (node == NULL)
00516 return ASN1_ELEMENT_NOT_FOUND;
00517
00518 p = node;
00519 while (p)
00520 {
00521 if (p->type & CONST_NOT_USED)
00522 {
00523 p2 = NULL;
00524 if (p != node)
00525 {
00526 p2 = MHD__asn1_find_left (p);
00527 if (!p2)
00528 p2 = MHD__asn1_find_up (p);
00529 }
00530 MHD__asn1_delete_structure (&p);
00531 p = p2;
00532 }
00533
00534 if (!p)
00535 break;
00536
00537 if (p->down)
00538 {
00539 p = p->down;
00540 }
00541 else
00542 {
00543 if (p == node)
00544 p = NULL;
00545 else if (p->right)
00546 p = p->right;
00547 else
00548 {
00549 while (1)
00550 {
00551 p = MHD__asn1_find_up (p);
00552 if (p == node)
00553 {
00554 p = NULL;
00555 break;
00556 }
00557 if (p->right)
00558 {
00559 p = p->right;
00560 break;
00561 }
00562 }
00563 }
00564 }
00565 }
00566 return ASN1_SUCCESS;
00567 }
00568
00569
00570 static MHD__asn1_retCode
00571 MHD__asn1_get_octet_string (const unsigned char *der, node_asn * node,
00572 int *len)
00573 {
00574 int len2, len3, counter, counter2, counter_end, tot_len, indefinite;
00575 unsigned char *temp, *temp2;
00576
00577 counter = 0;
00578
00579 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
00580 {
00581 tot_len = 0;
00582 indefinite = MHD__asn1_get_length_der (der, *len, &len3);
00583 if (indefinite < -1)
00584 return ASN1_DER_ERROR;
00585
00586 counter += len3;
00587 if (indefinite >= 0)
00588 indefinite += len3;
00589
00590 while (1)
00591 {
00592 if (counter > (*len))
00593 return ASN1_DER_ERROR;
00594
00595 if (indefinite == -1)
00596 {
00597 if ((der[counter] == 0) && (der[counter + 1] == 0))
00598 {
00599 counter += 2;
00600 break;
00601 }
00602 }
00603 else if (counter >= indefinite)
00604 break;
00605
00606 if (der[counter] != ASN1_TAG_OCTET_STRING)
00607 return ASN1_DER_ERROR;
00608
00609 counter++;
00610
00611 len2 =
00612 MHD__asn1_get_length_der (der + counter, *len - counter, &len3);
00613 if (len2 <= 0)
00614 return ASN1_DER_ERROR;
00615
00616 counter += len3 + len2;
00617 tot_len += len2;
00618 }
00619
00620
00621 if (node)
00622 {
00623 MHD__asn1_length_der (tot_len, NULL, &len2);
00624 temp = MHD__asn1_alloca (len2 + tot_len);
00625 if (temp == NULL)
00626 {
00627 return ASN1_MEM_ALLOC_ERROR;
00628 }
00629
00630 MHD__asn1_length_der (tot_len, temp, &len2);
00631 tot_len += len2;
00632 temp2 = temp + len2;
00633 len2 = MHD__asn1_get_length_der (der, *len, &len3);
00634 if (len2 < -1)
00635 {
00636 MHD__asn1_afree (temp);
00637 return ASN1_DER_ERROR;
00638 }
00639 counter2 = len3 + 1;
00640
00641 if (indefinite == -1)
00642 counter_end = counter - 2;
00643 else
00644 counter_end = counter;
00645
00646 while (counter2 < counter_end)
00647 {
00648 len2 =
00649 MHD__asn1_get_length_der (der + counter2, *len - counter,
00650 &len3);
00651 if (len2 < -1)
00652 {
00653 MHD__asn1_afree (temp);
00654 return ASN1_DER_ERROR;
00655 }
00656
00657
00658
00659
00660 memcpy (temp2, der + counter2 + len3, len2);
00661 temp2 += len2;
00662 counter2 += len2 + len3 + 1;
00663 }
00664
00665 MHD__asn1_set_value (node, temp, tot_len);
00666 MHD__asn1_afree (temp);
00667 }
00668 }
00669 else
00670 {
00671 len2 = MHD__asn1_get_length_der (der, *len, &len3);
00672 if (len2 < 0)
00673 return ASN1_DER_ERROR;
00674 if (len3 + len2 > *len)
00675 return ASN1_DER_ERROR;
00676 if (node)
00677 MHD__asn1_set_value (node, der, len3 + len2);
00678 counter = len3 + len2;
00679 }
00680
00681 *len = counter;
00682 return ASN1_SUCCESS;
00683
00684 }
00685
00686
00687 static MHD__asn1_retCode
00688 MHD__asn1_get_indefinite_length_string (const unsigned char *der, int *len)
00689 {
00690 int len2, len3, counter, indefinite;
00691 unsigned long tag;
00692 unsigned char class;
00693
00694 counter = indefinite = 0;
00695
00696 while (1)
00697 {
00698 if ((*len) < counter)
00699 return ASN1_DER_ERROR;
00700
00701 if ((der[counter] == 0) && (der[counter + 1] == 0))
00702 {
00703 counter += 2;
00704 indefinite--;
00705 if (indefinite <= 0)
00706 break;
00707 else
00708 continue;
00709 }
00710
00711 if (MHD__asn1_get_tag_der
00712 (der + counter, *len - counter, &class, &len2,
00713 &tag) != ASN1_SUCCESS)
00714 return ASN1_DER_ERROR;
00715 if (counter + len2 > *len)
00716 return ASN1_DER_ERROR;
00717 counter += len2;
00718 len2 = MHD__asn1_get_length_der (der + counter, *len - counter, &len3);
00719 if (len2 < -1)
00720 return ASN1_DER_ERROR;
00721 if (len2 == -1)
00722 {
00723 indefinite++;
00724 counter += 1;
00725 }
00726 else
00727 {
00728 counter += len2 + len3;
00729 }
00730 }
00731
00732 *len = counter;
00733 return ASN1_SUCCESS;
00734
00735 }
00736
00737
00762 MHD__asn1_retCode
00763 MHD__asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
00764 char *errorDescription)
00765 {
00766 node_asn *node, *p, *p2, *p3;
00767 char temp[128];
00768 int counter, len2, len3, len4, move, ris, tlen;
00769 unsigned char class, *temp2;
00770 unsigned long tag;
00771 int indefinite, result;
00772 const unsigned char *der = ider;
00773
00774 node = *element;
00775
00776 if (node == ASN1_TYPE_EMPTY)
00777 return ASN1_ELEMENT_NOT_FOUND;
00778
00779 if (node->type & CONST_OPTION)
00780 {
00781 MHD__asn1_delete_structure (element);
00782 return ASN1_GENERIC_ERROR;
00783 }
00784
00785 counter = 0;
00786 move = DOWN;
00787 p = node;
00788 while (1)
00789 {
00790 ris = ASN1_SUCCESS;
00791 if (move != UP)
00792 {
00793 if (p->type & CONST_SET)
00794 {
00795 p2 = MHD__asn1_find_up (p);
00796 len2 = strtol ((const char *) p2->value, NULL, 10);
00797 if (len2 == -1)
00798 {
00799 if (!der[counter] && !der[counter + 1])
00800 {
00801 p = p2;
00802 move = UP;
00803 counter += 2;
00804 continue;
00805 }
00806 }
00807 else if (counter == len2)
00808 {
00809 p = p2;
00810 move = UP;
00811 continue;
00812 }
00813 else if (counter > len2)
00814 {
00815 MHD__asn1_delete_structure (element);
00816 return ASN1_DER_ERROR;
00817 }
00818 p2 = p2->down;
00819 while (p2)
00820 {
00821 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
00822 {
00823 if (type_field (p2->type) != TYPE_CHOICE)
00824 ris =
00825 MHD__asn1_extract_tag_der (p2, der + counter,
00826 len - counter, &len2);
00827 else
00828 {
00829 p3 = p2->down;
00830 while (p3)
00831 {
00832 ris =
00833 MHD__asn1_extract_tag_der (p3, der + counter,
00834 len - counter,
00835 &len2);
00836 if (ris == ASN1_SUCCESS)
00837 break;
00838 p3 = p3->right;
00839 }
00840 }
00841 if (ris == ASN1_SUCCESS)
00842 {
00843 p2->type &= ~CONST_NOT_USED;
00844 p = p2;
00845 break;
00846 }
00847 }
00848 p2 = p2->right;
00849 }
00850 if (p2 == NULL)
00851 {
00852 MHD__asn1_delete_structure (element);
00853 return ASN1_DER_ERROR;
00854 }
00855 }
00856
00857 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
00858 {
00859 p2 = MHD__asn1_find_up (p);
00860 len2 = strtol ((const char *) p2->value, NULL, 10);
00861 if (counter == len2)
00862 {
00863 if (p->right)
00864 {
00865 p2 = p->right;
00866 move = RIGHT;
00867 }
00868 else
00869 move = UP;
00870
00871 if (p->type & CONST_OPTION)
00872 MHD__asn1_delete_structure (&p);
00873
00874 p = p2;
00875 continue;
00876 }
00877 }
00878
00879 if (type_field (p->type) == TYPE_CHOICE)
00880 {
00881 while (p->down)
00882 {
00883 if (counter < len)
00884 ris =
00885 MHD__asn1_extract_tag_der (p->down, der + counter,
00886 len - counter, &len2);
00887 else
00888 ris = ASN1_DER_ERROR;
00889 if (ris == ASN1_SUCCESS)
00890 {
00891 while (p->down->right)
00892 {
00893 p2 = p->down->right;
00894 MHD__asn1_delete_structure (&p2);
00895 }
00896 break;
00897 }
00898 else if (ris == ASN1_ERROR_TYPE_ANY)
00899 {
00900 MHD__asn1_delete_structure (element);
00901 return ASN1_ERROR_TYPE_ANY;
00902 }
00903 else
00904 {
00905 p2 = p->down;
00906 MHD__asn1_delete_structure (&p2);
00907 }
00908 }
00909
00910 if (p->down == NULL)
00911 {
00912 if (!(p->type & CONST_OPTION))
00913 {
00914 MHD__asn1_delete_structure (element);
00915 return ASN1_DER_ERROR;
00916 }
00917 }
00918 else
00919 p = p->down;
00920 }
00921
00922 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
00923 {
00924 p2 = MHD__asn1_find_up (p);
00925 len2 = strtol ((const char *) p2->value, NULL, 10);
00926 if ((len2 != -1) && (counter > len2))
00927 ris = ASN1_TAG_ERROR;
00928 }
00929
00930 if (ris == ASN1_SUCCESS)
00931 ris =
00932 MHD__asn1_extract_tag_der (p, der + counter, len - counter,
00933 &len2);
00934 if (ris != ASN1_SUCCESS)
00935 {
00936 if (p->type & CONST_OPTION)
00937 {
00938 p->type |= CONST_NOT_USED;
00939 move = RIGHT;
00940 }
00941 else if (p->type & CONST_DEFAULT)
00942 {
00943 MHD__asn1_set_value (p, NULL, 0);
00944 move = RIGHT;
00945 }
00946 else
00947 {
00948 if (errorDescription != NULL)
00949 MHD__asn1_error_description_tag_error (p,
00950 errorDescription);
00951
00952 MHD__asn1_delete_structure (element);
00953 return ASN1_TAG_ERROR;
00954 }
00955 }
00956 else
00957 counter += len2;
00958 }
00959
00960 if (ris == ASN1_SUCCESS)
00961 {
00962 switch (type_field (p->type))
00963 {
00964 case TYPE_NULL:
00965 if (der[counter])
00966 {
00967 MHD__asn1_delete_structure (element);
00968 return ASN1_DER_ERROR;
00969 }
00970 counter++;
00971 move = RIGHT;
00972 break;
00973 case TYPE_BOOLEAN:
00974 if (der[counter++] != 1)
00975 {
00976 MHD__asn1_delete_structure (element);
00977 return ASN1_DER_ERROR;
00978 }
00979 if (der[counter++] == 0)
00980 MHD__asn1_set_value (p, "F", 1);
00981 else
00982 MHD__asn1_set_value (p, "T", 1);
00983 move = RIGHT;
00984 break;
00985 case TYPE_INTEGER:
00986 case TYPE_ENUMERATED:
00987 len2 =
00988 MHD__asn1_get_length_der (der + counter, len - counter,
00989 &len3);
00990 if (len2 < 0)
00991 return ASN1_DER_ERROR;
00992 if (len2 + len3 > len - counter)
00993 return ASN1_DER_ERROR;
00994 MHD__asn1_set_value (p, der + counter, len3 + len2);
00995 counter += len3 + len2;
00996 move = RIGHT;
00997 break;
00998 case TYPE_OBJECT_ID:
00999 MHD__asn1_get_objectid_der (der + counter, len - counter, &len2,
01000 temp, sizeof (temp));
01001 tlen = strlen (temp);
01002 if (tlen > 0)
01003 MHD__asn1_set_value (p, temp, tlen + 1);
01004 counter += len2;
01005 move = RIGHT;
01006 break;
01007 case TYPE_TIME:
01008 result =
01009 MHD__asn1_get_time_der (der + counter, len - counter, &len2,
01010 temp, sizeof (temp) - 1);
01011 if (result != ASN1_SUCCESS)
01012 {
01013 MHD__asn1_delete_structure (element);
01014 return result;
01015 }
01016 tlen = strlen (temp);
01017 if (tlen > 0)
01018 MHD__asn1_set_value (p, temp, tlen + 1);
01019 counter += len2;
01020 move = RIGHT;
01021 break;
01022 case TYPE_OCTET_STRING:
01023 len3 = len - counter;
01024 ris = MHD__asn1_get_octet_string (der + counter, p, &len3);
01025 if (ris != ASN1_SUCCESS)
01026 return ris;
01027 counter += len3;
01028 move = RIGHT;
01029 break;
01030 case TYPE_GENERALSTRING:
01031 len2 =
01032 MHD__asn1_get_length_der (der + counter, len - counter,
01033 &len3);
01034 if (len2 < 0)
01035 return ASN1_DER_ERROR;
01036 if (len3 + len2 > len - counter)
01037 return ASN1_DER_ERROR;
01038 MHD__asn1_set_value (p, der + counter, len3 + len2);
01039 counter += len3 + len2;
01040 move = RIGHT;
01041 break;
01042 case TYPE_BIT_STRING:
01043 len2 =
01044 MHD__asn1_get_length_der (der + counter, len - counter,
01045 &len3);
01046 if (len2 < 0)
01047 return ASN1_DER_ERROR;
01048 if (len3 + len2 > len - counter)
01049 return ASN1_DER_ERROR;
01050 MHD__asn1_set_value (p, der + counter, len3 + len2);
01051 counter += len3 + len2;
01052 move = RIGHT;
01053 break;
01054 case TYPE_SEQUENCE:
01055 case TYPE_SET:
01056 if (move == UP)
01057 {
01058 len2 = strtol ((const char *) p->value, NULL, 10);
01059 MHD__asn1_set_value (p, NULL, 0);
01060 if (len2 == -1)
01061 {
01062 if (len - counter + 1 > 0)
01063 {
01064 if ((der[counter]) || der[counter + 1])
01065 {
01066 MHD__asn1_delete_structure (element);
01067 return ASN1_DER_ERROR;
01068 }
01069 }
01070 else
01071 return ASN1_DER_ERROR;
01072 counter += 2;
01073 }
01074 else
01075 {
01076 if (len2 != counter)
01077 {
01078 MHD__asn1_delete_structure (element);
01079 return ASN1_DER_ERROR;
01080 }
01081 }
01082 move = RIGHT;
01083 }
01084 else
01085 {
01086 len3 =
01087 MHD__asn1_get_length_der (der + counter, len - counter,
01088 &len2);
01089 if (len3 < -1)
01090 return ASN1_DER_ERROR;
01091 counter += len2;
01092 if (len3 > 0)
01093 {
01094 MHD__asn1_ltostr (counter + len3, temp);
01095 tlen = strlen (temp);
01096 if (tlen > 0)
01097 MHD__asn1_set_value (p, temp, tlen + 1);
01098 move = DOWN;
01099 }
01100 else if (len3 == 0)
01101 {
01102 p2 = p->down;
01103 while (p2)
01104 {
01105 if (type_field (p2->type) != TYPE_TAG)
01106 {
01107 p3 = p2->right;
01108 MHD__asn1_delete_structure (&p2);
01109 p2 = p3;
01110 }
01111 else
01112 p2 = p2->right;
01113 }
01114 move = RIGHT;
01115 }
01116 else
01117 {
01118 MHD__asn1_set_value (p, "-1", 3);
01119 move = DOWN;
01120 }
01121 }
01122 break;
01123 case TYPE_SEQUENCE_OF:
01124 case TYPE_SET_OF:
01125 if (move == UP)
01126 {
01127 len2 = strtol ((const char *) p->value, NULL, 10);
01128 if (len2 == -1)
01129 {
01130 if ((counter + 2) > len)
01131 return ASN1_DER_ERROR;
01132 if ((der[counter]) || der[counter + 1])
01133 {
01134 MHD__asn1_append_sequence_set (p);
01135 p = p->down;
01136 while (p->right)
01137 p = p->right;
01138 move = RIGHT;
01139 continue;
01140 }
01141 MHD__asn1_set_value (p, NULL, 0);
01142 counter += 2;
01143 }
01144 else
01145 {
01146 if (len2 > counter)
01147 {
01148 MHD__asn1_append_sequence_set (p);
01149 p = p->down;
01150 while (p->right)
01151 p = p->right;
01152 move = RIGHT;
01153 continue;
01154 }
01155 MHD__asn1_set_value (p, NULL, 0);
01156 if (len2 != counter)
01157 {
01158 MHD__asn1_delete_structure (element);
01159 return ASN1_DER_ERROR;
01160 }
01161 }
01162 }
01163 else
01164 {
01165 len3 =
01166 MHD__asn1_get_length_der (der + counter, len - counter,
01167 &len2);
01168 if (len3 < -1)
01169 return ASN1_DER_ERROR;
01170 counter += len2;
01171 if (len3)
01172 {
01173 if (len3 > 0)
01174 {
01175 MHD__asn1_ltostr (counter + len3, temp);
01176 tlen = strlen (temp);
01177
01178 if (tlen > 0)
01179 MHD__asn1_set_value (p, temp, tlen + 1);
01180 }
01181 else
01182 {
01183 MHD__asn1_set_value (p, "-1", 3);
01184 }
01185 p2 = p->down;
01186 while ((type_field (p2->type) == TYPE_TAG)
01187 || (type_field (p2->type) == TYPE_SIZE))
01188 p2 = p2->right;
01189 if (p2->right == NULL)
01190 MHD__asn1_append_sequence_set (p);
01191 p = p2;
01192 }
01193 }
01194 move = RIGHT;
01195 break;
01196 case TYPE_ANY:
01197 if (MHD__asn1_get_tag_der
01198 (der + counter, len - counter, &class, &len2,
01199 &tag) != ASN1_SUCCESS)
01200 return ASN1_DER_ERROR;
01201 if (counter + len2 > len)
01202 return ASN1_DER_ERROR;
01203 len4 =
01204 MHD__asn1_get_length_der (der + counter + len2,
01205 len - counter - len2, &len3);
01206 if (len4 < -1)
01207 return ASN1_DER_ERROR;
01208 if (len4 > len - counter + len2 + len3)
01209 return ASN1_DER_ERROR;
01210 if (len4 != -1)
01211 {
01212 len2 += len4;
01213 MHD__asn1_length_der (len2 + len3, NULL, &len4);
01214 temp2 =
01215 (unsigned char *) MHD__asn1_alloca (len2 + len3 + len4);
01216 if (temp2 == NULL)
01217 {
01218 MHD__asn1_delete_structure (element);
01219 return ASN1_MEM_ALLOC_ERROR;
01220 }
01221
01222 MHD__asn1_octet_der (der + counter, len2 + len3, temp2,
01223 &len4);
01224 MHD__asn1_set_value (p, temp2, len4);
01225 MHD__asn1_afree (temp2);
01226 counter += len2 + len3;
01227 }
01228 else
01229 {
01230
01231 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
01232 indefinite = 1;
01233 else
01234 indefinite = 0;
01235
01236 len2 = len - counter;
01237 ris =
01238 MHD__asn1_get_indefinite_length_string (der + counter,
01239 &len2);
01240 if (ris != ASN1_SUCCESS)
01241 {
01242 MHD__asn1_delete_structure (element);
01243 return ris;
01244 }
01245 MHD__asn1_length_der (len2, NULL, &len4);
01246 temp2 = (unsigned char *) MHD__asn1_alloca (len2 + len4);
01247 if (temp2 == NULL)
01248 {
01249 MHD__asn1_delete_structure (element);
01250 return ASN1_MEM_ALLOC_ERROR;
01251 }
01252
01253 MHD__asn1_octet_der (der + counter, len2, temp2, &len4);
01254 MHD__asn1_set_value (p, temp2, len4);
01255 MHD__asn1_afree (temp2);
01256 counter += len2;
01257
01258
01259
01260 if (indefinite)
01261 {
01262 if (!der[counter] && !der[counter + 1])
01263 {
01264 counter += 2;
01265 }
01266 else
01267 {
01268 MHD__asn1_delete_structure (element);
01269 return ASN1_DER_ERROR;
01270 }
01271 }
01272 }
01273 move = RIGHT;
01274 break;
01275 default:
01276 move = (move == UP) ? RIGHT : DOWN;
01277 break;
01278 }
01279 }
01280
01281 if (p == node && move != DOWN)
01282 break;
01283
01284 if (move == DOWN)
01285 {
01286 if (p->down)
01287 p = p->down;
01288 else
01289 move = RIGHT;
01290 }
01291 if ((move == RIGHT) && !(p->type & CONST_SET))
01292 {
01293 if (p->right)
01294 p = p->right;
01295 else
01296 move = UP;
01297 }
01298 if (move == UP)
01299 p = MHD__asn1_find_up (p);
01300 }
01301
01302 MHD__asn1_delete_not_used (*element);
01303
01304 if (counter != len)
01305 {
01306 MHD__asn1_delete_structure (element);
01307 return ASN1_DER_ERROR;
01308 }
01309
01310 return ASN1_SUCCESS;
01311 }
01312
01313
01344 MHD__asn1_retCode
01345 MHD__asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
01346 const char *name_element, int *start,
01347 int *end)
01348 {
01349 node_asn *node, *node_to_find, *p, *p2, *p3;
01350 int counter, len2, len3, len4, move, ris;
01351 unsigned char class;
01352 unsigned long tag;
01353 int indefinite;
01354 const unsigned char *der = ider;
01355
01356 node = element;
01357
01358 if (node == ASN1_TYPE_EMPTY)
01359 return ASN1_ELEMENT_NOT_FOUND;
01360
01361 node_to_find = MHD__asn1_find_node (node, name_element);
01362
01363 if (node_to_find == NULL)
01364 return ASN1_ELEMENT_NOT_FOUND;
01365
01366 if (node_to_find == node)
01367 {
01368 *start = 0;
01369 *end = len - 1;
01370 return ASN1_SUCCESS;
01371 }
01372
01373 if (node->type & CONST_OPTION)
01374 return ASN1_GENERIC_ERROR;
01375
01376 counter = 0;
01377 move = DOWN;
01378 p = node;
01379 while (1)
01380 {
01381 ris = ASN1_SUCCESS;
01382
01383 if (move != UP)
01384 {
01385 if (p->type & CONST_SET)
01386 {
01387 p2 = MHD__asn1_find_up (p);
01388 len2 = strtol ((const char *) p2->value, NULL, 10);
01389 if (len2 == -1)
01390 {
01391 if (!der[counter] && !der[counter + 1])
01392 {
01393 p = p2;
01394 move = UP;
01395 counter += 2;
01396 continue;
01397 }
01398 }
01399 else if (counter == len2)
01400 {
01401 p = p2;
01402 move = UP;
01403 continue;
01404 }
01405 else if (counter > len2)
01406 return ASN1_DER_ERROR;
01407 p2 = p2->down;
01408 while (p2)
01409 {
01410 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
01411 {
01412 if (type_field (p2->type) != TYPE_CHOICE)
01413 ris =
01414 MHD__asn1_extract_tag_der (p2, der + counter,
01415 len - counter, &len2);
01416 else
01417 {
01418 p3 = p2->down;
01419 ris =
01420 MHD__asn1_extract_tag_der (p3, der + counter,
01421 len - counter, &len2);
01422 }
01423 if (ris == ASN1_SUCCESS)
01424 {
01425 p2->type &= ~CONST_NOT_USED;
01426 p = p2;
01427 break;
01428 }
01429 }
01430 p2 = p2->right;
01431 }
01432 if (p2 == NULL)
01433 return ASN1_DER_ERROR;
01434 }
01435
01436 if (p == node_to_find)
01437 *start = counter;
01438
01439 if (type_field (p->type) == TYPE_CHOICE)
01440 {
01441 p = p->down;
01442 ris =
01443 MHD__asn1_extract_tag_der (p, der + counter, len - counter,
01444 &len2);
01445 if (p == node_to_find)
01446 *start = counter;
01447 }
01448
01449 if (ris == ASN1_SUCCESS)
01450 ris =
01451 MHD__asn1_extract_tag_der (p, der + counter, len - counter,
01452 &len2);
01453 if (ris != ASN1_SUCCESS)
01454 {
01455 if (p->type & CONST_OPTION)
01456 {
01457 p->type |= CONST_NOT_USED;
01458 move = RIGHT;
01459 }
01460 else if (p->type & CONST_DEFAULT)
01461 {
01462 move = RIGHT;
01463 }
01464 else
01465 {
01466 return ASN1_TAG_ERROR;
01467 }
01468 }
01469 else
01470 counter += len2;
01471 }
01472
01473 if (ris == ASN1_SUCCESS)
01474 {
01475 switch (type_field (p->type))
01476 {
01477 case TYPE_NULL:
01478 if (der[counter])
01479 return ASN1_DER_ERROR;
01480 counter++;
01481 move = RIGHT;
01482 break;
01483 case TYPE_BOOLEAN:
01484 if (der[counter++] != 1)
01485 return ASN1_DER_ERROR;
01486 counter++;
01487 move = RIGHT;
01488 break;
01489 case TYPE_INTEGER:
01490 case TYPE_ENUMERATED:
01491 len2 =
01492 MHD__asn1_get_length_der (der + counter, len - counter,
01493 &len3);
01494 if (len2 < 0)
01495 return ASN1_DER_ERROR;
01496 counter += len3 + len2;
01497 move = RIGHT;
01498 break;
01499 case TYPE_OBJECT_ID:
01500 len2 =
01501 MHD__asn1_get_length_der (der + counter, len - counter,
01502 &len3);
01503 if (len2 < 0)
01504 return ASN1_DER_ERROR;
01505 counter += len2 + len3;
01506 move = RIGHT;
01507 break;
01508 case TYPE_TIME:
01509 len2 =
01510 MHD__asn1_get_length_der (der + counter, len - counter,
01511 &len3);
01512 if (len2 < 0)
01513 return ASN1_DER_ERROR;
01514 counter += len2 + len3;
01515 move = RIGHT;
01516 break;
01517 case TYPE_OCTET_STRING:
01518 len3 = len - counter;
01519 ris = MHD__asn1_get_octet_string (der + counter, NULL, &len3);
01520 if (ris != ASN1_SUCCESS)
01521 return ris;
01522 counter += len3;
01523 move = RIGHT;
01524 break;
01525 case TYPE_GENERALSTRING:
01526 len2 =
01527 MHD__asn1_get_length_der (der + counter, len - counter,
01528 &len3);
01529 if (len2 < 0)
01530 return ASN1_DER_ERROR;
01531 counter += len3 + len2;
01532 move = RIGHT;
01533 break;
01534 case TYPE_BIT_STRING:
01535 len2 =
01536 MHD__asn1_get_length_der (der + counter, len - counter,
01537 &len3);
01538 if (len2 < 0)
01539 return ASN1_DER_ERROR;
01540 counter += len3 + len2;
01541 move = RIGHT;
01542 break;
01543 case TYPE_SEQUENCE:
01544 case TYPE_SET:
01545 if (move != UP)
01546 {
01547 len3 =
01548 MHD__asn1_get_length_der (der + counter, len - counter,
01549 &len2);
01550 if (len3 < -1)
01551 return ASN1_DER_ERROR;
01552 counter += len2;
01553 if (len3 == 0)
01554 move = RIGHT;
01555 else
01556 move = DOWN;
01557 }
01558 else
01559 {
01560 if (!der[counter] && !der[counter + 1])
01561 counter += 2;
01562 move = RIGHT;
01563 }
01564 break;
01565 case TYPE_SEQUENCE_OF:
01566 case TYPE_SET_OF:
01567 if (move != UP)
01568 {
01569 len3 =
01570 MHD__asn1_get_length_der (der + counter, len - counter,
01571 &len2);
01572 if (len3 < -1)
01573 return ASN1_DER_ERROR;
01574 counter += len2;
01575 if ((len3 == -1) && !der[counter] && !der[counter + 1])
01576 counter += 2;
01577 else if (len3)
01578 {
01579 p2 = p->down;
01580 while ((type_field (p2->type) == TYPE_TAG) ||
01581 (type_field (p2->type) == TYPE_SIZE))
01582 p2 = p2->right;
01583 p = p2;
01584 }
01585 }
01586 else
01587 {
01588 if (!der[counter] && !der[counter + 1])
01589 counter += 2;
01590 }
01591 move = RIGHT;
01592 break;
01593 case TYPE_ANY:
01594 if (MHD__asn1_get_tag_der
01595 (der + counter, len - counter, &class, &len2,
01596 &tag) != ASN1_SUCCESS)
01597 return ASN1_DER_ERROR;
01598 if (counter + len2 > len)
01599 return ASN1_DER_ERROR;
01600
01601 len4 =
01602 MHD__asn1_get_length_der (der + counter + len2,
01603 len - counter - len2, &len3);
01604 if (len4 < -1)
01605 return ASN1_DER_ERROR;
01606
01607 if (len4 != -1)
01608 {
01609 counter += len2 + len4 + len3;
01610 }
01611 else
01612 {
01613
01614 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
01615 indefinite = 1;
01616 else
01617 indefinite = 0;
01618
01619 len2 = len - counter;
01620 ris =
01621 MHD__asn1_get_indefinite_length_string (der + counter,
01622 &len2);
01623 if (ris != ASN1_SUCCESS)
01624 return ris;
01625 counter += len2;
01626
01627
01628
01629 if (indefinite)
01630 {
01631 if (!der[counter] && !der[counter + 1])
01632 counter += 2;
01633 else
01634 return ASN1_DER_ERROR;
01635 }
01636 }
01637 move = RIGHT;
01638 break;
01639 default:
01640 move = (move == UP) ? RIGHT : DOWN;
01641 break;
01642 }
01643 }
01644
01645 if ((p == node_to_find) && (move == RIGHT))
01646 {
01647 *end = counter - 1;
01648 return ASN1_SUCCESS;
01649 }
01650
01651 if (p == node && move != DOWN)
01652 break;
01653
01654 if (move == DOWN)
01655 {
01656 if (p->down)
01657 p = p->down;
01658 else
01659 move = RIGHT;
01660 }
01661 if ((move == RIGHT) && !(p->type & CONST_SET))
01662 {
01663 if (p->right)
01664 p = p->right;
01665 else
01666 move = UP;
01667 }
01668 if (move == UP)
01669 p = MHD__asn1_find_up (p);
01670 }
01671
01672 return ASN1_ELEMENT_NOT_FOUND;
01673 }