Sourcecode and documentation for libtasn1-2 version 0.2.10-3sarge1
show bar | Show file versions
Search packages:
| Sourcecode archive home

decoding.c

00001 /*
00002  *      Copyright (C) 2002 Fabio Fiorina
00003  *
00004  * This file is part of LIBASN1.
00005  *
00006  * The LIBTASN1 library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public   
00008  * License as published by the Free Software Foundation; either 
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00019  */
00020  
00021 
00022 /*****************************************************/
00023 /* File: decoding.c                                  */
00024 /* Description: Functions to manage DER decoding     */
00025 /*****************************************************/
00026  
00027 #include <int.h>
00028 #include <errors.h>
00029 #include "der.h"
00030 #include "parser_aux.h"
00031 #include <gstr.h>
00032 #include "structure.h"
00033 #include "element.h"
00034 
00035 
00036 void
00037 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
00038 {
00039 
00040   Estrcpy(ErrorDescription,":: tag error near element '");
00041   _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
00042                     MAX_ERROR_DESCRIPTION_SIZE-40);
00043   Estrcat(ErrorDescription,"'");
00044 
00045 }
00046 
00047   
00048 signed long
00049 _asn1_get_length_der(const unsigned char *der, int der_len, int  *len)
00050 {
00051   unsigned long ans;
00052   int k,punt;
00053 
00054   *len = 0;
00055   if (der_len <= 0) return 0;
00056 
00057   if(!(der[0]&128)){
00058     /* short form */
00059     *len=1;
00060     return der[0];
00061   }
00062   else{
00063     /* Long form */
00064     k=der[0]&0x7F;
00065     punt=1;
00066     if(k){  /* definite length method */
00067       ans=0;
00068       while(punt<=k && punt < der_len) {
00069       unsigned long last = ans;
00070          ans=ans*256+der[punt++];
00071        if (ans < last)
00072          /* we wrapped around, no bignum support... */
00073          return -2;
00074       }
00075     }
00076     else{  /* indefinite lenght method */
00077       ans=-1;
00078     }
00079 
00080     *len=punt;
00081     return ans;
00082   }
00083 }
00084 
00085 
00086 
00087 
00088 int
00089 _asn1_get_tag_der(const unsigned char *der, int der_len,
00090                  unsigned char *class,int  *len, unsigned long *tag)
00091 {
00092   int punt,ris;
00093 
00094   if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR;
00095 
00096   *class=der[0]&0xE0;
00097   if((der[0]&0x1F)!=0x1F){
00098     /* short form */
00099     *len=1;
00100     ris=der[0]&0x1F;
00101   }
00102   else{
00103     /* Long form */
00104     punt=1;
00105     ris=0;
00106     while(punt <= der_len && der[punt]&128)
00107       {
00108       int last = ris;
00109       ris=ris*128+(der[punt++]&0x7F);
00110       if (ris < last)
00111         /* wrapper around, and no bignums... */
00112         return ASN1_DER_ERROR;
00113       }
00114     if (punt >= der_len)
00115       return ASN1_DER_ERROR;
00116     {
00117       int last = ris;
00118       ris=ris*128+(der[punt++]&0x7F);
00119       if (ris < last)
00120       /* wrapper around, and no bignums... */
00121       return ASN1_DER_ERROR;
00122     }
00123     *len=punt;
00124   }
00125   if (tag) *tag = ris;
00126   return ASN1_SUCCESS;
00127 }
00128 
00129 
00130 
00131 
00132 int
00133 _asn1_get_octet_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size, int *str_len)
00134 {
00135   int len_len;
00136 
00137   if (der_len <= 0) return ASN1_GENERIC_ERROR;
00138 
00139   /* if(str==NULL) return ASN1_SUCCESS; */
00140   *str_len=_asn1_get_length_der(der, der_len, &len_len);
00141   
00142   if (*str_len < 0)
00143      return ASN1_DER_ERROR;
00144 
00145   *ret_len=*str_len+len_len;
00146   if ( str_size >= *str_len)
00147         memcpy(str,der+len_len,*str_len);
00148   else {
00149       return ASN1_MEM_ERROR;
00150   }
00151   
00152   return ASN1_SUCCESS;
00153 }
00154 
00155 
00156 
00157 /* Returns ASN1_SUCCESS on success or an error code on error.
00158  */
00159 int
00160 _asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size)
00161 {
00162   int len_len,str_len;
00163 
00164   if(der_len <=0 || str==NULL) return ASN1_DER_ERROR;
00165   str_len=_asn1_get_length_der(der, der_len, &len_len);
00166   if (str_len < 0 || str_size < str_len) 
00167      return ASN1_DER_ERROR;
00168   memcpy(str,der+len_len,str_len);
00169   str[str_len]=0;
00170   *ret_len=str_len+len_len;
00171   
00172   return ASN1_SUCCESS;
00173 }
00174 
00175 
00176 
00177 void
00178 _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size)
00179 {
00180   int len_len,len,k;
00181   char temp[20];
00182   unsigned long val,val1;
00183 
00184   *ret_len = 0;
00185   if (str && str_size > 0) str[0] = 0; /* no oid */
00186 
00187   if(str==NULL || der_len <= 0) return;
00188   len=_asn1_get_length_der(der,der_len, &len_len);
00189   
00190   if (len < 0 || len > der_len || len_len > der_len) return;
00191   
00192   val1=der[len_len]/40;
00193   val=der[len_len]-val1*40;
00194 
00195   _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
00196   _asn1_str_cat(str, str_size, ".");
00197   _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
00198 
00199   val=0;
00200   for(k=1;k<len;k++){
00201     val=val<<7;
00202     val|=der[len_len+k]&0x7F;
00203     if(!(der[len_len+k]&0x80)){
00204       _asn1_str_cat(str, str_size,".");
00205       _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
00206       val=0;
00207     }
00208   }
00209   *ret_len=len+len_len;
00210 }
00211 
00212 
00213 
00214 
00215 int
00216 _asn1_get_bit_der(const unsigned char *der, int der_len,
00217   int *ret_len,unsigned char *str, int str_size, int *bit_len)
00218 {
00219   int len_len,len_byte;
00220 
00221   if (der_len <=0) return ASN1_GENERIC_ERROR;
00222   len_byte=_asn1_get_length_der(der,der_len,&len_len)-1;
00223   if (len_byte < 0)
00224     return ASN1_DER_ERROR;
00225 
00226   *ret_len=len_byte+len_len+1;  
00227   *bit_len=len_byte*8-der[len_len];
00228 
00229   if (str_size >= len_byte)
00230       memcpy(str,der+len_len+1,len_byte);
00231   else {
00232       return ASN1_MEM_ERROR;
00233   }
00234  
00235   return ASN1_SUCCESS;
00236 }
00237 
00238 
00239 
00240 
00241 int
00242 _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len)
00243 {
00244   node_asn *p;
00245   int counter,len2,len3,is_tag_implicit;
00246   unsigned long tag,tag_implicit=0;
00247   unsigned char class,class2,class_implicit=0;
00248 
00249   if (der_len <= 0) return ASN1_GENERIC_ERROR;
00250   
00251   counter=is_tag_implicit=0;
00252 
00253   if(node->type&CONST_TAG){
00254     p=node->down;
00255     while(p){
00256       if(type_field(p->type)==TYPE_TAG){
00257       if(p->type&CONST_APPLICATION) class2=APPLICATION;
00258       else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
00259       else if(p->type&CONST_PRIVATE) class2=PRIVATE;
00260       else class2=CONTEXT_SPECIFIC;
00261       
00262       if(p->type&CONST_EXPLICIT){
00263         if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
00264            return ASN1_DER_ERROR;
00265         if (counter+len2 > der_len)
00266           return ASN1_DER_ERROR;
00267         counter+=len2;
00268         len3=_asn1_get_length_der(der+counter,der_len-counter, &len2);
00269         if (len3 < 0)
00270           return ASN1_DER_ERROR;
00271         counter+=len2;
00272         if(!is_tag_implicit){
00273           if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
00274             return ASN1_TAG_ERROR;
00275         }
00276         else{    /* TAG_IMPLICIT */
00277           if((class!=class_implicit) || (tag!=tag_implicit))
00278             return ASN1_TAG_ERROR;
00279         }
00280 
00281         is_tag_implicit=0;
00282       }
00283       else{    /* TAG_IMPLICIT */
00284         if(!is_tag_implicit){
00285           if((type_field(node->type)==TYPE_SEQUENCE) ||
00286              (type_field(node->type)==TYPE_SEQUENCE_OF) ||
00287              (type_field(node->type)==TYPE_SET) ||
00288              (type_field(node->type)==TYPE_SET_OF))  class2|=STRUCTURED;
00289           class_implicit=class2;
00290           tag_implicit=strtoul(p->value,NULL,10);
00291           is_tag_implicit=1;
00292         }
00293       }
00294       }
00295       p=p->right;
00296     }
00297   }
00298 
00299   if(is_tag_implicit){
00300     if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
00301            return ASN1_DER_ERROR;
00302     if (counter+len2 > der_len)
00303       return ASN1_DER_ERROR;
00304 
00305     if((class!=class_implicit) || (tag!=tag_implicit)){
00306       if(type_field(node->type)==TYPE_OCTET_STRING){
00307       class_implicit |= STRUCTURED;
00308       if((class!=class_implicit) || (tag!=tag_implicit))
00309         return ASN1_TAG_ERROR;
00310       }
00311       else
00312       return ASN1_TAG_ERROR;
00313     }
00314   }
00315   else{
00316     if(type_field(node->type)==TYPE_TAG){
00317       counter=0;
00318       *ret_len=counter;
00319       return ASN1_SUCCESS;
00320     }
00321 
00322     if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
00323      return ASN1_DER_ERROR;
00324     if (counter+len2 > der_len)
00325       return ASN1_DER_ERROR;
00326 
00327     switch(type_field(node->type)){
00328     case TYPE_NULL:
00329       if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
00330        break;
00331     case TYPE_BOOLEAN:
00332       if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
00333        break;
00334     case TYPE_INTEGER:
00335       if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
00336        break;
00337     case TYPE_ENUMERATED:
00338       if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
00339        break;
00340     case TYPE_OBJECT_ID:
00341       if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
00342        break;
00343     case TYPE_TIME:
00344       if(node->type&CONST_UTC){
00345         if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
00346       }
00347       else{
00348       if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime)) 
00349         return ASN1_DER_ERROR;
00350       }
00351       break;
00352     case TYPE_OCTET_STRING:
00353       if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
00354        || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
00355       break;
00356     case TYPE_GENERALSTRING:
00357       if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
00358       break;
00359     case TYPE_BIT_STRING:
00360       if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
00361       break;
00362     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
00363       if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE)) 
00364       return ASN1_DER_ERROR;
00365       break;
00366     case TYPE_SET: case TYPE_SET_OF:
00367       if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET)) 
00368       return ASN1_DER_ERROR;
00369       break;
00370     case TYPE_ANY:
00371       counter-=len2;
00372       break;
00373     default:
00374       return ASN1_DER_ERROR;
00375       break;
00376     }
00377   }
00378 
00379   counter+=len2;
00380   *ret_len=counter;
00381   return ASN1_SUCCESS;
00382 }
00383 
00384 
00385 int 
00386 _asn1_delete_not_used(node_asn *node)
00387 {
00388   node_asn *p,*p2;
00389 
00390   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00391 
00392   p=node;
00393   while(p){
00394     if(p->type&CONST_NOT_USED){
00395       p2=NULL;
00396       if(p!=node){
00397       p2=_asn1_find_left(p);
00398       if(!p2) p2=_asn1_find_up(p);
00399       }
00400       asn1_delete_structure(&p);
00401       p=p2;
00402     } 
00403 
00404     if(!p) break;  /* reach node */
00405 
00406     if(p->down){
00407       p=p->down;
00408     }
00409     else{
00410       if(p==node) p=NULL;
00411       else if(p->right) p=p->right;
00412       else{
00413       while(1){
00414         p=_asn1_find_up(p);
00415         if(p==node){
00416           p=NULL;
00417           break;
00418         }
00419         if(p->right){
00420           p=p->right;
00421           break;
00422         }
00423       }
00424       }
00425     }
00426   }
00427   return ASN1_SUCCESS;
00428 }
00429 
00430 
00431 asn1_retCode
00432 _asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len)
00433 {
00434   int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
00435   char *temp,*temp2;
00436 
00437   counter=0;
00438 
00439   if(*(der-1) & STRUCTURED){
00440     tot_len=0;
00441     indefinite=_asn1_get_length_der(der, *len, &len3);
00442     if (indefinite < -1)
00443       return ASN1_DER_ERROR;
00444 
00445     counter+=len3;
00446     if(indefinite>=0) indefinite+=len3;
00447  
00448     while(1){
00449       if(counter>(*len)) return ASN1_DER_ERROR;
00450 
00451       if(indefinite==-1){
00452       if((der[counter]==0) && (der[counter+1]==0)){
00453         counter+=2;
00454         break;
00455       }
00456       }
00457       else if(counter>=indefinite) break;
00458 
00459       if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
00460       
00461       counter++;
00462 
00463       len2=_asn1_get_length_der(der+counter,*len-counter, &len3);
00464       if(len2 <= 0) return ASN1_DER_ERROR;
00465 
00466       counter+=len3+len2;
00467       tot_len+=len2;
00468     }
00469 
00470     /* copy */
00471     if(node){
00472       _asn1_length_der(tot_len,NULL,&len2);
00473       temp=(unsigned char *)_asn1_alloca(len2+tot_len);
00474       if (temp==NULL){
00475       return ASN1_MEM_ALLOC_ERROR;
00476       }
00477       
00478       _asn1_length_der(tot_len,temp,&len2);
00479       tot_len+=len2;
00480       temp2=temp+len2;
00481       len2=_asn1_get_length_der(der,*len,&len3);
00482       if(len2 < -1) return ASN1_DER_ERROR;
00483       counter2=len3+1;
00484 
00485       if(indefinite==-1) counter_end=counter-2;
00486       else counter_end=counter;
00487       
00488       while(counter2<counter_end){
00489       len2=_asn1_get_length_der(der+counter2, *len-counter, &len3);
00490       if(len2 < -1) return ASN1_DER_ERROR;
00491 
00492       /* FIXME: to be checked. Is this ok? Has the
00493        * size been checked before?
00494        */
00495       memcpy(temp2,der+counter2+len3,len2);
00496       temp2+=len2;
00497       counter2+=len2+len3+1;
00498       }
00499       
00500       _asn1_set_value(node,temp,tot_len);
00501       _asn1_afree(temp);
00502     }
00503   }
00504   else{  /* NOT STRUCTURED */
00505     len2=_asn1_get_length_der(der, *len, &len3);
00506     if(len2 < 0) return ASN1_DER_ERROR;
00507     if (len3+len2 > *len) return ASN1_DER_ERROR;
00508     if(node)
00509       _asn1_set_value(node,der,len3+len2);
00510     counter=len3+len2;
00511   }   
00512 
00513   *len=counter;
00514   return ASN1_SUCCESS;
00515 
00516 }
00517 
00518 
00519 asn1_retCode
00520 _asn1_get_indefinite_length_string(const unsigned char* der, int* len)
00521 {
00522   int len2,len3,counter,indefinite;
00523   unsigned long tag;
00524   unsigned char class;
00525 
00526   counter=indefinite=0;
00527 
00528   while(1){
00529     if((*len)<counter) return ASN1_DER_ERROR;
00530 
00531     if((der[counter]==0) && (der[counter+1]==0)){
00532       counter+=2;
00533       indefinite--;
00534       if(indefinite<=0) break;
00535       else continue;
00536     }
00537 
00538     if(_asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
00539      return ASN1_DER_ERROR;
00540     if (counter+len2 > *len)
00541       return ASN1_DER_ERROR;
00542     counter+=len2;
00543     len2=_asn1_get_length_der(der+counter, *len-counter,&len3);
00544     if(len2 < -1) return ASN1_DER_ERROR;
00545     if(len2 == -1){
00546       indefinite++;
00547       counter+=1;
00548     }
00549     else{
00550       counter+=len2+len3;
00551     }
00552   }
00553 
00554   *len=counter;
00555   return ASN1_SUCCESS;
00556 
00557 }
00558 
00559 
00560 /**
00561   * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
00562   * @element: pointer to an ASN1 structure
00563   * @ider: vector that contains the DER encoding. 
00564   * @len: number of bytes of *der: der[0]..der[len-1]
00565   * Description:
00566   *
00567   * Fill the structure *ELEMENT with values of a DER encoding string. The sructure must just be
00568   * created with function 'create_stucture'.
00569   * If an error accurs during de decoding procedure, the *ELEMENT is deleted
00570   * and set equal to ASN1_TYPE_EMPTY.
00571   *
00572   * Returns:
00573   *
00574   *   ASN1_SUCCESS\: DER encoding OK
00575   *
00576   *   ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY.
00577   *
00578   *   ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure NAME. *ELEMENT deleted. 
00579   **/
00580 
00581 asn1_retCode
00582 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
00583               char *errorDescription)
00584 {
00585   node_asn *node,*p,*p2,*p3;
00586   char temp[128];
00587   int counter,len2,len3,len4,move,ris;
00588   unsigned char class,*temp2;
00589   unsigned long tag;
00590   int indefinite, result;
00591   const unsigned char* der = ider;
00592 
00593   node=*element;
00594 
00595   if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
00596 
00597   if(node->type&CONST_OPTION){
00598     asn1_delete_structure(element);
00599     return ASN1_GENERIC_ERROR;
00600   }
00601 
00602   counter=0;
00603   move=DOWN;
00604   p=node;
00605   while(1){
00606     ris=ASN1_SUCCESS;
00607     if(move!=UP){
00608       if(p->type&CONST_SET){
00609       p2=_asn1_find_up(p);
00610       len2=strtol(p2->value,NULL,10);
00611       if(len2==-1){
00612         if(!der[counter] && !der[counter+1]){
00613           p=p2;
00614           move=UP;
00615           counter+=2;
00616           continue;
00617         }
00618       }
00619       else if(counter==len2){
00620         p=p2;
00621         move=UP;
00622         continue;
00623       }
00624       else if(counter>len2){
00625         asn1_delete_structure(element);
00626         return ASN1_DER_ERROR;
00627       }
00628       p2=p2->down;
00629       while(p2){
00630         if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
00631           if(type_field(p2->type)!=TYPE_CHOICE)
00632             ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2);
00633           else{
00634             p3=p2->down;
00635             while(p3){
00636             ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2);
00637             if(ris==ASN1_SUCCESS) break;
00638             p3=p3->right;
00639             }
00640           }
00641           if(ris==ASN1_SUCCESS){
00642             p2->type&=~CONST_NOT_USED;
00643             p=p2;
00644             break;
00645           }
00646         }
00647         p2=p2->right;
00648       }
00649       if(p2==NULL){
00650         asn1_delete_structure(element);
00651         return ASN1_DER_ERROR;
00652       }
00653       }
00654 
00655       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
00656       p2=_asn1_find_up(p);
00657       len2=strtol(p2->value,NULL,10);
00658       if(counter==len2){
00659         if(p->right){
00660           p2=p->right;
00661           move=RIGHT;
00662         }
00663         else move=UP;
00664 
00665         if(p->type&CONST_OPTION) asn1_delete_structure(&p);
00666 
00667         p=p2;
00668         continue;
00669       }
00670       }
00671 
00672       if(type_field(p->type)==TYPE_CHOICE){
00673       while(p->down){
00674         if(counter<len)
00675           ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
00676         else
00677           ris=ASN1_DER_ERROR;
00678         if(ris==ASN1_SUCCESS){
00679           while(p->down->right){
00680             p2=p->down->right;
00681             asn1_delete_structure(&p2);
00682           }
00683           break;
00684         }
00685         else if(ris==ASN1_ERROR_TYPE_ANY){
00686           asn1_delete_structure(element);
00687           return ASN1_ERROR_TYPE_ANY;
00688         }
00689         else{
00690           p2=p->down;
00691           asn1_delete_structure(&p2);
00692         }
00693       }
00694 
00695         if(p->down==NULL){
00696         if(!(p->type&CONST_OPTION)){
00697           asn1_delete_structure(element);
00698           return ASN1_DER_ERROR;
00699         }
00700       }
00701       else
00702         p=p->down;
00703       }
00704 
00705       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
00706       p2=_asn1_find_up(p);
00707       len2=strtol(p2->value,NULL,10);
00708       if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
00709       }
00710      
00711       if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
00712       if(ris!=ASN1_SUCCESS){
00713       if(p->type&CONST_OPTION){
00714         p->type|=CONST_NOT_USED;
00715         move=RIGHT;
00716       }
00717       else if(p->type&CONST_DEFAULT) {
00718         _asn1_set_value(p,NULL,0);
00719         move=RIGHT;
00720       }
00721       else {
00722         if (errorDescription!=NULL)
00723           _asn1_error_description_tag_error(p,errorDescription);
00724         
00725         asn1_delete_structure(element);
00726         return ASN1_TAG_ERROR;
00727       }
00728       } 
00729       else counter+=len2;
00730     }
00731 
00732     if(ris==ASN1_SUCCESS){
00733       switch(type_field(p->type)){
00734       case TYPE_NULL:
00735       if(der[counter]){
00736         asn1_delete_structure(element);
00737         return ASN1_DER_ERROR;
00738       }
00739       counter++;
00740       move=RIGHT;
00741       break;
00742       case TYPE_BOOLEAN:
00743       if(der[counter++]!=1){
00744         asn1_delete_structure(element);
00745         return ASN1_DER_ERROR;
00746       }
00747       if(der[counter++]==0) _asn1_set_value(p,"F",1);
00748       else _asn1_set_value(p,"T",1);
00749       move=RIGHT;
00750       break;
00751       case TYPE_INTEGER: case TYPE_ENUMERATED:
00752       len2=_asn1_get_length_der(der+counter,len-counter, &len3);
00753       if(len2 < 0) return ASN1_DER_ERROR;
00754       if (len2+len3 > len-counter) return ASN1_DER_ERROR;
00755       _asn1_set_value(p,der+counter,len3+len2);
00756       counter+=len3+len2;
00757       move=RIGHT;
00758       break;
00759       case TYPE_OBJECT_ID:
00760       _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
00761       _asn1_set_value(p,temp,strlen(temp)+1);
00762       counter+=len2;
00763       move=RIGHT;
00764       break;
00765       case TYPE_TIME:
00766       result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
00767       if (result != ASN1_SUCCESS) {
00768             asn1_delete_structure(element);
00769               return result;
00770       }
00771       _asn1_set_value(p,temp,strlen(temp)+1);
00772       counter+=len2;
00773       move=RIGHT;
00774       break;
00775       case TYPE_OCTET_STRING:
00776       len3=len-counter;
00777       ris=_asn1_get_octet_string(der+counter,p,&len3);
00778       if(ris != ASN1_SUCCESS) return ris; 
00779       counter+=len3;
00780       move=RIGHT;
00781       break;
00782       case TYPE_GENERALSTRING:
00783       len2=_asn1_get_length_der(der+counter,len-counter,&len3);
00784       if(len2 < 0) return ASN1_DER_ERROR;
00785       if (len3+len2 > len-counter) return ASN1_DER_ERROR;
00786          _asn1_set_value(p,der+counter,len3+len2);
00787       counter+=len3+len2;
00788       move=RIGHT;
00789       break;
00790       case TYPE_BIT_STRING:
00791       len2=_asn1_get_length_der(der+counter,len-counter,&len3);
00792       if(len2 < 0) return ASN1_DER_ERROR;
00793       if (len3+len2 > len-counter) return ASN1_DER_ERROR;
00794          _asn1_set_value(p,der+counter,len3+len2);
00795       counter+=len3+len2;
00796       move=RIGHT;
00797       break;
00798       case TYPE_SEQUENCE:  case TYPE_SET:;
00799       if(move==UP){
00800         len2=strtol(p->value,NULL,10);
00801         _asn1_set_value(p,NULL,0);
00802         if(len2==-1){ /* indefinite length method */
00803           if (len-counter+1 > 0) {
00804             if((der[counter]) || der[counter+1]){
00805               asn1_delete_structure(element);
00806               return ASN1_DER_ERROR;
00807             }
00808             } else return ASN1_DER_ERROR;
00809           counter+=2;
00810         }
00811         else{ /* definite length method */
00812           if(len2!=counter){
00813             asn1_delete_structure(element);
00814             return ASN1_DER_ERROR;
00815           }
00816         }
00817         move=RIGHT;
00818       }
00819       else{   /* move==DOWN || move==RIGHT */
00820         len3=_asn1_get_length_der(der+counter,len-counter,&len2);
00821         if(len3 < -1) return ASN1_DER_ERROR;
00822         counter+=len2;
00823         if(len3>0){
00824           _asn1_ltostr(counter+len3,temp);
00825           _asn1_set_value(p,temp,strlen(temp)+1);
00826           move=DOWN; 
00827         }
00828         else if(len3==0){
00829           p2=p->down;
00830           while(p2){
00831             if(type_field(p2->type)!=TYPE_TAG){
00832             p3=p2->right;
00833             asn1_delete_structure(&p2);
00834             p2=p3;
00835             }
00836             else
00837             p2=p2->right;
00838           }
00839           move=RIGHT;
00840         }
00841         else{ /* indefinite length method */
00842           _asn1_set_value(p,"-1",3);
00843           move=DOWN; 
00844         }
00845       }
00846       break;
00847       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
00848       if(move==UP){
00849         len2=strtol(p->value,NULL,10);
00850         if(len2==-1){ /* indefinite length method */
00851           if((counter+2)>len) return ASN1_DER_ERROR;
00852           if((der[counter]) || der[counter+1]){
00853             _asn1_append_sequence_set(p);
00854             p=p->down;
00855             while(p->right) p=p->right;
00856             move=RIGHT;
00857             continue;
00858           }
00859           _asn1_set_value(p,NULL,0);
00860           counter+=2;
00861         }
00862         else{ /* definite length method */
00863           if(len2>counter){
00864             _asn1_append_sequence_set(p);
00865             p=p->down;
00866             while(p->right) p=p->right;
00867             move=RIGHT;
00868             continue;
00869           }
00870           _asn1_set_value(p,NULL,0);
00871           if(len2!=counter){
00872             asn1_delete_structure(element);
00873             return ASN1_DER_ERROR;
00874           }
00875         }
00876       }
00877       else{   /* move==DOWN || move==RIGHT */
00878         len3=_asn1_get_length_der(der+counter,len-counter,&len2);
00879         if(len3 < -1) return ASN1_DER_ERROR;
00880         counter+=len2;
00881         if(len3){
00882           if(len3>0){ /* definite length method */
00883           _asn1_ltostr(counter+len3,temp);
00884           _asn1_set_value(p,temp,strlen(temp)+1);
00885           }
00886           else { /* indefinite length method */
00887             _asn1_set_value(p,"-1",3);          
00888           }
00889           p2=p->down;
00890           while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
00891           if(p2->right==NULL) _asn1_append_sequence_set(p);
00892           p=p2;
00893         }
00894       }
00895       move=RIGHT;
00896       break;
00897       case TYPE_ANY:
00898       /* Check indefinite lenth method in a EXPLICIT TAG */
00899       if((p->type&CONST_TAG) && (der[counter-1]==0x80))
00900         indefinite=1;
00901       else
00902         indefinite=0;
00903 
00904       if(_asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
00905       return ASN1_DER_ERROR;
00906       if (counter+len2 > len)
00907         return ASN1_DER_ERROR;
00908       len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
00909       if(len4 < -1) return ASN1_DER_ERROR;
00910       if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR;
00911 
00912       if(len4 != -1){
00913         len2+=len4;
00914         _asn1_length_der(len2+len3,NULL,&len4);
00915         temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
00916         if (temp2==NULL){
00917           asn1_delete_structure(element);
00918           return ASN1_MEM_ALLOC_ERROR;
00919         }
00920         
00921         _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
00922         _asn1_set_value(p,temp2,len4);
00923         _asn1_afree(temp2);
00924         counter+=len2+len3;
00925       }
00926       else{ /* indefinite length */
00927         len2=len-counter;
00928         ris=_asn1_get_indefinite_length_string(der+counter,&len2);
00929         if(ris != ASN1_SUCCESS){
00930           asn1_delete_structure(element);
00931           return ris;
00932         }
00933         _asn1_length_der(len2,NULL,&len4);
00934         temp2=(unsigned char *)_asn1_alloca(len2+len4);
00935         if (temp2==NULL){
00936           asn1_delete_structure(element);
00937           return ASN1_MEM_ALLOC_ERROR;
00938         }
00939         
00940         _asn1_octet_der(der+counter,len2,temp2,&len4);
00941         _asn1_set_value(p,temp2,len4);
00942         _asn1_afree(temp2);
00943         counter+=len2;
00944       }
00945 
00946       /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
00947          a indefinite length method. */
00948       if(indefinite){
00949         if(!der[counter] && !der[counter+1]){ 
00950           counter+=2;
00951         }
00952         else{
00953           asn1_delete_structure(element);
00954           return ASN1_DER_ERROR;
00955         }
00956       }
00957       move=RIGHT;
00958       break;
00959       default:
00960       move=(move==UP)?RIGHT:DOWN;
00961       break;
00962       }
00963     }
00964 
00965     if(p==node && move!=DOWN) break;
00966 
00967     if(move==DOWN){
00968       if(p->down) p=p->down;
00969       else move=RIGHT;
00970     }
00971     if((move==RIGHT) && !(p->type&CONST_SET)){
00972       if(p->right) p=p->right;
00973       else move=UP;
00974     }
00975     if(move==UP) p=_asn1_find_up(p);
00976   }
00977 
00978   _asn1_delete_not_used(*element);
00979 
00980   if(counter != len){
00981     asn1_delete_structure(element);
00982     return ASN1_DER_ERROR;
00983   }
00984 
00985   return ASN1_SUCCESS;
00986 }
00987 
00988 
00989 #define FOUND        1
00990 #define SAME_BRANCH  2
00991 #define OTHER_BRANCH 3
00992 #define EXIT         4
00993 
00994 /**
00995   * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
00996   * @structure: pointer to an ASN1 structure
00997   * @elementName: name of the element to fill
00998   * @ider: vector that contains the DER encoding of the whole structure. 
00999   * @len: number of bytes of *der: der[0]..der[len-1]
01000   * @errorDescription: null-terminated string contains details when an arror accured.
01001   * 
01002   * Description:
01003   *
01004   * Fill the element named ELEMENTNAME with values of a DER encoding string. 
01005   * The sructure must just be created with function 'create_stucture'.
01006   * The DER vector must contain the encoding string of the whole STRUCTURE.
01007   * If an error accurs during the decoding procedure, the *STRUCTURE is deleted
01008   * and set equal to ASN1_TYPE_EMPTY.
01009   *
01010   * Returns:
01011   *
01012   *   ASN1_SUCCESS\: DER encoding OK
01013   *
01014   *   ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY or elementName == NULL.
01015   *
01016   *   ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure STRUCTURE. *ELEMENT deleted. 
01017   *
01018   **/
01019 asn1_retCode
01020 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
01021                     const void *ider,int len,char *errorDescription)
01022 {
01023   node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
01024   char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
01025   int nameLen=MAX_NAME_SIZE*10-1,state;
01026   int counter,len2,len3,len4,move,ris;
01027   unsigned char class,*temp2;
01028   unsigned long tag;
01029   int indefinite, result;
01030   const unsigned char* der = ider;
01031 
01032   node=*structure;
01033 
01034   if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
01035 
01036   if(elementName == NULL){
01037     asn1_delete_structure(structure);    
01038     return ASN1_ELEMENT_NOT_FOUND;
01039   }
01040 
01041   if(node->type&CONST_OPTION){
01042     asn1_delete_structure(structure);
01043     return ASN1_GENERIC_ERROR;
01044   }
01045 
01046   if((*structure)->name){  /* Has *structure a name? */
01047     nameLen-=strlen((*structure)->name);
01048     if(nameLen>0) strcpy(currentName,(*structure)->name);
01049     else{
01050       asn1_delete_structure(structure);
01051       return ASN1_MEM_ERROR;
01052     }
01053     if(!(strcmp(currentName,elementName))){ 
01054       state=FOUND;
01055       nodeFound=*structure;
01056     }
01057     else if(!memcmp(currentName,elementName,strlen(currentName))) 
01058       state=SAME_BRANCH;
01059     else 
01060       state=OTHER_BRANCH;
01061   }
01062   else{  /* *structure doesn't have a name? */
01063     currentName[0]=0;
01064     if(elementName[0]==0){
01065       state=FOUND;
01066       nodeFound=*structure;
01067     }
01068     else{
01069       state=SAME_BRANCH;
01070     }
01071   }
01072 
01073   counter=0;
01074   move=DOWN;
01075   p=node;
01076   while(1){
01077 
01078     ris=ASN1_SUCCESS;
01079 
01080     if(move!=UP){
01081       if(p->type&CONST_SET){
01082       p2=_asn1_find_up(p);
01083       len2=strtol(p2->value,NULL,10);
01084       if(counter==len2){
01085         p=p2;
01086         move=UP;
01087         continue;
01088       }
01089       else if(counter>len2){
01090         asn1_delete_structure(structure);
01091         return ASN1_DER_ERROR;
01092       }
01093       p2=p2->down;
01094       while(p2){
01095         if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
01096           if(type_field(p2->type)!=TYPE_CHOICE)
01097             ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
01098           else{
01099             p3=p2->down;
01100             while(p3){
01101             ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
01102             if(ris==ASN1_SUCCESS) break;
01103             p3=p3->right;
01104             }
01105           }
01106           if(ris==ASN1_SUCCESS){
01107             p2->type&=~CONST_NOT_USED;
01108             p=p2;
01109             break;
01110           }
01111         }
01112         p2=p2->right;
01113       }
01114       if(p2==NULL){
01115         asn1_delete_structure(structure);
01116         return ASN1_DER_ERROR;
01117       }
01118       }
01119 
01120       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
01121       p2=_asn1_find_up(p);
01122       len2=strtol(p2->value,NULL,10);
01123       if(counter==len2){
01124         if(p->right){
01125           p2=p->right;
01126           move=RIGHT;
01127         }
01128         else move=UP;
01129 
01130         if(p->type&CONST_OPTION) asn1_delete_structure(&p);
01131 
01132         p=p2;
01133         continue;
01134       }
01135       }
01136 
01137       if(type_field(p->type)==TYPE_CHOICE){
01138       while(p->down){
01139         if(counter<len)
01140           ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
01141         else
01142           ris=ASN1_DER_ERROR;
01143         if(ris==ASN1_SUCCESS){
01144           while(p->down->right){
01145             p2=p->down->right;
01146             asn1_delete_structure(&p2);
01147           }
01148           break;
01149         }
01150         else if(ris==ASN1_ERROR_TYPE_ANY){
01151           asn1_delete_structure(structure);
01152           return ASN1_ERROR_TYPE_ANY;
01153         }
01154         else{
01155           p2=p->down;
01156           asn1_delete_structure(&p2);
01157         }
01158       }
01159 
01160       if(p->down==NULL){
01161         if(!(p->type&CONST_OPTION)){
01162           asn1_delete_structure(structure);
01163           return ASN1_DER_ERROR;
01164         }
01165       }
01166       else
01167         p=p->down;
01168       }
01169 
01170       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
01171       p2=_asn1_find_up(p);
01172             len2=strtol(p2->value,NULL,10);
01173       if(counter>len2) ris=ASN1_TAG_ERROR;
01174       }
01175 
01176       if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
01177       if(ris!=ASN1_SUCCESS){
01178       if(p->type&CONST_OPTION){
01179         p->type|=CONST_NOT_USED;
01180         move=RIGHT;
01181       }
01182       else if(p->type&CONST_DEFAULT) {
01183         _asn1_set_value(p,NULL,0);
01184         move=RIGHT;
01185       }
01186       else {
01187         if (errorDescription!=NULL)
01188           _asn1_error_description_tag_error(p,errorDescription);
01189         
01190         asn1_delete_structure(structure);
01191         return ASN1_TAG_ERROR;
01192       }
01193       } 
01194       else counter+=len2;
01195     }
01196 
01197     if(ris==ASN1_SUCCESS){
01198       switch(type_field(p->type)){
01199       case TYPE_NULL:
01200       if(der[counter]){
01201         asn1_delete_structure(structure);
01202         return ASN1_DER_ERROR;
01203       }
01204       
01205       if(p==nodeFound) state=EXIT;
01206        
01207       counter++;
01208       move=RIGHT;
01209       break;
01210       case TYPE_BOOLEAN:
01211       if(der[counter++]!=1){
01212         asn1_delete_structure(structure);
01213         return ASN1_DER_ERROR;
01214       }
01215 
01216       if(state==FOUND){
01217         if(der[counter++]==0) _asn1_set_value(p,"F",1);
01218         else _asn1_set_value(p,"T",1);
01219        
01220         if(p==nodeFound) state=EXIT;
01221 
01222       }
01223       else
01224         counter++;
01225 
01226       move=RIGHT;
01227       break;
01228       case TYPE_INTEGER: case TYPE_ENUMERATED:
01229       len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01230       if(len2 < 0) return ASN1_DER_ERROR;
01231       if(state==FOUND){
01232         if (len3+len2 > len-counter) return ASN1_DER_ERROR;
01233         _asn1_set_value(p,der+counter,len3+len2);
01234         
01235         if(p==nodeFound) state=EXIT;
01236       }
01237       counter+=len3+len2;
01238       move=RIGHT;
01239       break;
01240       case TYPE_OBJECT_ID:
01241       if(state==FOUND){
01242         _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
01243         _asn1_set_value(p,temp,strlen(temp)+1);
01244         
01245         if(p==nodeFound) state=EXIT;
01246       }
01247       else{
01248         len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01249         if(len2 < 0) return ASN1_DER_ERROR;
01250         len2+=len3;
01251       }
01252 
01253       counter+=len2;
01254       move=RIGHT;
01255       break;
01256       case TYPE_TIME:
01257       if(state==FOUND){
01258         result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
01259         if (result != ASN1_SUCCESS) {
01260             asn1_delete_structure(structure);
01261               return result;
01262         }
01263 
01264         _asn1_set_value(p,temp,strlen(temp)+1);
01265         
01266         if(p==nodeFound) state=EXIT;
01267       }
01268       else{
01269         len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01270         if(len2 < 0) return ASN1_DER_ERROR;
01271         len2+=len3;
01272       }
01273 
01274       counter+=len2;
01275       move=RIGHT;
01276       break;
01277       case TYPE_OCTET_STRING:
01278       len3=len-counter;
01279       if(state==FOUND){
01280         ris=_asn1_get_octet_string(der+counter,p,&len3);
01281         if(p==nodeFound) state=EXIT;
01282       }
01283       else
01284         ris=_asn1_get_octet_string(der+counter,NULL,&len3);
01285 
01286       if(ris != ASN1_SUCCESS) return ris; 
01287       counter+=len3;
01288       move=RIGHT;
01289       break;
01290       case TYPE_GENERALSTRING:
01291       len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01292       if(len2 < 0) return ASN1_DER_ERROR;
01293       if(state==FOUND){
01294         if (len3+len2 > len-counter) return ASN1_DER_ERROR;
01295         _asn1_set_value(p,der+counter,len3+len2);
01296        
01297         if(p==nodeFound) state=EXIT;
01298       }
01299       counter+=len3+len2;
01300       move=RIGHT;
01301       break;
01302       case TYPE_BIT_STRING:
01303       len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01304       if(len2 < 0) return ASN1_DER_ERROR;
01305       if(state==FOUND){
01306         if (len3+len2 > len-counter) return ASN1_DER_ERROR;
01307         _asn1_set_value(p,der+counter,len3+len2);
01308         
01309         if(p==nodeFound) state=EXIT;
01310       }
01311       counter+=len3+len2;
01312       move=RIGHT;
01313       break;
01314       case TYPE_SEQUENCE:  case TYPE_SET:
01315       if(move==UP){
01316         len2=strtol(p->value,NULL,10);
01317         _asn1_set_value(p,NULL,0);
01318         if(len2==-1){ /* indefinite length method */
01319           if((der[counter]) || der[counter+1]){
01320             asn1_delete_structure(structure);
01321             return ASN1_DER_ERROR;
01322           }
01323           counter+=2;
01324         }
01325         else{ /* definite length method */
01326           if(len2!=counter){
01327             asn1_delete_structure(structure);
01328             return ASN1_DER_ERROR;
01329           }
01330         }
01331         if(p==nodeFound) state=EXIT;        
01332         move=RIGHT;
01333       }
01334       else{   /* move==DOWN || move==RIGHT */
01335         if(state==OTHER_BRANCH){
01336           len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01337           if(len3 < 0) return ASN1_DER_ERROR;
01338           counter+=len2+len3;
01339           move=RIGHT;
01340         }
01341         else { /*  state==SAME_BRANCH or state==FOUND */
01342           len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01343           if(len3 < 0) return ASN1_DER_ERROR;
01344           counter+=len2;
01345           if(len3>0){
01346             _asn1_ltostr(counter+len3,temp);
01347             _asn1_set_value(p,temp,strlen(temp)+1);
01348             move=DOWN;
01349           }
01350           else if(len3==0){
01351             p2=p->down;
01352             while(p2){
01353             if(type_field(p2->type)!=TYPE_TAG){
01354               p3=p2->right;
01355               asn1_delete_structure(&p2);
01356             p2=p3;
01357             }
01358             else
01359               p2=p2->right;
01360             }
01361             move=RIGHT;
01362           }
01363           else{ /* indefinite length method */
01364             _asn1_set_value(p,"-1",3);
01365             move=DOWN;
01366           } 
01367         }
01368       }
01369       break;
01370       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
01371       if(move==UP){
01372         len2=strtol(p->value,NULL,10);
01373         if(len2>counter){
01374           _asn1_append_sequence_set(p);
01375           p=p->down;
01376           while(p->right) p=p->right;
01377           move=RIGHT;
01378           continue;
01379         }
01380         _asn1_set_value(p,NULL,0);
01381         if(len2!=counter){
01382           asn1_delete_structure(structure);
01383           return ASN1_DER_ERROR;
01384         }
01385 
01386         if(p==nodeFound) state=EXIT;
01387       }
01388       else{   /* move==DOWN || move==RIGHT */
01389         if(state==OTHER_BRANCH){
01390           len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01391           if(len3 < 0) return ASN1_DER_ERROR;
01392           counter+=len2+len3;
01393           move=RIGHT;
01394         }
01395         else{ /* state==FOUND or state==SAME_BRANCH */
01396           len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01397           if(len3 < 0) return ASN1_DER_ERROR;
01398           counter+=len2;
01399           if(len3){
01400             _asn1_ltostr(counter+len3,temp);
01401             _asn1_set_value(p,temp,strlen(temp)+1);
01402             p2=p->down;
01403             while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
01404             if(p2->right==NULL) _asn1_append_sequence_set(p);
01405             p=p2;
01406             state=FOUND;
01407           }
01408         }
01409       }
01410       
01411       break;
01412       case TYPE_ANY:
01413       /* Check indefinite lenth method in a EXPLICIT TAG */
01414       if((p->type&CONST_TAG) && (der[counter-1]==0x80))
01415         indefinite=1;
01416       else
01417         indefinite=0;
01418 
01419       if(_asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
01420          return ASN1_DER_ERROR;
01421       if (counter+len2 > len)
01422         return ASN1_DER_ERROR;
01423 
01424       len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
01425       if(len4 < -1) return ASN1_DER_ERROR;
01426       
01427       if(len4 != -1){
01428         len2+=len4;
01429         if(state==FOUND){
01430           _asn1_length_der(len2+len3,NULL,&len4);
01431           temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
01432           if (temp2==NULL){
01433             asn1_delete_structure(structure);
01434             return ASN1_MEM_ALLOC_ERROR;
01435           }
01436           
01437           _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
01438           _asn1_set_value(p,temp2,len4);
01439           _asn1_afree(temp2);
01440 
01441           if(p==nodeFound) state=EXIT;
01442         }
01443         counter+=len2+len3;
01444       }
01445       else{ /* indefinite length */
01446         len2=len-counter;
01447         ris=_asn1_get_indefinite_length_string(der+counter,&len2);
01448         if(ris != ASN1_SUCCESS){
01449           asn1_delete_structure(structure);
01450           return ris;
01451         }
01452         
01453         if(state==FOUND){
01454           _asn1_length_der(len2,NULL,&len4);
01455           temp2=(unsigned char *)_asn1_alloca(len2+len4);
01456           if (temp2==NULL){
01457             asn1_delete_structure(structure);
01458             return ASN1_MEM_ALLOC_ERROR;
01459           }
01460         
01461           _asn1_octet_der(der+counter,len2,temp2,&len4);
01462           _asn1_set_value(p,temp2,len4);
01463           _asn1_afree(temp2);
01464 
01465           if(p==nodeFound) state=EXIT;
01466         }
01467 
01468         counter+=len2;
01469       }
01470 
01471       /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
01472          a indefinite length method. */
01473       if(indefinite){
01474         if(!der[counter] && !der[counter+1]){ 
01475           counter+=2;
01476         }
01477         else{
01478           asn1_delete_structure(structure);
01479           return ASN1_DER_ERROR;
01480         }
01481       }
01482       move=RIGHT;
01483       break;
01484 
01485       default:
01486       move=(move==UP)?RIGHT:DOWN;
01487       break;
01488       }
01489     }
01490 
01491     if((p==node && move!=DOWN) || (state==EXIT)) break;
01492 
01493     if(move==DOWN){
01494       if(p->down){
01495       p=p->down;
01496 
01497       if(state != FOUND){
01498         nameLen-=strlen(p->name)+1;
01499         if(nameLen>0){
01500           if(currentName[0]) strcat(currentName,".");
01501           strcat(currentName,p->name);
01502         }
01503         else{
01504           asn1_delete_structure(structure);
01505           return ASN1_MEM_ERROR;
01506         }
01507         if(!(strcmp(currentName,elementName))){ 
01508           state=FOUND;
01509           nodeFound=p;
01510         }
01511         else if(!memcmp(currentName,elementName,strlen(currentName))) 
01512           state=SAME_BRANCH;
01513         else 
01514           state=OTHER_BRANCH;
01515       }
01516       }
01517       else move=RIGHT;
01518     }
01519 
01520     if((move==RIGHT) && !(p->type&CONST_SET)){
01521       if(p->right){
01522       p=p->right;
01523 
01524       if(state != FOUND){
01525         dot_p=char_p=currentName;
01526         while((char_p=strchr(char_p,'.'))){
01527           dot_p=char_p++;
01528           dot_p++;
01529         }
01530         
01531         nameLen+=strlen(currentName)-(dot_p-currentName);
01532         *dot_p=0;
01533 
01534         nameLen-=strlen(p->name);
01535         if(nameLen>0) strcat(currentName,p->name);
01536         else{
01537           asn1_delete_structure(structure);
01538           return ASN1_MEM_ERROR;
01539         }
01540         
01541         if(!(strcmp(currentName,elementName))){ 
01542           state=FOUND;
01543           nodeFound=p;
01544         }
01545         else if(!memcmp(currentName,elementName,strlen(currentName))) 
01546           state=SAME_BRANCH;
01547         else 
01548           state=OTHER_BRANCH;
01549       }
01550       }
01551       else move=UP;
01552     }
01553 
01554     if(move==UP){
01555       p=_asn1_find_up(p);
01556 
01557       if(state != FOUND){
01558       dot_p=char_p=currentName;
01559       while((char_p=strchr(char_p,'.'))){
01560         dot_p=char_p++;
01561         dot_p++;
01562       }
01563       
01564       nameLen+=strlen(currentName)-(dot_p-currentName);
01565       *dot_p=0;
01566       
01567       if(!(strcmp(currentName,elementName))){ 
01568       state=FOUND;
01569       nodeFound=p;
01570       }
01571       else if(!memcmp(currentName,elementName,strlen(currentName))) 
01572         state=SAME_BRANCH;
01573       else 
01574         state=OTHER_BRANCH;
01575       }
01576     }
01577   }
01578 
01579   _asn1_delete_not_used(*structure);
01580 
01581   if(counter > len){
01582     asn1_delete_structure(structure);
01583     return ASN1_DER_ERROR;
01584   }
01585 
01586   return ASN1_SUCCESS;
01587 }
01588 
01589 
01590 
01591 /**
01592   * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
01593   * @element: pointer to an ASN1 element
01594   * @ider: vector that contains the DER encoding. 
01595   * @len: number of bytes of *der: der[0]..der[len-1]
01596   * @name_element: an element of NAME structure.
01597   * @start: the position of the first byte of NAME_ELEMENT decoding (der[*start]) 
01598   * @end: the position of the last byte of NAME_ELEMENT decoding (der[*end])
01599   * Description:
01600   * 
01601   * Find the start and end point of an element in a DER encoding string. I mean that if you
01602   * have a der encoding and you have already used the function "asn1_der_decoding" to fill a structure, it may
01603   * happen that you want to find the piece of string concerning an element of the structure.
01604   * 
01605   * Example: the sequence "tbsCertificate" inside an X509 certificate.
01606   *
01607   * Returns:
01608   *
01609   *   ASN1_SUCCESS\: DER encoding OK
01610   *
01611   *   ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE EMPTY  or NAME_ELEMENT is not a valid element.
01612   *
01613   *   ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure ELEMENT.
01614   *
01615   **/
01616 asn1_retCode
01617 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
01618                      const char *name_element,int *start, int *end)
01619 {
01620   node_asn *node,*node_to_find,*p,*p2,*p3;
01621   int counter,len2,len3,len4,move,ris;
01622   unsigned char class;
01623   unsigned long tag;
01624   int indefinite;
01625   const unsigned char* der = ider;
01626 
01627   node=element;
01628 
01629   if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
01630 
01631   node_to_find=_asn1_find_node(node,name_element);
01632 
01633   if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
01634 
01635   if(node_to_find==node){
01636     *start=0;
01637     *end=len-1;
01638     return ASN1_SUCCESS;
01639   }
01640 
01641   if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
01642 
01643   counter=0;
01644   move=DOWN;
01645   p=node;
01646   while(1){
01647     ris=ASN1_SUCCESS;
01648     
01649     if(move!=UP){
01650       if(p->type&CONST_SET){
01651       p2=_asn1_find_up(p);
01652       len2=strtol(p2->value,NULL,10);
01653       if(len2==-1){
01654         if(!der[counter] && !der[counter+1]){
01655           p=p2;
01656           move=UP;
01657           counter+=2;
01658           continue;
01659         }
01660       }
01661       else if(counter==len2){
01662         p=p2;
01663         move=UP;
01664         continue;
01665       }
01666       else if(counter>len2) return ASN1_DER_ERROR;
01667       p2=p2->down;
01668       while(p2){
01669         if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){  /* CONTROLLARE */
01670           if(type_field(p2->type)!=TYPE_CHOICE)
01671             ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
01672           else{
01673             p3=p2->down;
01674             ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
01675           }
01676           if(ris==ASN1_SUCCESS){
01677             p2->type&=~CONST_NOT_USED;
01678             p=p2;
01679             break;
01680           }
01681         }
01682         p2=p2->right;
01683       }
01684       if(p2==NULL) return ASN1_DER_ERROR;
01685       }
01686 
01687       if(p==node_to_find) *start=counter;
01688 
01689       if(type_field(p->type)==TYPE_CHOICE){
01690       p=p->down;
01691       ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
01692       if(p==node_to_find) *start=counter;
01693       }
01694 
01695       if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
01696       if(ris!=ASN1_SUCCESS){
01697       if(p->type&CONST_OPTION){
01698         p->type|=CONST_NOT_USED;
01699         move=RIGHT;
01700       }
01701       else if(p->type&CONST_DEFAULT) {
01702         move=RIGHT;
01703       }
01704       else {
01705         return ASN1_TAG_ERROR;
01706       }
01707       } 
01708       else counter+=len2;
01709     }
01710 
01711     if(ris==ASN1_SUCCESS){
01712       switch(type_field(p->type)){
01713       case TYPE_NULL:
01714       if(der[counter]) return ASN1_DER_ERROR;
01715       counter++;
01716       move=RIGHT;
01717       break;
01718       case TYPE_BOOLEAN:
01719       if(der[counter++]!=1) return ASN1_DER_ERROR;
01720       counter++;
01721       move=RIGHT;
01722       break;
01723       case TYPE_INTEGER: case TYPE_ENUMERATED:
01724       len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01725       if(len2 < 0) return ASN1_DER_ERROR;
01726       counter+=len3+len2;
01727       move=RIGHT;