Doc fixes, from Martijn Koster <mak@greenhills.co.uk>.
[platform/upstream/libtasn1.git] / lib / decoding.c
1 /*
2  *      Copyright (C) 2002 Fabio Fiorina
3  *
4  * This file is part of LIBASN1.
5  *
6  * The LIBTASN1 library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public   
8  * License as published by the Free Software Foundation; either 
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  */
20  
21
22 /*****************************************************/
23 /* File: decoding.c                                  */
24 /* Description: Functions to manage DER decoding     */
25 /*****************************************************/
26  
27 #include <int.h>
28 #include <errors.h>
29 #include "der.h"
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "structure.h"
33 #include "element.h"
34
35
36 void
37 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
38 {
39
40   Estrcpy(ErrorDescription,":: tag error near element '");
41   _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
42                           MAX_ERROR_DESCRIPTION_SIZE-40);
43   Estrcat(ErrorDescription,"'");
44
45 }
46
47   
48 signed long
49 _asn1_get_length_der(const unsigned char *der,int  *len)
50 {
51   unsigned long ans;
52   int k,punt;
53
54   if(!(der[0]&128)){
55     /* short form */
56     *len=1;
57     return der[0];
58   }
59   else{
60     /* Long form */
61     k=der[0]&0x7F;
62     punt=1;
63     if(k){  /* definite length method */
64       ans=0;
65       while(punt<=k) ans=ans*256+der[punt++];
66     }
67     else{  /* indefinite length method */
68       ans=-1;
69     }
70
71     *len=punt;
72     return ans;
73   }
74 }
75
76
77
78
79 unsigned int
80 _asn1_get_tag_der(const unsigned char *der,unsigned char *class,int  *len)
81 {
82   int punt,ris;
83
84   if (der==NULL || len == NULL) return ASN1_DER_ERROR;
85   *class=der[0]&0xE0;
86   if((der[0]&0x1F)!=0x1F){
87     /* short form */
88     *len=1;
89     ris=der[0]&0x1F;
90   }
91   else{
92     /* Long form */
93     punt=1;
94     ris=0;
95     while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F);
96     ris=ris*128+(der[punt++]&0x7F);   
97     *len=punt;
98   }
99   return ris;
100 }
101
102
103
104
105 int
106 _asn1_get_octet_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
107 {
108   int len_len;
109
110   /* if(str==NULL) return ASN1_SUCCESS; */
111   *str_len=_asn1_get_length_der(der,&len_len);
112
113   *der_len=*str_len+len_len;
114   if ( str_size >= *str_len)
115           memcpy(str,der+len_len,*str_len);
116   else {
117         return ASN1_MEM_ERROR;
118   }
119   
120   return ASN1_SUCCESS;
121 }
122
123
124
125 /* Returns ASN1_SUCCESS on success or an error code on error.
126  */
127 int
128 _asn1_get_time_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size)
129 {
130   int len_len,str_len;
131
132   if(str==NULL) return ASN1_DER_ERROR;
133   str_len=_asn1_get_length_der(der,&len_len);
134   if (str_len < 0 || str_size < str_len) 
135      return ASN1_DER_ERROR;
136   memcpy(str,der+len_len,str_len);
137   str[str_len]=0;
138   *der_len=str_len+len_len;
139   
140   return ASN1_SUCCESS;
141 }
142
143
144
145 void
146 _asn1_get_objectid_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size)
147 {
148   int len_len,len,k;
149   char temp[20];
150   unsigned long val,val1;
151
152   if(str==NULL) return;
153   len=_asn1_get_length_der(der,&len_len);
154   
155   val1=der[len_len]/40;
156   val=der[len_len]-val1*40;
157
158   _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
159   _asn1_str_cat(str, str_size, ".");
160   _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
161
162   val=0;
163   for(k=1;k<len;k++){
164     val=val<<7;
165     val|=der[len_len+k]&0x7F;
166     if(!(der[len_len+k]&0x80)){
167       _asn1_str_cat(str, str_size,".");
168       _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
169       val=0;
170     }
171   }
172   *der_len=len+len_len;
173 }
174
175
176
177
178 int
179 _asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
180 {
181   int len_len,len_byte;
182
183   len_byte=_asn1_get_length_der(der,&len_len)-1;
184
185   *der_len=len_byte+len_len+1;  
186   *bit_len=len_byte*8-der[len_len];
187
188   if (str_size >= len_byte)
189         memcpy(str,der+len_len+1,len_byte);
190   else {
191         return ASN1_MEM_ERROR;
192   }
193  
194   return ASN1_SUCCESS;
195 }
196
197
198
199
200 int
201 _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len)
202 {
203   node_asn *p;
204   int counter,len2,len3,is_tag_implicit;
205   unsigned long tag,tag_implicit=0;
206   unsigned char class,class2,class_implicit=0;
207
208
209   counter=is_tag_implicit=0;
210
211   if(node->type&CONST_TAG){
212     p=node->down;
213     while(p){
214       if(type_field(p->type)==TYPE_TAG){
215         if(p->type&CONST_APPLICATION) class2=APPLICATION;
216         else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
217         else if(p->type&CONST_PRIVATE) class2=PRIVATE;
218         else class2=CONTEXT_SPECIFIC;
219         
220         if(p->type&CONST_EXPLICIT){
221           tag=_asn1_get_tag_der(der+counter,&class,&len2);
222           counter+=len2;
223           len3=_asn1_get_length_der(der+counter,&len2);
224           counter+=len2;
225           if(!is_tag_implicit){
226             if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
227               return ASN1_TAG_ERROR;
228           }
229           else{    /* TAG_IMPLICIT */
230             if((class!=class_implicit) || (tag!=tag_implicit))
231               return ASN1_TAG_ERROR;
232           }
233
234           is_tag_implicit=0;
235         }
236         else{    /* TAG_IMPLICIT */
237           if(!is_tag_implicit){
238             if((type_field(node->type)==TYPE_SEQUENCE) ||
239                (type_field(node->type)==TYPE_SEQUENCE_OF) ||
240                (type_field(node->type)==TYPE_SET) ||
241                (type_field(node->type)==TYPE_SET_OF))  class2|=STRUCTURED;
242             class_implicit=class2;
243             tag_implicit=strtoul(p->value,NULL,10);
244             is_tag_implicit=1;
245           }
246         }
247       }
248       p=p->right;
249     }
250   }
251
252   if(is_tag_implicit){
253     tag=_asn1_get_tag_der(der+counter,&class,&len2);
254     if((class!=class_implicit) || (tag!=tag_implicit)){
255       if(type_field(node->type)==TYPE_OCTET_STRING){
256         class_implicit |= STRUCTURED;
257         if((class!=class_implicit) || (tag!=tag_implicit))
258           return ASN1_TAG_ERROR;
259       }
260       else
261         return ASN1_TAG_ERROR;
262     }
263   }
264   else{
265     if(type_field(node->type)==TYPE_TAG){
266       counter=0;
267       *der_len=counter;
268       return ASN1_SUCCESS;
269     }
270
271     tag=_asn1_get_tag_der(der+counter,&class,&len2);
272     switch(type_field(node->type)){
273     case TYPE_NULL:
274       if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
275        break;
276     case TYPE_BOOLEAN:
277       if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
278        break;
279     case TYPE_INTEGER:
280       if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
281        break;
282     case TYPE_ENUMERATED:
283       if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
284        break;
285     case TYPE_OBJECT_ID:
286       if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
287        break;
288     case TYPE_TIME:
289       if(node->type&CONST_UTC){
290           if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
291       }
292       else{
293         if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime)) 
294           return ASN1_DER_ERROR;
295       }
296       break;
297     case TYPE_OCTET_STRING:
298       if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
299          || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
300       break;
301     case TYPE_GENERALSTRING:
302       if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
303       break;
304     case TYPE_BIT_STRING:
305       if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
306       break;
307     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
308       if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE)) 
309         return ASN1_DER_ERROR;
310       break;
311     case TYPE_SET: case TYPE_SET_OF:
312       if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET)) 
313         return ASN1_DER_ERROR;
314       break;
315     case TYPE_ANY:
316       counter-=len2;
317       break;
318     default:
319       return ASN1_DER_ERROR;
320       break;
321     }
322   }
323
324   counter+=len2;
325   *der_len=counter;
326   return ASN1_SUCCESS;
327 }
328
329
330 int 
331 _asn1_delete_not_used(node_asn *node)
332 {
333   node_asn *p,*p2;
334
335   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
336
337   p=node;
338   while(p){
339     if(p->type&CONST_NOT_USED){
340       p2=NULL;
341       if(p!=node){
342         p2=_asn1_find_left(p);
343         if(!p2) p2=_asn1_find_up(p);
344       }
345       asn1_delete_structure(&p);
346       p=p2;
347     } 
348
349     if(!p) break;  /* reach node */
350
351     if(p->down){
352       p=p->down;
353     }
354     else{
355       if(p==node) p=NULL;
356       else if(p->right) p=p->right;
357       else{
358         while(1){
359           p=_asn1_find_up(p);
360           if(p==node){
361             p=NULL;
362             break;
363           }
364           if(p->right){
365             p=p->right;
366             break;
367           }
368         }
369       }
370     }
371   }
372   return ASN1_SUCCESS;
373 }
374
375
376 asn1_retCode
377 _asn1_get_octet_string(const unsigned char* der,node_asn *node,int* len)
378 {
379   int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
380   char *temp,*temp2;
381
382   counter=0;
383
384   if(*(der-1) & STRUCTURED){
385     tot_len=0;
386     indefinite=_asn1_get_length_der(der,&len3);
387
388     counter+=len3;
389     if(indefinite>=0) indefinite+=len3;
390  
391     while(1){
392       if(counter>(*len)) return ASN1_DER_ERROR;
393
394       if(indefinite==-1){
395         if((der[counter]==0) && (der[counter+1]==0)){
396           counter+=2;
397           break;
398         }
399       }
400       else if(counter>=indefinite) break;
401
402       if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
403         
404       counter++;
405
406       len2=_asn1_get_length_der(der+counter,&len3);
407       if(len2 <= 0) return ASN1_DER_ERROR;
408
409       counter+=len3+len2;
410       tot_len+=len2;
411     }
412
413     /* copy */
414     if(node){
415       _asn1_length_der(tot_len,NULL,&len2);
416       temp=(unsigned char *)_asn1_alloca(len2+tot_len);
417       if (temp==NULL){
418         return ASN1_MEM_ALLOC_ERROR;
419       }
420       
421       _asn1_length_der(tot_len,temp,&len2);
422       tot_len+=len2;
423       temp2=temp+len2;
424       len2=_asn1_get_length_der(der,&len3);
425       counter2=len3+1;
426
427       if(indefinite==-1) counter_end=counter-2;
428       else counter_end=counter;
429       
430       while(counter2<counter_end){
431         len2=_asn1_get_length_der(der+counter2,&len3);  
432         memcpy(temp2,der+counter2+len3,len2);
433         temp2+=len2;
434         counter2+=len2+len3+1;
435       }
436       _asn1_set_value(node,temp,tot_len);
437       _asn1_afree(temp);
438     }
439   }
440   else{  /* NOT STRUCTURED */
441     len2=_asn1_get_length_der(der,&len3);
442     if(node)
443       _asn1_set_value(node,der,len3+len2);
444     counter=len3+len2;
445   }   
446
447   *len=counter;
448   return ASN1_SUCCESS;
449
450 }
451
452
453 asn1_retCode
454 _asn1_get_indefinite_length_string(const unsigned char* der,int* len)
455 {
456   int len2,len3,counter,indefinite;
457   unsigned int tag;
458   unsigned char class;
459
460   counter=indefinite=0;
461
462   while(1){
463     if((*len)<counter) return ASN1_DER_ERROR;
464
465     if((der[counter]==0) && (der[counter+1]==0)){
466       counter+=2;
467       indefinite--;
468       if(indefinite<=0) break;
469       else continue;
470     }
471
472     tag=_asn1_get_tag_der(der+counter,&class,&len2);
473     counter+=len2;
474     len2=_asn1_get_length_der(der+counter,&len3);
475     if(len2 == -1){
476       indefinite++;
477       counter+=1;
478     }
479     else{
480       counter+=len2+len3;
481     }
482   }
483
484   *len=counter;
485   return ASN1_SUCCESS;
486
487 }
488
489
490 /**
491   * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
492   * @element: pointer to an ASN1 structure
493   * @ider: vector that contains the DER encoding. 
494   * @len: number of bytes of *der: der[0]..der[len-1]
495   * Description:
496   *
497   * Fill the structure *ELEMENT with values of a DER encoding string. The sructure must just be
498   * created with function 'create_stucture'.
499   * If an error occurs during the decoding procedure, the *ELEMENT is deleted
500   * and set equal to ASN1_TYPE_EMPTY.
501   *
502   * Returns:
503   *
504   *   ASN1_SUCCESS\: DER encoding OK
505   *
506   *   ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY.
507   *
508   *   ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure NAME. *ELEMENT deleted. 
509   **/
510
511 asn1_retCode
512 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
513                   char *errorDescription)
514 {
515   node_asn *node,*p,*p2,*p3;
516   char temp[128];
517   int counter,len2,len3,len4,move,ris;
518   unsigned char class,*temp2;
519   unsigned int tag;
520   int indefinite, result;
521   const unsigned char* der = ider;
522
523   node=*element;
524
525   if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
526
527   if(node->type&CONST_OPTION){
528     asn1_delete_structure(element);
529     return ASN1_GENERIC_ERROR;
530   }
531
532   counter=0;
533   move=DOWN;
534   p=node;
535   while(1){
536     ris=ASN1_SUCCESS;
537     if(move!=UP){
538       if(p->type&CONST_SET){
539         p2=_asn1_find_up(p);
540         len2=strtol(p2->value,NULL,10);
541         if(len2==-1){
542           if(!der[counter] && !der[counter+1]){
543             p=p2;
544             move=UP;
545             counter+=2;
546             continue;
547           }
548         }
549         else if(counter==len2){
550           p=p2;
551           move=UP;
552           continue;
553         }
554         else if(counter>len2){
555           asn1_delete_structure(element);
556           return ASN1_DER_ERROR;
557         }
558         p2=p2->down;
559         while(p2){
560           if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
561             if(type_field(p2->type)!=TYPE_CHOICE)
562               ris=_asn1_extract_tag_der(p2,der+counter,&len2);
563             else{
564               p3=p2->down;
565               while(p3){
566                 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
567                 if(ris==ASN1_SUCCESS) break;
568                 p3=p3->right;
569               }
570             }
571             if(ris==ASN1_SUCCESS){
572               p2->type&=~CONST_NOT_USED;
573               p=p2;
574               break;
575             }
576           }
577           p2=p2->right;
578         }
579         if(p2==NULL){
580           asn1_delete_structure(element);
581           return ASN1_DER_ERROR;
582         }
583       }
584
585       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
586         p2=_asn1_find_up(p);
587         len2=strtol(p2->value,NULL,10);
588         if(counter==len2){
589           if(p->right){
590             p2=p->right;
591             move=RIGHT;
592           }
593           else move=UP;
594
595           if(p->type&CONST_OPTION) asn1_delete_structure(&p);
596
597           p=p2;
598           continue;
599         }
600       }
601
602       if(type_field(p->type)==TYPE_CHOICE){
603         while(p->down){
604           if(counter<len)
605             ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
606           else
607             ris=ASN1_DER_ERROR;
608           if(ris==ASN1_SUCCESS){
609             while(p->down->right){
610               p2=p->down->right;
611               asn1_delete_structure(&p2);
612             }
613             break;
614           }
615           else if(ris==ASN1_ERROR_TYPE_ANY){
616             asn1_delete_structure(element);
617             return ASN1_ERROR_TYPE_ANY;
618           }
619           else{
620             p2=p->down;
621             asn1_delete_structure(&p2);
622           }
623         }
624
625         if(p->down==NULL){
626           if(!(p->type&CONST_OPTION)){
627             asn1_delete_structure(element);
628             return ASN1_DER_ERROR;
629           }
630         }
631         else
632           p=p->down;
633       }
634
635       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
636         p2=_asn1_find_up(p);
637         len2=strtol(p2->value,NULL,10);
638         if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
639       }
640      
641       if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
642       if(ris!=ASN1_SUCCESS){
643         if(p->type&CONST_OPTION){
644           p->type|=CONST_NOT_USED;
645           move=RIGHT;
646         }
647         else if(p->type&CONST_DEFAULT) {
648           _asn1_set_value(p,NULL,0);
649           move=RIGHT;
650         }
651         else {
652           if (errorDescription!=NULL)
653             _asn1_error_description_tag_error(p,errorDescription);
654           
655           asn1_delete_structure(element);
656           return ASN1_TAG_ERROR;
657         }
658       } 
659       else counter+=len2;
660     }
661
662     if(ris==ASN1_SUCCESS){
663       switch(type_field(p->type)){
664       case TYPE_NULL:
665         if(der[counter]){
666           asn1_delete_structure(element);
667           return ASN1_DER_ERROR;
668         }
669         counter++;
670         move=RIGHT;
671         break;
672       case TYPE_BOOLEAN:
673         if(der[counter++]!=1){
674           asn1_delete_structure(element);
675           return ASN1_DER_ERROR;
676         }
677         if(der[counter++]==0) _asn1_set_value(p,"F",1);
678         else _asn1_set_value(p,"T",1);
679         move=RIGHT;
680         break;
681       case TYPE_INTEGER: case TYPE_ENUMERATED:
682         len2=_asn1_get_length_der(der+counter,&len3);
683         _asn1_set_value(p,der+counter,len3+len2);
684         counter+=len3+len2;
685         move=RIGHT;
686         break;
687       case TYPE_OBJECT_ID:
688         _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
689         _asn1_set_value(p,temp,strlen(temp)+1);
690         counter+=len2;
691         move=RIGHT;
692       break;
693       case TYPE_TIME:
694         result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1);
695         if (result != ASN1_SUCCESS) {
696                 asn1_delete_structure(element);
697                 return result;
698         }
699         _asn1_set_value(p,temp,strlen(temp)+1);
700         counter+=len2;
701         move=RIGHT;
702         break;
703       case TYPE_OCTET_STRING:
704         len3=len-counter;
705         ris=_asn1_get_octet_string(der+counter,p,&len3);
706         if(ris != ASN1_SUCCESS) return ris; 
707         counter+=len3;
708         move=RIGHT;
709         break;
710       case TYPE_GENERALSTRING:
711         len2=_asn1_get_length_der(der+counter,&len3);
712         _asn1_set_value(p,der+counter,len3+len2);
713         counter+=len3+len2;
714         move=RIGHT;
715         break;
716       case TYPE_BIT_STRING:
717         len2=_asn1_get_length_der(der+counter,&len3);
718         _asn1_set_value(p,der+counter,len3+len2);
719         counter+=len3+len2;
720         move=RIGHT;
721         break;
722       case TYPE_SEQUENCE:  case TYPE_SET:
723         if(move==UP){
724           len2=strtol(p->value,NULL,10);
725           _asn1_set_value(p,NULL,0);
726           if(len2==-1){ /* indefinite length method */
727             if((der[counter]) || der[counter+1]){
728               asn1_delete_structure(element);
729               return ASN1_DER_ERROR;
730             }
731             counter+=2;
732           }
733           else{ /* definite length method */
734             if(len2!=counter){
735               asn1_delete_structure(element);
736               return ASN1_DER_ERROR;
737             }
738           }
739           move=RIGHT;
740         }
741         else{   /* move==DOWN || move==RIGHT */
742           len3=_asn1_get_length_der(der+counter,&len2);
743           counter+=len2;
744           if(len3>0){
745             _asn1_ltostr(counter+len3,temp);
746             _asn1_set_value(p,temp,strlen(temp)+1);
747             move=DOWN; 
748           }
749           else if(len3==0){
750             p2=p->down;
751             while(p2){
752               if(type_field(p2->type)!=TYPE_TAG){
753                 p3=p2->right;
754                 asn1_delete_structure(&p2);
755                 p2=p3;
756               }
757               else
758                 p2=p2->right;
759             }
760             move=RIGHT;
761           }
762           else{ /* indefinite length method */
763             _asn1_set_value(p,"-1",3);
764             move=DOWN; 
765           }
766         }
767         break;
768       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
769         if(move==UP){
770           len2=strtol(p->value,NULL,10);
771           if(len2==-1){ /* indefinite length method */
772             if((counter+2)>len) return ASN1_DER_ERROR;
773             if((der[counter]) || der[counter+1]){
774               _asn1_append_sequence_set(p);
775               p=p->down;
776               while(p->right) p=p->right;
777               move=RIGHT;
778               continue;
779             }
780             _asn1_set_value(p,NULL,0);
781             counter+=2;
782           }
783           else{ /* definite length method */
784             if(len2>counter){
785               _asn1_append_sequence_set(p);
786               p=p->down;
787               while(p->right) p=p->right;
788               move=RIGHT;
789               continue;
790             }
791             _asn1_set_value(p,NULL,0);
792             if(len2!=counter){
793               asn1_delete_structure(element);
794               return ASN1_DER_ERROR;
795             }
796           }
797         }
798         else{   /* move==DOWN || move==RIGHT */
799           len3=_asn1_get_length_der(der+counter,&len2);
800           counter+=len2;
801           if(len3){
802             if(len3>0){ /* definite length method */
803             _asn1_ltostr(counter+len3,temp);
804             _asn1_set_value(p,temp,strlen(temp)+1);
805             }
806             else { /* indefinite length method */
807               _asn1_set_value(p,"-1",3);              
808             }
809             p2=p->down;
810             while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
811             if(p2->right==NULL) _asn1_append_sequence_set(p);
812             p=p2;
813           }
814         }
815         move=RIGHT;
816         break;
817       case TYPE_ANY:
818         tag=_asn1_get_tag_der(der+counter,&class,&len2);
819         len4=_asn1_get_length_der(der+counter+len2,&len3);
820         
821         if(len4 != -1){
822           len2+=len4;
823           _asn1_length_der(len2+len3,NULL,&len4);
824           temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
825           if (temp2==NULL){
826             asn1_delete_structure(element);
827             return ASN1_MEM_ALLOC_ERROR;
828           }
829         
830           _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
831           _asn1_set_value(p,temp2,len4);
832           _asn1_afree(temp2);
833           counter+=len2+len3;
834         }
835         else{ /* indefinite length */
836           /* Check indefinite lenth method in an EXPLICIT TAG */
837           if((p->type&CONST_TAG) && (der[counter-1]==0x80))
838             indefinite=1;
839           else
840             indefinite=0;
841
842           len2=len-counter;
843           ris=_asn1_get_indefinite_length_string(der+counter,&len2);
844           if(ris != ASN1_SUCCESS){
845             asn1_delete_structure(element);
846             return ris;
847           }
848           _asn1_length_der(len2,NULL,&len4);
849           temp2=(unsigned char *)_asn1_alloca(len2+len4);
850           if (temp2==NULL){
851             asn1_delete_structure(element);
852             return ASN1_MEM_ALLOC_ERROR;
853           }
854         
855           _asn1_octet_der(der+counter,len2,temp2,&len4);
856           _asn1_set_value(p,temp2,len4);
857           _asn1_afree(temp2);
858           counter+=len2;
859
860           /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
861              an indefinite length method. */
862           if(indefinite){
863             if(!der[counter] && !der[counter+1]){ 
864               counter+=2;
865             }
866             else{
867               asn1_delete_structure(element);
868               return ASN1_DER_ERROR;
869             }
870           }
871         }
872         move=RIGHT;
873         break;
874       default:
875         move=(move==UP)?RIGHT:DOWN;
876         break;
877       }
878     }
879
880     if(p==node && move!=DOWN) break;
881
882     if(move==DOWN){
883       if(p->down) p=p->down;
884       else move=RIGHT;
885     }
886     if((move==RIGHT) && !(p->type&CONST_SET)){
887       if(p->right) p=p->right;
888       else move=UP;
889     }
890     if(move==UP) p=_asn1_find_up(p);
891   }
892
893   _asn1_delete_not_used(*element);
894
895   if(counter != len){
896     asn1_delete_structure(element);
897     return ASN1_DER_ERROR;
898   }
899
900   return ASN1_SUCCESS;
901 }
902
903
904 #define FOUND        1
905 #define SAME_BRANCH  2
906 #define OTHER_BRANCH 3
907 #define EXIT         4
908
909 /**
910   * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
911   * @structure: pointer to an ASN1 structure
912   * @elementName: name of the element to fill
913   * @ider: vector that contains the DER encoding of the whole structure. 
914   * @len: number of bytes of *der: der[0]..der[len-1]
915   * @errorDescription: null-terminated string contains details when an error occurred.
916   * 
917   * Description:
918   *
919   * Fill the element named ELEMENTNAME with values of a DER encoding string. 
920   * The sructure must just be created with function 'create_stucture'.
921   * The DER vector must contain the encoding string of the whole STRUCTURE.
922   * If an error occurs during the decoding procedure, the *STRUCTURE is deleted
923   * and set equal to ASN1_TYPE_EMPTY.
924   *
925   * Returns:
926   *
927   *   ASN1_SUCCESS\: DER encoding OK
928   *
929   *   ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY or elementName == NULL.
930   *
931   *   ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure STRUCTURE. *ELEMENT deleted. 
932   *
933   **/
934 asn1_retCode
935 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
936                           const void *ider,int len,char *errorDescription)
937 {
938   node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
939   char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
940   int nameLen=MAX_NAME_SIZE*10-1,state;
941   int counter,len2,len3,len4,move,ris;
942   unsigned char class,*temp2;
943   unsigned int tag;
944   int indefinite, result;
945   const unsigned char* der = ider;
946
947   node=*structure;
948
949   if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
950
951   if(elementName == NULL){
952     asn1_delete_structure(structure);    
953     return ASN1_ELEMENT_NOT_FOUND;
954   }
955
956   if(node->type&CONST_OPTION){
957     asn1_delete_structure(structure);
958     return ASN1_GENERIC_ERROR;
959   }
960
961   if((*structure)->name){  /* Has *structure got a name? */
962     nameLen-=strlen((*structure)->name);
963     if(nameLen>0) strcpy(currentName,(*structure)->name);
964     else{
965       asn1_delete_structure(structure);
966       return ASN1_MEM_ERROR;
967     }
968     if(!(strcmp(currentName,elementName))){ 
969       state=FOUND;
970       nodeFound=*structure;
971     }
972     else if(!memcmp(currentName,elementName,strlen(currentName))) 
973       state=SAME_BRANCH;
974     else 
975       state=OTHER_BRANCH;
976   }
977   else{  /* *structure doesn't have a name? */
978     currentName[0]=0;
979     if(elementName[0]==0){
980       state=FOUND;
981       nodeFound=*structure;
982     }
983     else{
984       state=SAME_BRANCH;
985     }
986   }
987
988   counter=0;
989   move=DOWN;
990   p=node;
991   while(1){
992
993     ris=ASN1_SUCCESS;
994
995     if(move!=UP){
996       if(p->type&CONST_SET){
997         p2=_asn1_find_up(p);
998         len2=strtol(p2->value,NULL,10);
999         if(counter==len2){
1000           p=p2;
1001           move=UP;
1002           continue;
1003         }
1004         else if(counter>len2){
1005           asn1_delete_structure(structure);
1006           return ASN1_DER_ERROR;
1007         }
1008         p2=p2->down;
1009         while(p2){
1010           if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
1011             if(type_field(p2->type)!=TYPE_CHOICE)
1012               ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1013             else{
1014               p3=p2->down;
1015               while(p3){
1016                 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1017                 if(ris==ASN1_SUCCESS) break;
1018                 p3=p3->right;
1019               }
1020             }
1021             if(ris==ASN1_SUCCESS){
1022               p2->type&=~CONST_NOT_USED;
1023               p=p2;
1024               break;
1025             }
1026           }
1027           p2=p2->right;
1028         }
1029         if(p2==NULL){
1030           asn1_delete_structure(structure);
1031           return ASN1_DER_ERROR;
1032         }
1033       }
1034
1035       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1036         p2=_asn1_find_up(p);
1037         len2=strtol(p2->value,NULL,10);
1038         if(counter==len2){
1039           if(p->right){
1040             p2=p->right;
1041             move=RIGHT;
1042           }
1043           else move=UP;
1044
1045           if(p->type&CONST_OPTION) asn1_delete_structure(&p);
1046
1047           p=p2;
1048           continue;
1049         }
1050       }
1051
1052       if(type_field(p->type)==TYPE_CHOICE){
1053         while(p->down){
1054           if(counter<len)
1055             ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
1056           else
1057             ris=ASN1_DER_ERROR;
1058           if(ris==ASN1_SUCCESS){
1059             while(p->down->right){
1060               p2=p->down->right;
1061               asn1_delete_structure(&p2);
1062             }
1063             break;
1064           }
1065           else if(ris==ASN1_ERROR_TYPE_ANY){
1066             asn1_delete_structure(structure);
1067             return ASN1_ERROR_TYPE_ANY;
1068           }
1069           else{
1070             p2=p->down;
1071             asn1_delete_structure(&p2);
1072           }
1073         }
1074
1075         if(p->down==NULL){
1076           if(!(p->type&CONST_OPTION)){
1077             asn1_delete_structure(structure);
1078             return ASN1_DER_ERROR;
1079           }
1080         }
1081         else
1082           p=p->down;
1083       }
1084
1085       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1086         p2=_asn1_find_up(p);
1087         len2=strtol(p2->value,NULL,10);
1088         if(counter>len2) ris=ASN1_TAG_ERROR;
1089       }
1090
1091       if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1092       if(ris!=ASN1_SUCCESS){
1093         if(p->type&CONST_OPTION){
1094           p->type|=CONST_NOT_USED;
1095           move=RIGHT;
1096         }
1097         else if(p->type&CONST_DEFAULT) {
1098           _asn1_set_value(p,NULL,0);
1099           move=RIGHT;
1100         }
1101         else {
1102           if (errorDescription!=NULL)
1103             _asn1_error_description_tag_error(p,errorDescription);
1104           
1105           asn1_delete_structure(structure);
1106           return ASN1_TAG_ERROR;
1107         }
1108       } 
1109       else counter+=len2;
1110     }
1111
1112     if(ris==ASN1_SUCCESS){
1113       switch(type_field(p->type)){
1114       case TYPE_NULL:
1115         if(der[counter]){
1116           asn1_delete_structure(structure);
1117           return ASN1_DER_ERROR;
1118         }
1119         
1120         if(p==nodeFound) state=EXIT;
1121          
1122         counter++;
1123         move=RIGHT;
1124         break;
1125       case TYPE_BOOLEAN:
1126         if(der[counter++]!=1){
1127           asn1_delete_structure(structure);
1128           return ASN1_DER_ERROR;
1129         }
1130
1131         if(state==FOUND){
1132           if(der[counter++]==0) _asn1_set_value(p,"F",1);
1133           else _asn1_set_value(p,"T",1);
1134          
1135           if(p==nodeFound) state=EXIT;
1136
1137         }
1138         else
1139           counter++;
1140
1141         move=RIGHT;
1142         break;
1143       case TYPE_INTEGER: case TYPE_ENUMERATED:
1144         len2=_asn1_get_length_der(der+counter,&len3);
1145         if(state==FOUND){
1146           _asn1_set_value(p,der+counter,len3+len2);
1147           
1148           if(p==nodeFound) state=EXIT;
1149         }
1150         counter+=len3+len2;
1151         move=RIGHT;
1152         break;
1153       case TYPE_OBJECT_ID:
1154         if(state==FOUND){
1155           _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
1156           _asn1_set_value(p,temp,strlen(temp)+1);
1157           
1158           if(p==nodeFound) state=EXIT;
1159         }
1160         else{
1161           len2=_asn1_get_length_der(der+counter,&len3);
1162           len2+=len3;
1163         }
1164
1165         counter+=len2;
1166         move=RIGHT;
1167       break;
1168       case TYPE_TIME:
1169         if(state==FOUND){
1170           result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1);
1171           if (result != ASN1_SUCCESS) {
1172                 asn1_delete_structure(structure);
1173                 return result;
1174           }
1175
1176           _asn1_set_value(p,temp,strlen(temp)+1);
1177           
1178           if(p==nodeFound) state=EXIT;
1179         }
1180         else{
1181           len2=_asn1_get_length_der(der+counter,&len3);
1182           len2+=len3;
1183         }
1184
1185         counter+=len2;
1186         move=RIGHT;
1187         break;
1188       case TYPE_OCTET_STRING:
1189         len3=len-counter;
1190         if(state==FOUND){
1191           ris=_asn1_get_octet_string(der+counter,p,&len3);
1192           if(p==nodeFound) state=EXIT;
1193         }
1194         else
1195           ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1196
1197         if(ris != ASN1_SUCCESS) return ris; 
1198         counter+=len3;
1199         move=RIGHT;
1200         break;
1201       case TYPE_GENERALSTRING:
1202         len2=_asn1_get_length_der(der+counter,&len3);
1203         if(state==FOUND){
1204           _asn1_set_value(p,der+counter,len3+len2);
1205          
1206           if(p==nodeFound) state=EXIT;
1207         }
1208         counter+=len3+len2;
1209         move=RIGHT;
1210         break;
1211       case TYPE_BIT_STRING:
1212         len2=_asn1_get_length_der(der+counter,&len3);
1213         if(state==FOUND){
1214           _asn1_set_value(p,der+counter,len3+len2);
1215           
1216           if(p==nodeFound) state=EXIT;
1217         }
1218         counter+=len3+len2;
1219         move=RIGHT;
1220         break;
1221       case TYPE_SEQUENCE:  case TYPE_SET:
1222         if(move==UP){
1223           len2=strtol(p->value,NULL,10);
1224           _asn1_set_value(p,NULL,0);
1225           if(len2==-1){ /* indefinite length method */
1226             if((der[counter]) || der[counter+1]){
1227               asn1_delete_structure(structure);
1228               return ASN1_DER_ERROR;
1229             }
1230             counter+=2;
1231           }
1232           else{ /* definite length method */
1233             if(len2!=counter){
1234               asn1_delete_structure(structure);
1235               return ASN1_DER_ERROR;
1236             }
1237           }
1238           if(p==nodeFound) state=EXIT;    
1239           move=RIGHT;
1240         }
1241         else{   /* move==DOWN || move==RIGHT */
1242           if(state==OTHER_BRANCH){
1243             len3=_asn1_get_length_der(der+counter,&len2);
1244             counter+=len2+len3;
1245             move=RIGHT;
1246           }
1247           else { /*  state==SAME_BRANCH or state==FOUND */
1248             len3=_asn1_get_length_der(der+counter,&len2);
1249             counter+=len2;
1250             if(len3>0){
1251               _asn1_ltostr(counter+len3,temp);
1252               _asn1_set_value(p,temp,strlen(temp)+1);
1253               move=DOWN;
1254             }
1255             else if(len3==0){
1256               p2=p->down;
1257               while(p2){
1258                 if(type_field(p2->type)!=TYPE_TAG){
1259                   p3=p2->right;
1260                   asn1_delete_structure(&p2);
1261                 p2=p3;
1262                 }
1263                 else
1264                   p2=p2->right;
1265               }
1266               move=RIGHT;
1267             }
1268             else{ /* indefinite length method */
1269               _asn1_set_value(p,"-1",3);
1270               move=DOWN;
1271             } 
1272           }
1273         }
1274         break;
1275       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1276         if(move==UP){
1277           len2=strtol(p->value,NULL,10);
1278           if(len2>counter){
1279             _asn1_append_sequence_set(p);
1280             p=p->down;
1281             while(p->right) p=p->right;
1282             move=RIGHT;
1283             continue;
1284           }
1285           _asn1_set_value(p,NULL,0);
1286           if(len2!=counter){
1287             asn1_delete_structure(structure);
1288             return ASN1_DER_ERROR;
1289           }
1290
1291           if(p==nodeFound) state=EXIT;
1292         }
1293         else{   /* move==DOWN || move==RIGHT */
1294           if(state==OTHER_BRANCH){
1295             len3=_asn1_get_length_der(der+counter,&len2);
1296             counter+=len2+len3;
1297             move=RIGHT;
1298           }
1299           else{ /* state==FOUND or state==SAME_BRANCH */
1300             len3=_asn1_get_length_der(der+counter,&len2);
1301             counter+=len2;
1302             if(len3){
1303               _asn1_ltostr(counter+len3,temp);
1304               _asn1_set_value(p,temp,strlen(temp)+1);
1305               p2=p->down;
1306               while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1307               if(p2->right==NULL) _asn1_append_sequence_set(p);
1308               p=p2;
1309               state=FOUND;
1310             }
1311           }
1312         }
1313         
1314         break;
1315       case TYPE_ANY:
1316         tag=_asn1_get_tag_der(der+counter,&class,&len2);
1317         len4=_asn1_get_length_der(der+counter+len2,&len3);
1318         
1319         if(len4 != -1){
1320           len2+=len4;
1321           if(state==FOUND){
1322             _asn1_length_der(len2+len3,NULL,&len4);
1323             temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1324             if (temp2==NULL){
1325               asn1_delete_structure(structure);
1326               return ASN1_MEM_ALLOC_ERROR;
1327             }
1328             
1329             _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1330             _asn1_set_value(p,temp2,len4);
1331             _asn1_afree(temp2);
1332
1333             if(p==nodeFound) state=EXIT;
1334           }
1335           counter+=len2+len3;
1336         }
1337         else{ /* indefinite length */
1338           /* Check indefinite lenth method in an EXPLICIT TAG */
1339           if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1340             indefinite=1;
1341           else
1342             indefinite=0;
1343
1344           len2=len-counter;
1345           ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1346           if(ris != ASN1_SUCCESS){
1347             asn1_delete_structure(structure);
1348             return ris;
1349           }
1350           
1351           if(state==FOUND){
1352             _asn1_length_der(len2,NULL,&len4);
1353             temp2=(unsigned char *)_asn1_alloca(len2+len4);
1354             if (temp2==NULL){
1355               asn1_delete_structure(structure);
1356               return ASN1_MEM_ALLOC_ERROR;
1357             }
1358         
1359             _asn1_octet_der(der+counter,len2,temp2,&len4);
1360             _asn1_set_value(p,temp2,len4);
1361             _asn1_afree(temp2);
1362
1363             if(p==nodeFound) state=EXIT;
1364           }
1365
1366           counter+=len2;
1367
1368           /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1369              an indefinite length method. */
1370           if(indefinite){
1371             if(!der[counter] && !der[counter+1]){ 
1372               counter+=2;
1373             }
1374             else{
1375               asn1_delete_structure(structure);
1376               return ASN1_DER_ERROR;
1377             }
1378           }
1379         }
1380         move=RIGHT;
1381         break;
1382
1383       default:
1384         move=(move==UP)?RIGHT:DOWN;
1385         break;
1386       }
1387     }
1388
1389     if((p==node && move!=DOWN) || (state==EXIT)) break;
1390
1391     if(move==DOWN){
1392       if(p->down){
1393         p=p->down;
1394
1395         if(state != FOUND){
1396           nameLen-=strlen(p->name)+1;
1397           if(nameLen>0){
1398             if(currentName[0]) strcat(currentName,".");
1399             strcat(currentName,p->name);
1400           }
1401           else{
1402             asn1_delete_structure(structure);
1403             return ASN1_MEM_ERROR;
1404           }
1405           if(!(strcmp(currentName,elementName))){ 
1406             state=FOUND;
1407             nodeFound=p;
1408           }
1409           else if(!memcmp(currentName,elementName,strlen(currentName))) 
1410             state=SAME_BRANCH;
1411           else 
1412             state=OTHER_BRANCH;
1413         }
1414       }
1415       else move=RIGHT;
1416     }
1417
1418     if((move==RIGHT) && !(p->type&CONST_SET)){
1419       if(p->right){
1420         p=p->right;
1421
1422         if(state != FOUND){
1423           dot_p=char_p=currentName;
1424           while((char_p=strchr(char_p,'.'))){
1425             dot_p=char_p++;
1426             dot_p++;
1427           }
1428           
1429           nameLen+=strlen(currentName)-(dot_p-currentName);
1430           *dot_p=0;
1431
1432           nameLen-=strlen(p->name);
1433           if(nameLen>0) strcat(currentName,p->name);
1434           else{
1435             asn1_delete_structure(structure);
1436             return ASN1_MEM_ERROR;
1437           }
1438           
1439           if(!(strcmp(currentName,elementName))){ 
1440             state=FOUND;
1441             nodeFound=p;
1442           }
1443           else if(!memcmp(currentName,elementName,strlen(currentName))) 
1444             state=SAME_BRANCH;
1445           else 
1446             state=OTHER_BRANCH;
1447         }
1448       }
1449       else move=UP;
1450     }
1451
1452     if(move==UP){
1453       p=_asn1_find_up(p);
1454
1455       if(state != FOUND){
1456         dot_p=char_p=currentName;
1457         while((char_p=strchr(char_p,'.'))){
1458           dot_p=char_p++;
1459           dot_p++;
1460         }
1461         
1462         nameLen+=strlen(currentName)-(dot_p-currentName);
1463         *dot_p=0;
1464         
1465         if(!(strcmp(currentName,elementName))){ 
1466         state=FOUND;
1467         nodeFound=p;
1468         }
1469         else if(!memcmp(currentName,elementName,strlen(currentName))) 
1470           state=SAME_BRANCH;
1471         else 
1472           state=OTHER_BRANCH;
1473       }
1474     }
1475   }
1476
1477   _asn1_delete_not_used(*structure);
1478
1479   if(counter > len){
1480     asn1_delete_structure(structure);
1481     return ASN1_DER_ERROR;
1482   }
1483
1484   return ASN1_SUCCESS;
1485 }
1486
1487
1488
1489 /**
1490   * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1491   * @element: pointer to an ASN1 element
1492   * @ider: vector that contains the DER encoding. 
1493   * @len: number of bytes of *der: der[0]..der[len-1]
1494   * @name_element: an element of NAME structure.
1495   * @start: the position of the first byte of NAME_ELEMENT decoding (der[*start]) 
1496   * @end: the position of the last byte of NAME_ELEMENT decoding (der[*end])
1497   * Description:
1498   * 
1499   * Find the start and end point of an element in a DER encoding string. I mean that if you
1500   * have a der encoding and you have already used the function "asn1_der_decoding" to fill a structure, it may
1501   * happen that you want to find the piece of string concerning an element of the structure.
1502   * 
1503   * Example: the sequence "tbsCertificate" inside an X509 certificate.
1504   *
1505   * Returns:
1506   *
1507   *   ASN1_SUCCESS\: DER encoding OK
1508   *
1509   *   ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE EMPTY  or NAME_ELEMENT is not a valid element.
1510   *
1511   *   ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure ELEMENT.
1512   *
1513   **/
1514 asn1_retCode
1515 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
1516                            const char *name_element,int *start, int *end)
1517 {
1518   node_asn *node,*node_to_find,*p,*p2,*p3;
1519   int counter,len2,len3,len4,move,ris;
1520   unsigned char class;
1521   unsigned int tag;
1522   int indefinite;
1523   const unsigned char* der = ider;
1524
1525   node=element;
1526
1527   if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1528
1529   node_to_find=_asn1_find_node(node,name_element);
1530
1531   if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
1532
1533   if(node_to_find==node){
1534     *start=0;
1535     *end=len-1;
1536     return ASN1_SUCCESS;
1537   }
1538
1539   if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
1540
1541   counter=0;
1542   move=DOWN;
1543   p=node;
1544   while(1){
1545     ris=ASN1_SUCCESS;
1546     
1547     if(move!=UP){
1548       if(p->type&CONST_SET){
1549         p2=_asn1_find_up(p);
1550         len2=strtol(p2->value,NULL,10);
1551         if(len2==-1){
1552           if(!der[counter] && !der[counter+1]){
1553             p=p2;
1554             move=UP;
1555             counter+=2;
1556             continue;
1557           }
1558         }
1559         else if(counter==len2){
1560           p=p2;
1561           move=UP;
1562           continue;
1563         }
1564         else if(counter>len2) return ASN1_DER_ERROR;
1565         p2=p2->down;
1566         while(p2){
1567           if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){  /* CONTROLLARE */
1568             if(type_field(p2->type)!=TYPE_CHOICE)
1569               ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1570             else{
1571               p3=p2->down;
1572               ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1573             }
1574             if(ris==ASN1_SUCCESS){
1575               p2->type&=~CONST_NOT_USED;
1576               p=p2;
1577               break;
1578             }
1579           }
1580           p2=p2->right;
1581         }
1582         if(p2==NULL) return ASN1_DER_ERROR;
1583       }
1584
1585       if(p==node_to_find) *start=counter;
1586
1587       if(type_field(p->type)==TYPE_CHOICE){
1588         p=p->down;
1589         ris=_asn1_extract_tag_der(p,der+counter,&len2);
1590         if(p==node_to_find) *start=counter;
1591       }
1592
1593       if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1594       if(ris!=ASN1_SUCCESS){
1595         if(p->type&CONST_OPTION){
1596           p->type|=CONST_NOT_USED;
1597           move=RIGHT;
1598         }
1599         else if(p->type&CONST_DEFAULT) {
1600           move=RIGHT;
1601         }
1602         else {
1603           return ASN1_TAG_ERROR;
1604         }
1605       } 
1606       else counter+=len2;
1607     }
1608
1609     if(ris==ASN1_SUCCESS){
1610       switch(type_field(p->type)){
1611       case TYPE_NULL:
1612         if(der[counter]) return ASN1_DER_ERROR;
1613         counter++;
1614         move=RIGHT;
1615         break;
1616       case TYPE_BOOLEAN:
1617         if(der[counter++]!=1) return ASN1_DER_ERROR;
1618         counter++;
1619         move=RIGHT;
1620         break;
1621       case TYPE_INTEGER: case TYPE_ENUMERATED:
1622         len2=_asn1_get_length_der(der+counter,&len3);
1623         counter+=len3+len2;
1624         move=RIGHT;
1625         break;
1626       case TYPE_OBJECT_ID:
1627         len2=_asn1_get_length_der(der+counter,&len3);
1628         counter+=len2+len3;
1629         move=RIGHT;
1630       break;
1631       case TYPE_TIME:
1632         len2=_asn1_get_length_der(der+counter,&len3);
1633         counter+=len2+len3;
1634         move=RIGHT;
1635         break;
1636       case TYPE_OCTET_STRING:
1637         len3=len-counter;
1638         ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1639         if(ris != ASN1_SUCCESS) return ris; 
1640         counter+=len3;
1641         move=RIGHT;
1642         break;
1643       case TYPE_GENERALSTRING:
1644         len2=_asn1_get_length_der(der+counter,&len3);
1645         counter+=len3+len2;
1646         move=RIGHT;
1647         break;
1648       case TYPE_BIT_STRING:
1649         len2=_asn1_get_length_der(der+counter,&len3);
1650         counter+=len3+len2;
1651         move=RIGHT;
1652         break;
1653       case TYPE_SEQUENCE:  case TYPE_SET:
1654         if(move!=UP){
1655           len3=_asn1_get_length_der(der+counter,&len2);
1656           counter+=len2;
1657           if(len3==0) move=RIGHT;
1658           else move=DOWN; 
1659         }
1660         else{
1661           if(!der[counter] && !der[counter+1]) /* indefinite length method */
1662             counter+=2;
1663           move=RIGHT;
1664         }
1665         break;
1666       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1667         if(move!=UP){
1668           len3=_asn1_get_length_der(der+counter,&len2);
1669           counter+=len2;
1670           if((len3==-1) && !der[counter] && !der[counter+1])
1671             counter+=2;
1672           else if(len3){
1673             p2=p->down;
1674             while((type_field(p2->type)==TYPE_TAG) || 
1675                   (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1676             p=p2;
1677           }
1678         }
1679         else{
1680           if(!der[counter] && !der[counter+1]) /* indefinite length method */
1681             counter+=2;
1682         }
1683         move=RIGHT;
1684         break;
1685       case TYPE_ANY:
1686         tag=_asn1_get_tag_der(der+counter,&class,&len2);
1687         len4=_asn1_get_length_der(der+counter+len2,&len3);
1688         
1689         if(len4 != -1){
1690           counter+=len2+len4+len3;
1691         }
1692         else{ /* indefinite length */
1693           /* Check indefinite lenth method in an EXPLICIT TAG */
1694           if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1695             indefinite=1;
1696           else
1697             indefinite=0;
1698           
1699           len2=len-counter;
1700           ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1701           if(ris != ASN1_SUCCESS)
1702             return ris;
1703           counter+=len2;
1704
1705           /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1706              an indefinite length method. */
1707           if(indefinite){
1708             if(!der[counter] && !der[counter+1])
1709               counter+=2;
1710             else
1711               return ASN1_DER_ERROR;
1712           }
1713         }
1714         move=RIGHT;
1715         break;
1716       default:
1717         move=(move==UP)?RIGHT:DOWN;
1718         break;
1719       }
1720     }
1721
1722     if((p==node_to_find) && (move==RIGHT)){
1723       *end=counter-1;
1724       return ASN1_SUCCESS;
1725     }
1726
1727     if(p==node && move!=DOWN) break;
1728
1729     if(move==DOWN){
1730       if(p->down) p=p->down;
1731       else move=RIGHT;
1732     }
1733     if((move==RIGHT) && !(p->type&CONST_SET)){
1734       if(p->right) p=p->right;
1735       else move=UP;
1736     }
1737     if(move==UP) p=_asn1_find_up(p);
1738   }
1739
1740   return ASN1_ELEMENT_NOT_FOUND;
1741 }
1742
1743
1744 /**
1745   * asn1_expand_any_defined_by - Expand every "ANY DEFINED BY" fields of 
1746   *    structure *ELEMENT with the corresponding type.
1747   * @definitions: ASN1 definitions
1748   * @element: pointer to an ASN1 structure
1749   * Description:
1750   *
1751   * Expands every "ANY DEFINED BY" element of a structure created from
1752   * a DER decoding process (asn1_der_decoding function). The element ANY
1753   * must be defined by an OBJECT IDENTIFIER. The type used to expand
1754   * the element ANY is the first one following the definition of
1755   * the actual value of the OBJECT IDENTIFIER.
1756   *
1757   *
1758   * Returns:
1759   *
1760   *   ASN1_SUCCESS\: substitution OK
1761   *
1762   *   ASN1_ERROR_TYPE_ANY\: some "ANY DEFINED BY" element couldn't be expanded
1763   *   due to a problem in OBJECT_ID -> TYPE association. 
1764   *   other errors\: result of der decoding process. 
1765   **/
1766
1767 asn1_retCode
1768 asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
1769 {
1770   char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1771   asn1_retCode retCode=ASN1_SUCCESS,result;
1772   int len,len2,len3;
1773   ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
1774   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1775
1776   if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1777     return ASN1_ELEMENT_NOT_FOUND;
1778
1779   strcpy(definitionsName,definitions->name);
1780   strcat(definitionsName,".");
1781
1782   p=*element;
1783   while(p){
1784     
1785     switch(type_field(p->type)){
1786     case TYPE_ANY:
1787       if((p->type&CONST_DEFINED_BY) && (p->value)){
1788         /* search the "DEF_BY" element */
1789         p2=p->down;
1790         while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
1791           p2=p2->right;
1792         
1793         if(!p2){
1794           retCode=ASN1_ERROR_TYPE_ANY;
1795           break;
1796         }
1797         
1798         p3=_asn1_find_up(p);
1799         
1800         if(!p3){
1801           retCode=ASN1_ERROR_TYPE_ANY;
1802           break;
1803         }
1804
1805         p3=p3->down;
1806         while(p3){
1807           if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1808           p3=p3->right;
1809         }
1810         
1811         if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1812            (p3->value==NULL)){
1813
1814           p3=_asn1_find_up(p);
1815           p3=_asn1_find_up(p3);
1816
1817           if(!p3){
1818             retCode=ASN1_ERROR_TYPE_ANY;
1819             break;
1820           }
1821
1822           p3=p3->down;
1823  
1824           while(p3){
1825             if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1826             p3=p3->right;
1827           }
1828          
1829           if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1830              (p3->value==NULL)){
1831             retCode=ASN1_ERROR_TYPE_ANY;
1832             break;
1833           }
1834         }
1835         
1836         /* search the OBJECT_ID into definitions */
1837         p2=definitions->down;
1838         while(p2){
1839           if((type_field(p2->type)==TYPE_OBJECT_ID) &&
1840              (p2->type & CONST_ASSIGN)){ 
1841             strcpy(name,definitionsName);
1842             strcat(name,p2->name);
1843             
1844             len=MAX_NAME_SIZE;
1845             result=asn1_read_value(definitions,name,value,&len);
1846  
1847             if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
1848               p2=p2->right; /* pointer to the structure to 
1849                                use for expansion */
1850               while((p2) && (p2->type & CONST_ASSIGN))
1851                 p2=p2->right;
1852               
1853               if(p2){
1854                 strcpy(name,definitionsName);
1855                 strcat(name,p2->name);
1856                 
1857                 result=asn1_create_element(definitions,name,&aux);
1858                 if(result == ASN1_SUCCESS){
1859                   _asn1_set_name(aux,p->name);
1860                   len2=_asn1_get_length_der(p->value,&len3);
1861                   
1862                   result=asn1_der_decoding(&aux,p->value+len3,len2,
1863                                            errorDescription);
1864                   if(result == ASN1_SUCCESS){
1865                     
1866                     _asn1_set_right(aux,p->right);
1867                     _asn1_set_right(p,aux);
1868
1869                     result=asn1_delete_structure(&p);
1870                     if(result == ASN1_SUCCESS){
1871                       p=aux;
1872                       aux=ASN1_TYPE_EMPTY;
1873                       break;
1874                     }
1875                     else{ /* error with asn1_delete_structure */
1876                       asn1_delete_structure(&aux);
1877                       retCode=result;
1878                       break;
1879                     }
1880                   }
1881                   else{/* error with asn1_der_decoding */
1882                     retCode=result;
1883                     break;
1884                   }
1885                 }
1886                 else{/* error with asn1_create_element */
1887                   retCode=result;
1888                   break;
1889                 }
1890               }
1891               else{/* error with the pointer to the structure to exapand */
1892                 retCode=ASN1_ERROR_TYPE_ANY;
1893                 break;
1894               }
1895             }
1896           }           
1897           p2=p2->right;
1898         } /* end while */
1899         
1900         if(!p2){
1901           retCode=ASN1_ERROR_TYPE_ANY;
1902           break;
1903         }
1904         
1905       }
1906       break;
1907     default:
1908       break;
1909     }
1910     
1911
1912     if(p->down){
1913       p=p->down;
1914     }
1915     else if(p==*element){
1916       p=NULL;
1917       break;
1918     }
1919     else if(p->right) p=p->right;
1920     else{
1921       while(1){
1922         p=_asn1_find_up(p);
1923         if(p==*element){
1924           p=NULL;
1925           break;
1926         }
1927         if(p->right){
1928           p=p->right;
1929           break;
1930         }
1931       }
1932     }
1933   }
1934
1935   return retCode;
1936 }
1937
1938
1939
1940 /**
1941   * asn1_expand_octet_string - Expand an "OCTET STRING" fields of 
1942   *    structure *ELEMENT with the corresponding type.
1943   * @definitions: ASN1 definitions
1944   * @element: pointer to an ASN1 structure
1945   * @octetName: name of the OCTECT STRING field to expand.
1946   * @objectName: name of the OBJECT IDENTIFIER field to use to define
1947   *    the type for expansion.
1948   * 
1949   * Description:
1950   *
1951   * Expands an "OCTET STRING" element of a structure created from
1952   * a DER decoding process (asn1_der_decoding function). The type used 
1953   * for expansion is the first one following the definition of
1954   * the actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
1955   *
1956   * Returns:
1957   *
1958   *   ASN1_SUCCESS\: substitution OK
1959   *
1960   *   ASN1_ELEMENT_NOT_FOUND\: OBJECTNAME or OCTETNAME are not correct.
1961   *
1962   *   ASN1_VALUE_NOT_VALID\: wasn't possible to find the type to use
1963   *       for expansion.
1964   *    
1965   *   other errors\: result of der decoding process. 
1966   **/
1967 asn1_retCode
1968 asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
1969                          const char *octetName,const char *objectName)
1970 {
1971   char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1972   asn1_retCode retCode=ASN1_SUCCESS,result;
1973   int len,len2,len3;
1974   ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
1975   ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
1976   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1977
1978   if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1979     return ASN1_ELEMENT_NOT_FOUND;
1980
1981   octetNode=_asn1_find_node(*element,octetName);
1982   if(octetNode==ASN1_TYPE_EMPTY)
1983     return ASN1_ELEMENT_NOT_FOUND;
1984   if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
1985     return ASN1_ELEMENT_NOT_FOUND;
1986   if(octetNode->value==NULL)
1987     return ASN1_VALUE_NOT_FOUND;
1988
1989   objectNode=_asn1_find_node(*element,objectName);
1990   if(objectNode==ASN1_TYPE_EMPTY)
1991     return ASN1_ELEMENT_NOT_FOUND;
1992
1993   if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
1994     return ASN1_ELEMENT_NOT_FOUND;
1995
1996   if(objectNode->value==NULL)
1997     return ASN1_VALUE_NOT_FOUND;
1998
1999         
2000   /* search the OBJECT_ID into definitions */
2001   p2=definitions->down;
2002   while(p2){
2003     if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2004        (p2->type & CONST_ASSIGN)){ 
2005       strcpy(name,definitions->name);
2006       strcat(name,".");
2007       strcat(name,p2->name);
2008     
2009       len = sizeof(value);
2010       result=asn1_read_value(definitions,name,value,&len);
2011
2012       if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
2013
2014         p2=p2->right; /* pointer to the structure to 
2015                          use for expansion */
2016         while((p2) && (p2->type & CONST_ASSIGN))
2017           p2=p2->right;
2018               
2019         if(p2){
2020           strcpy(name,definitions->name);
2021           strcat(name,".");
2022           strcat(name,p2->name);
2023                 
2024           result=asn1_create_element(definitions,name,&aux);
2025           if(result == ASN1_SUCCESS){
2026             _asn1_set_name(aux,octetNode->name);          
2027             len2=_asn1_get_length_der(octetNode->value,&len3);
2028             
2029             result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
2030                                      errorDescription);
2031             if(result == ASN1_SUCCESS){
2032               
2033               _asn1_set_right(aux,octetNode->right);
2034               _asn1_set_right(octetNode,aux);
2035               
2036               result=asn1_delete_structure(&octetNode);
2037               if(result == ASN1_SUCCESS){
2038                 aux=ASN1_TYPE_EMPTY;
2039                 break;
2040               }
2041               else{ /* error with asn1_delete_structure */
2042                 asn1_delete_structure(&aux);
2043                 retCode=result;
2044                 break;
2045               }
2046             }
2047             else{/* error with asn1_der_decoding */
2048               retCode=result;
2049               break;
2050             }
2051           }
2052           else{/* error with asn1_create_element */
2053             retCode=result;
2054             break;
2055           }
2056         }
2057         else{/* error with the pointer to the structure to exapand */
2058           retCode=ASN1_VALUE_NOT_VALID;
2059           break;
2060         }
2061       }
2062     }   
2063     
2064     p2=p2->right;
2065
2066   }
2067
2068   if(!p2) retCode=ASN1_VALUE_NOT_VALID;
2069
2070   return retCode;
2071 }
2072