2aebab392496e2787f0b68b50164d08f85eb11d7
[platform/upstream/libtasn1.git] / lib / der.c
1 /*
2  *      Copyright (C) 2000,2001  Fabio Fiorina
3  *
4  * This file is part of GNUTLS.
5  *
6  * GNUTLS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUTLS 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; 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: x509_der.c                                  */
24 /* Description: Functions to manage DER encoding     */
25 /*****************************************************/
26  
27 #include <defines.h>
28 #include "der.h"
29 #include "asn1.h"
30 #include <gstr.h>
31
32 #define TAG_BOOLEAN          0x01
33 #define TAG_INTEGER          0x02
34 #define TAG_SEQUENCE         0x10
35 #define TAG_SET              0x11
36 #define TAG_OCTET_STRING     0x04
37 #define TAG_BIT_STRING       0x03
38 #define TAG_UTCTime          0x17
39 #define TAG_GENERALIZEDTime  0x18
40 #define TAG_OBJECT_ID        0x06
41 #define TAG_ENUMERATED       0x0A
42 #define TAG_NULL             0x05
43
44
45 char *
46 _asn1_ltostr(long v,char *str)
47 {
48   long d,r;
49   char temp[20];
50   int count,k,start;
51
52   if(v<0){
53     str[0]='-';
54     start=1;
55     v=-v;
56   }
57   else start=0;
58
59   count=0;
60   do{
61     d=v/10;
62     r=v-d*10;
63     temp[start+count]='0'+(char)r;
64     count++;
65     v=d;
66   }while(v);
67
68   for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
69   str[count+start]=0;
70   return str;
71 }
72
73
74 void
75 _asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len)
76 {
77   int k;
78   unsigned char temp[128];
79
80   if(len<128){
81     /* short form */
82     if(ans!=NULL) ans[0]=(unsigned char)len;
83     *ans_len=1;
84   }
85   else{
86     /* Long form */
87     k=0;
88     while(len){
89       temp[k++]=len&0xFF;
90       len=len>>8;
91     }
92     *ans_len=k+1;
93     if(ans!=NULL){
94       ans[0]=((unsigned char)k&0x7F)+128;
95       while(k--) ans[*ans_len-1-k]=temp[k];  
96     }
97   }
98 }
99
100   
101 unsigned long
102 _asn1_get_length_der(unsigned char *der,int  *len)
103 {
104   unsigned long ans;
105   int k,punt;
106
107   if(!(der[0]&128)){
108     /* short form */
109     *len=1;
110     return der[0];
111   }
112   else{
113     /* Long form */
114     k=der[0]&0x7F;
115     punt=1;
116     ans=0;
117     while(punt<=k) ans=ans*256+der[punt++];
118     
119     *len=punt;
120     return ans;
121   }
122 }
123
124
125 void
126 _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
127 {
128   int k;
129   unsigned char temp[128];
130
131   if(tag_value<30){
132     /* short form */
133     ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
134     *ans_len=1;
135   }
136   else{
137     /* Long form */
138     ans[0]=(class&0xE0) + 31;
139     k=0;
140     while(tag_value){
141       temp[k++]=tag_value&0x7F;
142       tag_value=tag_value>>7;
143     }
144     *ans_len=k+1;
145     while(k--) ans[*ans_len-1-k]=temp[k]+128;
146     ans[*ans_len-1]-=128;  
147   }
148 }
149
150
151 unsigned int
152 _asn1_get_tag_der(unsigned char *der,unsigned char *class,int  *len)
153 {
154   int punt,ris;
155
156   *class=der[0]&0xE0;
157   if((der[0]&0x1F)!=0x1F){
158     /* short form */
159     *len=1;
160     ris=der[0]&0x1F;
161   }
162   else{
163     /* Long form */
164     punt=1;
165     ris=0;
166     while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F);
167     ris=ris*128+(der[punt++]&0x7F);   
168     *len=punt;
169   }
170   return ris;
171 }
172
173
174 void
175 _asn1_octet_der(unsigned char *str,int str_len,unsigned char *der,int *der_len)
176 {
177   int len_len;
178
179   if(der==NULL) return;
180   _asn1_length_der(str_len,der,&len_len);
181   memcpy(der+len_len,str,str_len);
182   *der_len=str_len+len_len;
183 }
184
185
186 int
187 _asn1_get_octet_der(unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
188 {
189   int len_len;
190
191   if(str==NULL) return ASN_OK;
192   *str_len=_asn1_get_length_der(der,&len_len);
193   if ( str_size >= *str_len)
194           memcpy(str,der+len_len,*str_len);
195   else {
196         return ASN_MEM_ERROR;
197   }
198   *der_len=*str_len+len_len;
199   
200   return ASN_OK;
201 }
202
203
204 void
205 _asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
206 {
207   int len_len;
208
209   if(der==NULL) return;
210   _asn1_length_der(strlen(str),der,&len_len);
211   memcpy(der+len_len,str,strlen(str));
212   *der_len=len_len+strlen(str);
213 }
214
215
216 /*
217 void
218 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
219 {
220   int len_len,str_len;
221   char temp[20];
222
223   if(str==NULL) return;
224   str_len=_asn1_get_length_der(der,&len_len);
225   memcpy(temp,der+len_len,str_len);
226   *der_len=str_len+len_len;
227   switch(str_len){
228   case 11:
229     temp[10]=0;
230     strcat(temp,"00+0000");
231     break;
232   case 13:
233     temp[12]=0;
234     strcat(temp,"+0000");
235     break;
236   case 15:
237     temp[15]=0;
238     memmove(temp+12,temp+10,6);
239     temp[10]=temp[11]='0';
240     break;
241   case 17:
242     temp[17]=0;
243     break;
244   default:
245     return;
246   }
247   strcpy(str,temp);
248 }
249 */
250
251
252 void
253 _asn1_get_time_der(unsigned char *der,int *der_len,unsigned char *str)
254 {
255   int len_len,str_len;
256
257   if(str==NULL) return;
258   str_len=_asn1_get_length_der(der,&len_len);
259   memcpy(str,der+len_len,str_len);
260   str[str_len]=0;
261   *der_len=str_len+len_len;
262 }
263
264 void
265 _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
266 {
267   int len_len,counter,k,first;
268   char temp[128],*n_end,*n_start;
269   unsigned char bit7;
270   unsigned long val,val1=0;
271
272   if(der==NULL) return;
273
274   _asn1_str_cpy(temp, sizeof(temp), str);
275   _asn1_str_cat(temp, sizeof(temp), " ");
276
277   counter=0;
278   n_start=temp;
279   while((n_end=strchr(n_start,' '))){
280     *n_end=0;
281     val=strtoul(n_start,NULL,10);
282     counter++;
283
284     if(counter==1) val1=val;
285     else if(counter==2){
286       der[0]=40*val1+val;
287       *der_len=1;
288     }
289     else{
290       first=0;
291       for(k=4;k>=0;k--){
292         bit7=(val>>(k*7))&0x7F;
293         if(bit7 || first || !k){
294           if(k) bit7|=0x80;
295           der[*der_len]=bit7;
296           (*der_len)++;
297           first=1;
298         }
299       }
300
301     }
302     n_start=n_end+1;
303   }
304
305   _asn1_length_der(*der_len,NULL,&len_len);
306   memmove(der+len_len,der,*der_len);
307   _asn1_length_der(*der_len,der,&len_len);
308   *der_len+=len_len;
309 }
310
311
312 void
313 _asn1_get_objectid_der(unsigned char *der,int *der_len,unsigned char *str, int str_size)
314 {
315   int len_len,len,k;
316   char temp[20];
317   unsigned long val,val1;
318
319   if(str==NULL) return;
320   len=_asn1_get_length_der(der,&len_len);
321   
322   val1=der[len_len]/40;
323   val=der[len_len]-val1*40;
324
325   _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
326   _asn1_str_cat(str, str_size, " ");
327   _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
328
329   val=0;
330   for(k=1;k<len;k++){
331     val=val<<7;
332     val|=der[len_len+k]&0x7F;
333     if(!(der[len_len+k]&0x80)){
334       _asn1_str_cat(str, str_size," ");
335       _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
336       val=0;
337     }
338   }
339   *der_len=len+len_len;
340 }
341
342
343
344 char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
345
346 void
347 _asn1_bit_der(unsigned char *str,int bit_len,unsigned char *der,int *der_len)
348 {
349   int len_len,len_byte,len_pad;
350
351   if(der==NULL) return;
352   len_byte=bit_len>>3;
353   len_pad=8-(bit_len&7);
354   if(len_pad==8) len_pad=0;
355   else len_byte++;
356   _asn1_length_der(len_byte+1,der,&len_len);
357   der[len_len]=len_pad;
358   memcpy(der+len_len+1,str,len_byte);
359   der[len_len+len_byte]&=bit_mask[len_pad];
360   *der_len=len_byte+len_len+1;
361 }
362
363
364 int
365 _asn1_get_bit_der(unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
366 {
367   int len_len,len_byte;
368
369   if(str==NULL) return ASN_OK;
370   len_byte=_asn1_get_length_der(der,&len_len)-1;
371   
372   if (str_size >= len_byte)
373         memcpy(str,der+len_len+1,len_byte);
374   else {
375         return ASN_MEM_ERROR;
376   }
377   *bit_len=len_byte*8-der[len_len];
378   *der_len=len_byte+len_len+1;
379
380   return ASN_OK;
381 }
382
383
384
385
386 #define UP    1
387 #define DOWN  2
388 #define RIGHT 3
389
390
391 void
392 _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter)
393 {
394   node_asn *p;
395   int is_tag_implicit,len2,len3;
396   unsigned char temp[10];
397   
398   is_tag_implicit=0;
399
400   if(node->type&CONST_TAG){
401     p=node->down;
402     while(p){
403       if(type_field(p->type)==TYPE_TAG){
404         if(p->type&CONST_EXPLICIT){
405           len2=strtol(p->name,NULL,10);
406           _asn1_set_name(p,NULL);
407           _asn1_length_der(*counter-len2,temp,&len3);
408           memmove(der+len2+len3,der+len2,*counter-len2);
409           memcpy(der+len2,temp,len3);
410           *counter+=len3;         
411           is_tag_implicit=0;
412         }
413         else{  /* CONST_IMPLICIT */
414           if(!is_tag_implicit){
415             is_tag_implicit=1;
416           }
417         }
418       }
419       p=p->right;
420     }
421   }
422 }
423
424
425 int
426 _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter)
427 {
428   node_asn *p;
429   int tag_len,is_tag_implicit;
430   unsigned char class,class_implicit=0,temp[10];
431   unsigned long tag_implicit=0;
432    
433   is_tag_implicit=0;
434
435   if(node->type&CONST_TAG){
436     p=node->down;
437     while(p){
438       if(type_field(p->type)==TYPE_TAG){
439         if(p->type&CONST_APPLICATION) class=APPLICATION;
440         else if(p->type&CONST_UNIVERSAL) class=UNIVERSAL;
441         else if(p->type&CONST_PRIVATE) class=PRIVATE;
442         else class=CONTEXT_SPECIFIC;
443         
444         if(p->type&CONST_EXPLICIT){
445           if(is_tag_implicit)
446             _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len);
447           else
448             _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),der+*counter,&tag_len);
449           *counter+=tag_len;
450           _asn1_ltostr(*counter,temp);
451           _asn1_set_name(p,temp);
452
453           is_tag_implicit=0;
454         }
455         else{  /* CONST_IMPLICIT */
456           if(!is_tag_implicit){
457             if((type_field(node->type)==TYPE_SEQUENCE) || 
458                (type_field(node->type)==TYPE_SEQUENCE_OF) ||
459                (type_field(node->type)==TYPE_SET) ||
460                (type_field(node->type)==TYPE_SET_OF)) class|=STRUCTURED;
461             class_implicit=class;
462             tag_implicit=strtoul(p->value,NULL,10);
463             is_tag_implicit=1;
464           }
465         }
466       }
467       p=p->right;
468     }
469   }
470   
471   if(is_tag_implicit){
472     _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len);
473   }
474   else{
475     switch(type_field(node->type)){
476     case TYPE_NULL:
477       _asn1_tag_der(UNIVERSAL,TAG_NULL,der+*counter,&tag_len);
478       break;
479     case TYPE_BOOLEAN:
480       _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,der+*counter,&tag_len);
481       break;
482     case TYPE_INTEGER:
483       _asn1_tag_der(UNIVERSAL,TAG_INTEGER,der+*counter,&tag_len);
484       break;
485     case TYPE_ENUMERATED:
486       _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,der+*counter,&tag_len);
487       break;
488     case TYPE_OBJECT_ID:
489       _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,der+*counter,&tag_len);
490       break;
491     case TYPE_TIME:
492       if(node->type&CONST_UTC){
493         _asn1_tag_der(UNIVERSAL,TAG_UTCTime,der+*counter,&tag_len);
494       }
495       else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,der+*counter,&tag_len);
496       break;
497     case TYPE_OCTET_STRING:
498       _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,der+*counter,&tag_len);
499       break;
500     case TYPE_BIT_STRING:
501       _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,der+*counter,&tag_len);
502       break;
503     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
504       _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,der+*counter,&tag_len);
505       break;
506     case TYPE_SET: case TYPE_SET_OF:
507       _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,der+*counter,&tag_len);
508       break;
509     case TYPE_TAG:
510       tag_len=0;
511       break;
512     case TYPE_CHOICE:
513       tag_len=0;
514       break;
515     case TYPE_ANY:
516       tag_len=0;
517       break;
518     default:
519       return ASN_GENERIC_ERROR;
520     }
521   }
522   
523   *counter+=tag_len;
524
525   return ASN_OK;
526 }
527
528
529 int
530 _asn1_extract_tag_der(node_asn *node,unsigned char *der,int *der_len)
531 {
532   node_asn *p;
533   int counter,len2,len3,is_tag_implicit;
534   unsigned long tag,tag_implicit=0;
535   unsigned char class,class2,class_implicit=0;
536
537   counter=is_tag_implicit=0;
538   if(node->type&CONST_TAG){
539     p=node->down;
540     while(p){
541       if(type_field(p->type)==TYPE_TAG){
542         if(p->type&CONST_APPLICATION) class2=APPLICATION;
543         else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
544         else if(p->type&CONST_PRIVATE) class2=PRIVATE;
545         else class2=CONTEXT_SPECIFIC;
546         
547         if(p->type&CONST_EXPLICIT){
548           tag=_asn1_get_tag_der(der+counter,&class,&len2);
549           counter+=len2;
550           len3=_asn1_get_length_der(der+counter,&len2);
551           counter+=len2;
552           if(!is_tag_implicit){
553             if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
554               return ASN_TAG_ERROR;
555           }
556           else{    /* TAG_IMPLICIT */
557             if((class!=class_implicit) || (tag!=tag_implicit))
558               return ASN_TAG_ERROR;
559           }
560
561           is_tag_implicit=0;
562         }
563         else{    /* TAG_IMPLICIT */
564           if(!is_tag_implicit){
565             if((type_field(node->type)==TYPE_SEQUENCE) ||
566                (type_field(node->type)==TYPE_SEQUENCE_OF) ||
567                (type_field(node->type)==TYPE_SET) ||
568                (type_field(node->type)==TYPE_SET_OF))  class2|=STRUCTURED;
569             class_implicit=class2;
570             tag_implicit=strtoul(p->value,NULL,10);
571             is_tag_implicit=1;
572           }
573         }
574       }
575       p=p->right;
576     }
577   }
578
579   if(is_tag_implicit){
580     tag=_asn1_get_tag_der(der+counter,&class,&len2);
581     if((class!=class_implicit) || (tag!=tag_implicit)) return ASN_TAG_ERROR;
582   }
583   else{
584     if(type_field(node->type)==TYPE_TAG){
585       counter=0;
586       *der_len=counter;
587       return ASN_OK;
588     }
589
590     tag=_asn1_get_tag_der(der+counter,&class,&len2);
591     switch(type_field(node->type)){
592     case TYPE_NULL:
593       if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN_DER_ERROR;
594        break;
595     case TYPE_BOOLEAN:
596       if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN_DER_ERROR;
597        break;
598     case TYPE_INTEGER:
599       if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN_DER_ERROR;
600        break;
601     case TYPE_ENUMERATED:
602       if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN_DER_ERROR;
603        break;
604     case TYPE_OBJECT_ID:
605       if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN_DER_ERROR;
606        break;
607     case TYPE_TIME:
608       if(node->type&CONST_UTC){
609           if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN_DER_ERROR;
610       }
611       else{
612         if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime)) 
613           return ASN_DER_ERROR;
614       }
615       break;
616     case TYPE_OCTET_STRING:
617       if((class!=UNIVERSAL) || (tag!=TAG_OCTET_STRING)) return ASN_DER_ERROR;
618       break;
619     case TYPE_BIT_STRING:
620       if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN_DER_ERROR;
621       break;
622     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
623       if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE)) 
624         return ASN_DER_ERROR;
625       break;
626     case TYPE_SET: case TYPE_SET_OF:
627       if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET)) 
628         return ASN_DER_ERROR;
629       break;
630     case TYPE_ANY:
631       counter-=len2;
632       break;
633     default:
634       return ASN_DER_ERROR;
635       break;
636     }
637   }
638
639   counter+=len2;
640   *der_len=counter;
641   return ASN_OK;
642 }
643
644
645 void
646 _asn1_ordering_set(unsigned char *der,node_asn *node)
647 {
648   struct vet{
649     int end;
650     unsigned long value;
651     struct vet *next,*prev;
652   };
653
654   int counter,len,len2;
655   struct vet *first,*last,*p_vet,*p2_vet;
656   node_asn *p;
657   unsigned char class,*temp;
658   unsigned long tag;
659
660   counter=0;
661
662   if(type_field(node->type)!=TYPE_SET) return;
663
664   p=node->down;
665   while((type_field(p->type)==TYPE_TAG)  || (type_field(p->type)==TYPE_SIZE)) p=p->right;
666
667   if((p==NULL) || (p->right==NULL)) return;
668
669   first=last=NULL;
670   while(p){
671     p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
672     if (p_vet==NULL) return;
673     
674     p_vet->next=NULL;
675     p_vet->prev=last;
676     if(first==NULL) first=p_vet;
677     else last->next=p_vet;
678     last=p_vet;
679
680     /* tag value calculation */
681     tag=_asn1_get_tag_der(der+counter,&class,&len2);
682     p_vet->value=(class<<24)|tag;
683     counter+=len2;
684
685     /* extraction  and length */
686     len2=_asn1_get_length_der(der+counter,&len);
687     counter+=len+len2;
688
689     p_vet->end=counter;
690     p=p->right;
691   }
692
693   p_vet=first;
694
695   while(p_vet){
696     p2_vet=p_vet->next;
697     counter=0;
698     while(p2_vet){
699       if(p_vet->value>p2_vet->value){
700         /* change position */
701         temp=(unsigned char *)_asn1_alloca( p_vet->end-counter);
702         if (temp==NULL) return;
703         
704         memcpy(temp,der+counter,p_vet->end-counter);
705         memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
706         memcpy(der+p_vet->end,temp,p_vet->end-counter);
707         _asn1_afree(temp);
708         
709         tag=p_vet->value;
710         p_vet->value=p2_vet->value;
711         p2_vet->value=tag;
712         
713         p_vet->end=counter+(p2_vet->end-p_vet->end);
714       }
715       counter=p_vet->end;
716       
717       p2_vet=p2_vet->next;
718       p_vet=p_vet->next;
719     }
720
721     if(p_vet!=first) p_vet->prev->next=NULL;
722     else first=NULL;
723     _asn1_afree(p_vet);
724     p_vet=first;
725   }
726 }
727
728
729 void
730 _asn1_ordering_set_of(unsigned char *der,node_asn *node)
731 {
732   struct vet{
733     int end;
734     struct vet *next,*prev;
735   };
736
737   int counter,len,len2,change;
738   struct vet *first,*last,*p_vet,*p2_vet;
739   node_asn *p;
740   unsigned char *temp,class;
741   unsigned long k,max;
742
743   counter=0;
744
745   if(type_field(node->type)!=TYPE_SET_OF) return;
746
747   p=node->down;
748   while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
749   p=p->right;
750
751   if((p==NULL) || (p->right==NULL)) return;
752
753   first=last=NULL;
754   while(p){
755     p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
756     if (p_vet==NULL) return;
757     
758     p_vet->next=NULL;
759     p_vet->prev=last;
760     if(first==NULL) first=p_vet;
761     else last->next=p_vet;
762     last=p_vet;
763
764     /* extraction of tag and length */
765     _asn1_get_tag_der(der+counter,&class,&len);
766     counter+=len;
767     len2=_asn1_get_length_der(der+counter,&len);
768     counter+=len+len2;
769
770     p_vet->end=counter;
771     p=p->right;
772   }
773
774   p_vet=first;
775
776   while(p_vet){
777     p2_vet=p_vet->next;
778     counter=0;
779     while(p2_vet){
780       if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
781         max=p_vet->end-counter;
782       else
783         max=p2_vet->end-p_vet->end;
784
785       change=-1;
786       for(k=0;k<max;k++) 
787         if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
788         else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
789
790       if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
791         change=1;
792
793       if(change==1){
794         /* change position */
795         temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
796         if (temp==NULL) return;
797         
798         memcpy(temp,der+counter,p_vet->end-counter);
799         memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
800         memcpy(der+p_vet->end,temp,p_vet->end-counter);
801         _asn1_afree(temp);
802         
803         p_vet->end=counter+(p2_vet->end-p_vet->end);
804       }
805       counter=p_vet->end;
806       
807       p2_vet=p2_vet->next;
808       p_vet=p_vet->next;
809     }
810
811     if(p_vet!=first) p_vet->prev->next=NULL;
812     else first=NULL;
813     _asn1_afree(p_vet);
814     p_vet=first;
815   }
816 }
817
818 /**
819   * asn1_create_der - Creates the DER encoding for the NAME structure
820   * @root: pointer to a structure
821   * @name: the name of the structure you want to encode (it must be inside *POINTER).
822   * @der: vector that will contain the DER encoding. DER must be a pointer to memory cells already allocated.
823   * @len: number of bytes of *der: der[0]..der[len-1]
824   * Description:
825   *
826   * Creates the DER encoding for the NAME structure (inside *POINTER structure).
827   * 
828   * Returns:
829   *
830   *   ASN_OK\: DER encoding OK
831   *
832   *   ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
833   *
834   *   ASN_VALUE_NOT_FOUND\: there is an element without a value.
835   **/
836 int 
837 asn1_create_der(node_asn *root,char *name,unsigned char *der,int *len)
838 {
839   node_asn *node,*p;
840   char temp[20];
841   int counter,counter_old,len2,len3,move,ris;
842
843   node=_asn1_find_node(root,name);
844   if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
845
846   counter=0;
847   move=DOWN;
848   p=node;
849   while(1){
850     
851     counter_old=counter;
852     if(move!=UP) ris=_asn1_insert_tag_der(p,der,&counter);
853
854     switch(type_field(p->type)){
855     case TYPE_NULL:
856       der[counter]=0;
857       counter++;
858       move=RIGHT;
859       break;
860     case TYPE_BOOLEAN:
861       if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
862       else{
863         der[counter++]=1;
864         if(p->value[0]=='F') der[counter++]=0;
865         else der[counter++]=0xFF;
866       }
867       move=RIGHT;
868       break;
869     case TYPE_INTEGER: case TYPE_ENUMERATED:
870       if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
871       else{
872         len2=_asn1_get_length_der(p->value,&len3);
873         memcpy(der+counter,p->value,len3+len2);
874         counter+=len3+len2;
875       }
876       move=RIGHT;
877       break;
878     case TYPE_OBJECT_ID:
879       _asn1_objectid_der(p->value,der+counter,&len2);
880       counter+=len2;
881       move=RIGHT;
882       break;
883     case TYPE_TIME:
884       _asn1_time_der(p->value,der+counter,&len2);
885       counter+=len2;
886       move=RIGHT;
887       break;
888     case TYPE_OCTET_STRING:
889       len2=_asn1_get_length_der(p->value,&len3);
890       memcpy(der+counter,p->value,len3+len2);
891       counter+=len3+len2;
892       move=RIGHT;
893       break;
894     case TYPE_BIT_STRING:
895       len2=_asn1_get_length_der(p->value,&len3);
896       memcpy(der+counter,p->value,len3+len2);
897       counter+=len3+len2;
898       move=RIGHT;
899       break;
900     case TYPE_SEQUENCE: case TYPE_SET: 
901       if(move!=UP){
902         _asn1_ltostr(counter,temp);
903         _asn1_set_value(p,temp,strlen(temp)+1);
904         move=DOWN;
905       }
906       else{   /* move==UP */
907         len2=strtol(p->value,NULL,10);
908         _asn1_set_value(p,NULL,0);
909         if(type_field(p->type)==TYPE_SET) _asn1_ordering_set(der+len2,p);
910         _asn1_length_der(counter-len2,temp,&len3);
911         memmove(der+len2+len3,der+len2,counter-len2);
912         memcpy(der+len2,temp,len3);
913         counter+=len3;
914         move=RIGHT;
915       }
916       break;
917     case TYPE_SEQUENCE_OF: case TYPE_SET_OF: 
918       if(move!=UP){
919         _asn1_ltostr(counter,temp);
920         _asn1_set_value(p,temp,strlen(temp)+1);
921         p=p->down;
922         while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
923         if(p->right){
924           p=p->right;
925           move=RIGHT;
926           continue;
927         }
928         else p=_asn1_find_up(p);
929         move=UP;
930       }
931       if(move==UP){
932         len2=strtol(p->value,NULL,10);
933         _asn1_set_value(p,NULL,0);
934         if(type_field(p->type)==TYPE_SET_OF) _asn1_ordering_set_of(der+len2,p);
935         _asn1_length_der(counter-len2,temp,&len3);
936         memmove(der+len2+len3,der+len2,counter-len2);
937         memcpy(der+len2,temp,len3);
938         counter+=len3;
939         move=RIGHT;
940       }
941       break;
942     case TYPE_ANY:
943       len2=_asn1_get_length_der(p->value,&len3);
944       memcpy(der+counter,p->value+len3,len2);
945       counter+=len2;
946       move=RIGHT;
947       break;
948     default:
949        move=(move==UP)?RIGHT:DOWN;
950       break;
951     }
952
953     if((move!=DOWN) && (counter!=counter_old))
954       _asn1_complete_explicit_tag(p,der,&counter);
955
956     if(p==node && move!=DOWN) break;
957
958     if(move==DOWN){
959       if(p->down) p=p->down;
960       else move=RIGHT;
961     }
962     if(move==RIGHT){
963       if(p->right) p=p->right;
964       else move=UP;
965     }
966    if(move==UP) p=_asn1_find_up(p);
967   }
968
969   *len=counter;
970   return ASN_OK;
971 }
972
973 /**
974   * asn1_get_der - Fill the structure *POINTER with values of a DER encoding string.
975   * @root: pointer to a structure
976   * @der: vector that contains the DER encoding. 
977   * @len: number of bytes of *der: der[0]..der[len-1]
978   * Description:
979   *
980   * Fill the structure *POINTER with values of a DER encoding string. The sructure must just be
981   * created with function 'create_stucture'.
982   * 
983   * Returns:
984   *
985   *   ASN_OK\: DER encoding OK
986   *
987   *   ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
988   *
989   *   ASN_TAG_ERROR,ASN_DER_ERROR\: the der encoding doesn't match the structure NAME.  
990   **/
991
992 int 
993 asn1_get_der(node_asn *root,unsigned char *der,int len)
994 {
995   node_asn *node,*p,*p2,*p3;
996   char temp[128];
997   int counter,len2,len3,len4,move,ris;
998   unsigned char class,*temp2;
999   unsigned int tag;
1000
1001   node=root;
1002   if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
1003
1004   if(node->type&CONST_OPTION) return ASN_GENERIC_ERROR;
1005
1006   counter=0;
1007   move=DOWN;
1008   p=node;
1009   while(1){
1010     ris=ASN_OK;
1011
1012     if(move!=UP){
1013       if(p->type&CONST_SET){
1014         p2=_asn1_find_up(p);
1015         len2=strtol(p2->value,NULL,10);
1016         if(counter==len2){
1017           p=p2;
1018           move=UP;
1019           continue;
1020         }
1021         else if(counter>len2) return ASN_DER_ERROR;
1022         p2=p2->down;
1023         while(p2){
1024           if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){  /* CONTROLLARE */
1025             if(type_field(p2->type)!=TYPE_CHOICE)
1026               ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1027             else{
1028               p3=p2->down;
1029               while(p3){
1030                 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1031                 if(ris==ASN_OK) break;
1032                 //if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
1033                 p3=p3->right;
1034               }
1035             }
1036             if(ris==ASN_OK){
1037               p2->type&=~CONST_NOT_USED;
1038               p=p2;
1039               break;
1040             }
1041             //else if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
1042           }
1043           p2=p2->right;
1044         }
1045         if(p2==NULL) return ASN_DER_ERROR;
1046       }
1047
1048       if(type_field(p->type)==TYPE_CHOICE){
1049         while(p->down){
1050           ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
1051           if(ris==ASN_OK){
1052             while(p->down->right) asn1_delete_structure(p->down->right);
1053             break;
1054           }
1055           else if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
1056           else asn1_delete_structure(p->down);
1057         }
1058         if(p->down==NULL) return ASN_DER_ERROR;
1059         p=p->down;
1060       }
1061
1062       if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1063         p2=_asn1_find_up(p);
1064         len2=strtol(p2->value,NULL,10);
1065         if(counter>=len2) ris=ASN_TAG_ERROR;
1066       }
1067
1068       if(ris==ASN_OK) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1069       if(ris!=ASN_OK){
1070         //if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
1071         if(p->type&CONST_OPTION){
1072           p->type|=CONST_NOT_USED;
1073           move=RIGHT;
1074         }
1075         else if(p->type&CONST_DEFAULT) {
1076           _asn1_set_value(p,NULL,0);
1077           move=RIGHT;
1078         }
1079         else {
1080           //return (type_field(p->type)!=TYPE_ANY)?ASN_TAG_ERROR:ASN_ERROR_TYPE_ANY;
1081           return ASN_TAG_ERROR;
1082         }
1083       } 
1084       else counter+=len2;
1085     }
1086
1087     if(ris==ASN_OK){
1088       switch(type_field(p->type)){
1089       case TYPE_NULL:
1090         if(der[counter]) return ASN_DER_ERROR;
1091         counter++;
1092         move=RIGHT;
1093         break;
1094       case TYPE_BOOLEAN:
1095         if(der[counter++]!=1) return ASN_DER_ERROR;
1096         if(der[counter++]==0) _asn1_set_value(p,"F",1);
1097         else _asn1_set_value(p,"T",1);
1098         move=RIGHT;
1099         break;
1100       case TYPE_INTEGER: case TYPE_ENUMERATED:
1101         len2=_asn1_get_length_der(der+counter,&len3);
1102         _asn1_set_value(p,der+counter,len3+len2);
1103         counter+=len3+len2;
1104         move=RIGHT;
1105         break;
1106       case TYPE_OBJECT_ID:
1107         _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
1108         _asn1_set_value(p,temp,strlen(temp)+1);
1109         counter+=len2;
1110         move=RIGHT;
1111       break;
1112       case TYPE_TIME:
1113         _asn1_get_time_der(der+counter,&len2,temp);
1114         _asn1_set_value(p,temp,strlen(temp)+1);
1115         counter+=len2;
1116         move=RIGHT;
1117         break;
1118       case TYPE_OCTET_STRING:
1119         len2=_asn1_get_length_der(der+counter,&len3);
1120         _asn1_set_value(p,der+counter,len3+len2);
1121         counter+=len3+len2;
1122         move=RIGHT;
1123         break;
1124       case TYPE_BIT_STRING:
1125         len2=_asn1_get_length_der(der+counter,&len3);
1126         _asn1_set_value(p,der+counter,len3+len2);
1127         counter+=len3+len2;
1128         move=RIGHT;
1129         break;
1130       case TYPE_SEQUENCE:  case TYPE_SET:;
1131         if(move==UP){
1132           len2=strtol(p->value,NULL,10);
1133           _asn1_set_value(p,NULL,0);
1134           if(len2!=counter) return ASN_DER_ERROR;
1135           move=RIGHT;
1136         }
1137         else{   /* move==DOWN || move==RIGHT */
1138           len3=_asn1_get_length_der(der+counter,&len2);
1139           counter+=len2;
1140           _asn1_ltostr(counter+len3,temp);
1141           _asn1_set_value(p,temp,strlen(temp)+1);
1142           move=DOWN; 
1143         }
1144         break;
1145       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1146         if(move==UP){
1147           len2=strtol(p->value,NULL,10);
1148           if(len2>counter){
1149             _asn1_append_sequence_set(p);
1150             p=p->down;
1151             while(p->right) p=p->right;
1152             move=RIGHT;
1153             continue;
1154           }
1155           _asn1_set_value(p,NULL,0);
1156           if(len2!=counter) return ASN_DER_ERROR;
1157         }
1158         else{   /* move==DOWN || move==RIGHT */
1159           len3=_asn1_get_length_der(der+counter,&len2);
1160           counter+=len2;
1161           if(len3){
1162             _asn1_ltostr(counter+len3,temp);
1163             _asn1_set_value(p,temp,strlen(temp)+1);
1164             p2=p->down;
1165             while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1166             if(p2->right==NULL) _asn1_append_sequence_set(p);
1167             p=p2;
1168           }
1169         }
1170         move=RIGHT;
1171         break;
1172       case TYPE_ANY:
1173         tag=_asn1_get_tag_der(der+counter,&class,&len2);
1174         len2+=_asn1_get_length_der(der+counter+len2,&len3);
1175         _asn1_length_der(len2+len3,NULL,&len4);
1176         temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1177         if (temp2==NULL) return ASN_MEM_ERROR;
1178         
1179         _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1180         _asn1_set_value(p,temp2,len4);
1181         _asn1_afree(temp2);
1182         counter+=len2+len3;
1183         move=RIGHT;
1184         break;
1185       default:
1186         move=(move==UP)?RIGHT:DOWN;
1187         break;
1188       }
1189     }
1190
1191     if(p==node && move!=DOWN) break;
1192
1193     if(move==DOWN){
1194       if(p->down) p=p->down;
1195       else move=RIGHT;
1196     }
1197     if((move==RIGHT) && !(p->type&CONST_SET)){
1198       if(p->right) p=p->right;
1199       else move=UP;
1200     }
1201     if(move==UP) p=_asn1_find_up(p);
1202   }
1203
1204   _asn1_delete_not_used(root);
1205
1206   return (counter==len)?ASN_OK:ASN_DER_ERROR;
1207 }
1208
1209
1210 /**
1211   * asn1_get_start_end_der - Find the start and end point of an element in a DER encoding string.
1212   * @root: pointer to a structure
1213   * @der: vector that contains the DER encoding. 
1214   * @len: number of bytes of *der: der[0]..der[len-1]
1215   * @name_element: an element of NAME structure.
1216   * @start: the position of the first byte of NAME_ELEMENT decoding (der[*start]) 
1217   * @end: the position of the last byte of NAME_ELEMENT decoding (der[*end])
1218   * Description:
1219   * 
1220   * Find the start and end point of an element in a DER encoding string. I mean that if you
1221   * have a der encoding and you have already used the function "get_der" to fill a structure, it may
1222   * happen that you want to find the piece of string concerning an element of the structure.
1223   * 
1224   * Example: the sequence "tbsCertificate" inside an X509 certificate.
1225   *
1226   * Returns:
1227   *
1228   *   ASN_OK\: DER encoding OK
1229   *
1230   *   ASN_ELEMENT_NOT_FOUND\: NAME or NAME_ELEMENT is not a valid element.
1231   *
1232   *   ASN_TAG_ERROR,ASN_DER_ERROR\: the der encoding doesn't match the structure NAME.
1233   *
1234   **/
1235 int 
1236 asn1_get_start_end_der(node_asn *root,unsigned char *der,int len,char *name_element,int *start, int *end)
1237 {
1238   node_asn *node,*node_to_find,*p,*p2,*p3;
1239   int counter,len2,len3,move,ris;
1240   unsigned char class;
1241   unsigned int tag;
1242
1243   node=root;
1244   node_to_find=_asn1_find_node(root,name_element);
1245
1246   if(node_to_find==NULL) return ASN_ELEMENT_NOT_FOUND;
1247
1248   if(node_to_find==node){
1249     *start=0;
1250     *end=len-1;
1251     return ASN_OK;
1252   }
1253
1254   if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
1255
1256   if(node->type&CONST_OPTION) return ASN_GENERIC_ERROR;
1257
1258   counter=0;
1259   move=DOWN;
1260   p=node;
1261   while(1){
1262     ris=ASN_OK;
1263     
1264     if(move!=UP){
1265       if(p->type&CONST_SET){
1266         p2=_asn1_find_up(p);
1267         len2=strtol(p2->value,NULL,10);
1268         if(counter==len2){
1269           p=p2;
1270           move=UP;
1271           continue;
1272         }
1273         else if(counter>len2) return ASN_DER_ERROR;
1274         p2=p2->down;
1275         while(p2){
1276           if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){  /* CONTROLLARE */
1277             if(type_field(p2->type)!=TYPE_CHOICE)
1278               ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1279             else{
1280               p3=p2->down;
1281               ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1282             }
1283             if(ris==ASN_OK){
1284               p2->type&=~CONST_NOT_USED;
1285               p=p2;
1286               break;
1287             }
1288           }
1289           p2=p2->right;
1290         }
1291         if(p2==NULL) return ASN_DER_ERROR;
1292       }
1293
1294       if(p==node_to_find) *start=counter;
1295
1296       if(type_field(p->type)==TYPE_CHOICE){
1297         p=p->down;
1298         ris=_asn1_extract_tag_der(p,der+counter,&len2);
1299         if(p==node_to_find) *start=counter;
1300       }
1301
1302       if(ris==ASN_OK) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1303       if(ris!=ASN_OK){
1304         if(p->type&CONST_OPTION){
1305           p->type|=CONST_NOT_USED;
1306           move=RIGHT;
1307         }
1308         else if(p->type&CONST_DEFAULT) {
1309           move=RIGHT;
1310         }
1311         else {
1312           return ASN_TAG_ERROR;
1313         }
1314       } 
1315       else counter+=len2;
1316     }
1317
1318     if(ris==ASN_OK){
1319       switch(type_field(p->type)){
1320       case TYPE_NULL:
1321         if(der[counter]) return ASN_DER_ERROR;
1322         counter++;
1323         move=RIGHT;
1324         break;
1325       case TYPE_BOOLEAN:
1326         if(der[counter++]!=1) return ASN_DER_ERROR;
1327         counter++;
1328         move=RIGHT;
1329         break;
1330       case TYPE_INTEGER: case TYPE_ENUMERATED:
1331         len2=_asn1_get_length_der(der+counter,&len3);
1332         counter+=len3+len2;
1333         move=RIGHT;
1334         break;
1335       case TYPE_OBJECT_ID:
1336         len2=_asn1_get_length_der(der+counter,&len3);
1337         counter+=len2+len3;
1338         move=RIGHT;
1339       break;
1340       case TYPE_TIME:
1341         len2=_asn1_get_length_der(der+counter,&len3);
1342         counter+=len2+len3;
1343         move=RIGHT;
1344         break;
1345       case TYPE_OCTET_STRING:
1346         len2=_asn1_get_length_der(der+counter,&len3);
1347         counter+=len3+len2;
1348         move=RIGHT;
1349         break;
1350       case TYPE_BIT_STRING:
1351         len2=_asn1_get_length_der(der+counter,&len3);
1352         counter+=len3+len2;
1353         move=RIGHT;
1354         break;
1355       case TYPE_SEQUENCE:  case TYPE_SET:
1356         if(move!=UP){
1357           len3=_asn1_get_length_der(der+counter,&len2);
1358           counter+=len2;
1359           move=DOWN; 
1360         }
1361         else move=RIGHT;
1362         break;
1363       case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1364         if(move!=UP){
1365           len3=_asn1_get_length_der(der+counter,&len2);
1366           counter+=len2;
1367           if(len3){
1368             p2=p->down;
1369             while((type_field(p2->type)==TYPE_TAG) || 
1370                   (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1371             p=p2;
1372           }
1373         }
1374         move=RIGHT;
1375         break;
1376       case TYPE_ANY:
1377         tag=_asn1_get_tag_der(der+counter,&class,&len2);
1378         len2+=_asn1_get_length_der(der+counter+len2,&len3);
1379         counter+=len3+len2;
1380         move=RIGHT;
1381         break;
1382       default:
1383         move=(move==UP)?RIGHT:DOWN;
1384         break;
1385       }
1386     }
1387
1388     if((p==node_to_find) && (move==RIGHT)){
1389       *end=counter-1;
1390       return ASN_OK;
1391     }
1392
1393     if(p==node && move!=DOWN) break;
1394
1395     if(move==DOWN){
1396       if(p->down) p=p->down;
1397       else move=RIGHT;
1398     }
1399     if((move==RIGHT) && !(p->type&CONST_SET)){
1400       if(p->right) p=p->right;
1401       else move=UP;
1402     }
1403     if(move==UP) p=_asn1_find_up(p);
1404   }
1405
1406   return ASN_ELEMENT_NOT_FOUND;
1407 }
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417