decoding.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2004, 2006 Free Software Foundation
00003  *      Copyright (C) 2002 Fabio Fiorina
00004  *
00005  * This file is part of LIBTASN1.
00006  *
00007  * The LIBTASN1 library is free software; you can redistribute it
00008  * and/or modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00020  * 02110-1301, USA
00021  */
00022 
00023 
00024 /*****************************************************/
00025 /* File: decoding.c                                  */
00026 /* Description: Functions to manage DER decoding     */
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       /* short form */
00073       *len = 1;
00074       return der[0];
00075     }
00076   else
00077     {
00078       /* Long form */
00079       k = der[0] & 0x7F;
00080       punt = 1;
00081       if (k)
00082         {                       /* definite length method */
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                 /* we wrapped around, no bignum support... */
00091                 return -2;
00092             }
00093         }
00094       else
00095         {                       /* indefinite length method */
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       /* short form */
00132       *len = 1;
00133       ris = der[0] & 0x1F;
00134     }
00135   else
00136     {
00137       /* Long form */
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             /* wrapper around, and no bignums... */
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           /* wrapper around, and no bignums... */
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   /* if(str==NULL) return ASN1_SUCCESS; */
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 /* Returns ASN1_SUCCESS on success or an error code on error.
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;                 /* no oid */
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                     {           /* ASN1_TAG_IMPLICIT */
00370                       if ((class != class_implicit) || (tag != tag_implicit))
00371                         return ASN1_TAG_ERROR;
00372                     }
00373 
00374                   is_tag_implicit = 0;
00375                 }
00376               else
00377                 {               /* ASN1_TAG_IMPLICIT */
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;                  /* reach node */
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       /* copy */
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               /* FIXME: to be checked. Is this ok? Has the
00658                * size been checked before?
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     {                           /* NOT STRUCTURED */
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                     {           /* indefinite length method */
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                     {           /* definite length method */
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                 {               /* move==DOWN || move==RIGHT */
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                     {           /* indefinite length method */
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                     {           /* indefinite length method */
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                     {           /* definite length method */
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                 {               /* move==DOWN || move==RIGHT */
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                         {       /* definite length method */
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                         {       /* indefinite length method */
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                 {               /* indefinite length */
01230                   /* Check indefinite lenth method in an EXPLICIT TAG */
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                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
01259                      an indefinite length method. */
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                     {           /* CONTROLLARE */
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])       /* indefinite length method */
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])       /* indefinite length method */
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                 {               /* indefinite length */
01613                   /* Check indefinite lenth method in an EXPLICIT TAG */
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                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
01628                      an indefinite length method. */
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 }
Generated by  doxygen 1.6.2-20100208