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

coding.c

00001 /*
00002  *      Copyright (C) 2002  Fabio Fiorina
00003  *
00004  * This file is part of LIBASN1.
00005  *
00006  * The LIBTASN1 library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public   
00008  * License as published by the Free Software Foundation; either 
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00019  */
00020 
00021 
00022 /*****************************************************/
00023 /* File: coding.c                                    */
00024 /* Description: Functions to create a DER coding of  */
00025 /*   an ASN1 type.                                   */
00026 /*****************************************************/
00027  
00028 #include <int.h>
00029 #include <errors.h>
00030 #include "der.h"
00031 #include "parser_aux.h"
00032 #include <gstr.h>
00033 #include "element.h"
00034 
00035 #define MAX_TAG_LEN 16
00036 
00037 /******************************************************/
00038 /* Function : _asn1_error_description_value_not_found */
00039 /* Description: creates the ErrorDescription string   */
00040 /* for the ASN1_VALUE_NOT_FOUND error.                */
00041 /* Parameters:                                        */
00042 /*   node: node of the tree where the value is NULL.  */
00043 /*   ErrorDescription: string returned.               */
00044 /* Return:                                            */
00045 /******************************************************/
00046 void
00047 _asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
00048 {
00049 
00050   if (ErrorDescription == NULL) return;
00051 
00052   Estrcpy(ErrorDescription,":: value of element '");
00053   _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
00054                     MAX_ERROR_DESCRIPTION_SIZE-40);
00055   Estrcat(ErrorDescription,"' not found");
00056 
00057 }
00058 
00059 /******************************************************/
00060 /* Function : _asn1_length_der                        */
00061 /* Description: creates the DER coding for the LEN    */
00062 /* parameter (only the length).                       */
00063 /* Parameters:                                        */
00064 /*   len: value to convert.                           */
00065 /*   ans: string returned.                            */
00066 /*   ans_len: number of meanful bytes of ANS          */
00067 /*            (ans[0]..ans[ans_len-1]).               */
00068 /* Return:                                            */
00069 /******************************************************/
00070 void
00071 _asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len)
00072 {
00073   int k;
00074   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
00075 
00076   if(len<128){
00077     /* short form */
00078     if(ans!=NULL) ans[0]=(unsigned char)len;
00079     *ans_len=1;
00080   }
00081   else{
00082     /* Long form */
00083     k=0;
00084     while(len){
00085       temp[k++]=len&0xFF;
00086       len=len>>8;
00087     }
00088     *ans_len=k+1;
00089     if(ans!=NULL){
00090       ans[0]=((unsigned char)k&0x7F)+128;
00091       while(k--) ans[*ans_len-1-k]=temp[k];  
00092     }
00093   }
00094 }
00095 
00096 /******************************************************/
00097 /* Function : _asn1_tag_der                           */
00098 /* Description: creates the DER coding for the CLASS  */
00099 /* and TAG parameters.                                */
00100 /* Parameters:                                        */
00101 /*   class: value to convert.                         */
00102 /*   tag_value: value to convert.                     */
00103 /*   ans: string returned.                            */
00104 /*   ans_len: number of meanful bytes of ANS          */
00105 /*            (ans[0]..ans[ans_len-1]).               */
00106 /* Return:                                            */
00107 /******************************************************/
00108 void
00109 _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
00110 {
00111   int k;
00112   unsigned char temp[SIZEOF_UNSIGNED_INT];
00113 
00114   if(tag_value<31){
00115     /* short form */
00116     ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
00117     *ans_len=1;
00118   }
00119   else{
00120     /* Long form */
00121     ans[0]=(class&0xE0) + 31;
00122     k=0;
00123     while(tag_value){
00124       temp[k++]=tag_value&0x7F;
00125       tag_value=tag_value>>7;
00126     }
00127     *ans_len=k+1;
00128     while(k--) ans[*ans_len-1-k]=temp[k]+128;
00129     ans[*ans_len-1]-=128;  
00130   }
00131 }
00132 
00133 /******************************************************/
00134 /* Function : _asn1_octect_der                        */
00135 /* Description: creates the DER coding for an         */
00136 /* OCTET type (length included).                      */
00137 /* Parameters:                                        */
00138 /*   str: OCTET string.                               */
00139 /*   str_len: STR length (str[0]..str[str_len-1]).    */
00140 /*   der: string returned.                            */
00141 /*   der_len: number of meanful bytes of DER          */
00142 /*            (der[0]..der[ans_len-1]).               */
00143 /* Return:                                            */
00144 /******************************************************/
00145 void
00146 _asn1_octet_der(const unsigned char *str,int str_len,unsigned char *der,int *der_len)
00147 {
00148   int len_len;
00149 
00150   if(der==NULL || str_len <= 0) return;
00151   _asn1_length_der(str_len,der,&len_len);
00152   memcpy(der+len_len,str,str_len);
00153   *der_len=str_len+len_len;
00154 }
00155 
00156 /******************************************************/
00157 /* Function : _asn1_time_der                          */
00158 /* Description: creates the DER coding for a TIME     */
00159 /* type (length included).                            */
00160 /* Parameters:                                        */
00161 /*   str: TIME null-terminated string.                */
00162 /*   der: string returned.                            */
00163 /*   der_len: number of meanful bytes of DER          */
00164 /*            (der[0]..der[ans_len-1]). Initially it  */
00165 /*            if must store the lenght of DER.        */
00166 /* Return:                                            */
00167 /*   ASN1_MEM_ERROR when DER isn't big enough         */
00168 /*   ASN1_SUCCESS otherwise                           */
00169 /******************************************************/
00170 asn1_retCode
00171 _asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
00172 {
00173   int len_len;
00174   int max_len;
00175 
00176   max_len=*der_len;
00177 
00178   _asn1_length_der(strlen(str),(max_len>0)?der:NULL,&len_len);
00179 
00180   if((len_len+(int)strlen(str))<=max_len)
00181     memcpy(der+len_len,str,strlen(str));
00182   *der_len=len_len+strlen(str);
00183 
00184   if((*der_len)>max_len) return ASN1_MEM_ERROR;
00185 
00186   return ASN1_SUCCESS;
00187 }
00188 
00189 
00190 /*
00191 void
00192 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
00193 {
00194   int len_len,str_len;
00195   char temp[20];
00196 
00197   if(str==NULL) return;
00198   str_len=_asn1_get_length_der(der,*der_len,&len_len);
00199   if (str_len<0) return;
00200   memcpy(temp,der+len_len,str_len);
00201   *der_len=str_len+len_len;
00202   switch(str_len){
00203   case 11:
00204     temp[10]=0;
00205     strcat(temp,"00+0000");
00206     break;
00207   case 13:
00208     temp[12]=0;
00209     strcat(temp,"+0000");
00210     break;
00211   case 15:
00212     temp[15]=0;
00213     memmove(temp+12,temp+10,6);
00214     temp[10]=temp[11]='0';
00215     break;
00216   case 17:
00217     temp[17]=0;
00218     break;
00219   default:
00220     return;
00221   }
00222   strcpy(str,temp);
00223 }
00224 */
00225 
00226 /******************************************************/
00227 /* Function : _asn1_objectid_der                      */
00228 /* Description: creates the DER coding for an         */
00229 /* OBJECT IDENTIFIER  type (length included).         */
00230 /* Parameters:                                        */
00231 /*   str: OBJECT IDENTIFIER null-terminated string.   */
00232 /*   der: string returned.                            */
00233 /*   der_len: number of meanful bytes of DER          */
00234 /*            (der[0]..der[ans_len-1]). Initially it  */
00235 /*            if must store the lenght of DER.        */
00236 /* Return:                                            */
00237 /*   ASN1_MEM_ERROR when DER isn't big enough         */
00238 /*   ASN1_SUCCESS otherwise                           */
00239 /******************************************************/
00240 asn1_retCode
00241 _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
00242 {
00243   int len_len,counter,k,first,max_len;
00244   char *temp,*n_end,*n_start;
00245   unsigned char bit7;
00246   unsigned long val,val1=0;
00247 
00248   max_len=*der_len;
00249 
00250   temp=(char *) _asn1_alloca(strlen(str)+2);
00251   if(temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00252 
00253   strcpy(temp, str);
00254   strcat(temp, ".");
00255 
00256   counter=0;
00257   n_start=temp;
00258   while((n_end=strchr(n_start,'.'))){
00259     *n_end=0;
00260     val=strtoul(n_start,NULL,10);
00261     counter++;
00262 
00263     if(counter==1) val1=val;
00264     else if(counter==2){
00265       if(max_len>0)
00266       der[0]=40*val1+val;
00267       *der_len=1;
00268     }
00269     else{
00270       first=0;
00271       for(k=4;k>=0;k--){
00272       bit7=(val>>(k*7))&0x7F;
00273       if(bit7 || first || !k){
00274         if(k) bit7|=0x80;
00275         if(max_len>(*der_len))
00276           der[*der_len]=bit7;
00277         (*der_len)++;
00278         first=1;
00279       }
00280       }
00281 
00282     }
00283     n_start=n_end+1;
00284   }
00285 
00286   _asn1_length_der(*der_len,NULL,&len_len);
00287   if(max_len>=(*der_len+len_len)){
00288     memmove(der+len_len,der,*der_len);
00289     _asn1_length_der(*der_len,der,&len_len);
00290   }
00291   *der_len+=len_len;
00292 
00293   _asn1_afree(temp);
00294 
00295   if(max_len<(*der_len)) return ASN1_MEM_ERROR;
00296 
00297   return ASN1_SUCCESS;
00298 }
00299 
00300 
00301 char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
00302 
00303 /******************************************************/
00304 /* Function : _asn1_bit_der                           */
00305 /* Description: creates the DER coding for a BIT      */
00306 /* STRING  type (length and pad included).            */
00307 /* Parameters:                                        */
00308 /*   str: BIT string.                                 */
00309 /*   bit_len: number of meanful bits in STR.          */
00310 /*   der: string returned.                            */
00311 /*   der_len: number of meanful bytes of DER          */
00312 /*            (der[0]..der[ans_len-1]).               */
00313 /* Return:                                            */
00314 /******************************************************/
00315 void
00316 _asn1_bit_der(const unsigned char *str,int bit_len,unsigned char *der,int *der_len)
00317 {
00318   int len_len,len_byte,len_pad;
00319 
00320   if(der==NULL) return;
00321   len_byte=bit_len>>3;
00322   len_pad=8-(bit_len&7);
00323   if(len_pad==8) len_pad=0;
00324   else len_byte++;
00325   _asn1_length_der(len_byte+1,der,&len_len);
00326   der[len_len]=len_pad;
00327   memcpy(der+len_len+1,str,len_byte);
00328   der[len_len+len_byte]&=bit_mask[len_pad];
00329   *der_len=len_byte+len_len+1;
00330 }
00331 
00332 
00333 /******************************************************/
00334 /* Function : _asn1_complete_explicit_tag             */
00335 /* Description: add the length coding to the EXPLICIT */
00336 /* tags.                                              */
00337 /* Parameters:                                        */
00338 /*   node: pointer to the tree element.               */
00339 /*   der: string with the DER coding of the whole tree*/
00340 /*   counter: number of meanful bytes of DER          */
00341 /*            (der[0]..der[*counter-1]).              */
00342 /*   max_len: size of der vector                      */
00343 /* Return:                                            */
00344 /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
00345 /*   otherwise ASN1_SUCCESS.                          */
00346 /******************************************************/
00347 asn1_retCode
00348 _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
00349 {
00350   node_asn *p;
00351   int is_tag_implicit,len2,len3;
00352   unsigned char temp[SIZEOF_UNSIGNED_INT];
00353   
00354   is_tag_implicit=0;
00355 
00356   if(node->type&CONST_TAG){
00357     p=node->down;
00358     /* When there are nested tags we must complete them reverse to
00359        the order they were created. This is because completing a tag
00360        modifies alla date within it, including the incomplete tags 
00361        which store buffer positions -- simon@josefsson.org 2002-09-06
00362     */
00363     while(p->right)
00364       p=p->right;
00365     while(p && p!=node->down->left){
00366       if(type_field(p->type)==TYPE_TAG){
00367       if(p->type&CONST_EXPLICIT){
00368         len2=strtol(p->name,NULL,10);
00369         _asn1_set_name(p,NULL);
00370         _asn1_length_der(*counter-len2,temp,&len3);
00371         if(len3<=(*max_len)){ 
00372           memmove(der+len2+len3,der+len2,*counter-len2);
00373           memcpy(der+len2,temp,len3);
00374         }
00375         *max_len -= len3;
00376         *counter+=len3;   
00377         is_tag_implicit=0;
00378       }
00379       else{  /* CONST_IMPLICIT */
00380         if(!is_tag_implicit){
00381           is_tag_implicit=1;
00382         }
00383       }
00384       }
00385       p=p->left;
00386     }
00387   }
00388 
00389   if(*max_len<0) return ASN1_MEM_ERROR;
00390 
00391   return ASN1_SUCCESS;
00392 }
00393 
00394 
00395 /******************************************************/
00396 /* Function : _asn1_insert_tag_der                    */
00397 /* Description: creates the DER coding of tags of one */
00398 /* NODE.                                              */
00399 /* Parameters:                                        */
00400 /*   node: pointer to the tree element.               */
00401 /*   der: string returned                             */
00402 /*   counter: number of meanful bytes of DER          */
00403 /*            (counter[0]..der[*counter-1]).          */
00404 /*   max_len: size of der vector                      */
00405 /* Return:                                            */
00406 /*   ASN1_GENERIC_ERROR if the type is unknown,       */
00407 /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
00408 /*   otherwise ASN1_SUCCESS.                          */
00409 /******************************************************/
00410 asn1_retCode
00411 _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
00412 {
00413   node_asn *p;
00414   int tag_len,is_tag_implicit;
00415   unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1];
00416   unsigned long tag_implicit=0;
00417   char tag_der[MAX_TAG_LEN];
00418    
00419   is_tag_implicit=0;
00420 
00421   if(node->type&CONST_TAG){
00422     p=node->down;
00423     while(p){
00424       if(type_field(p->type)==TYPE_TAG){
00425       if(p->type&CONST_APPLICATION) class=APPLICATION;
00426       else if(p->type&CONST_UNIVERSAL) class=UNIVERSAL;
00427       else if(p->type&CONST_PRIVATE) class=PRIVATE;
00428       else class=CONTEXT_SPECIFIC;
00429       
00430       if(p->type&CONST_EXPLICIT){
00431         if(is_tag_implicit)
00432           _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
00433         else
00434           _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
00435 
00436         *max_len -= tag_len;
00437         if(*max_len>=0)
00438           memcpy(der+*counter,tag_der,tag_len);
00439         *counter+=tag_len;
00440 
00441         _asn1_ltostr(*counter,temp);
00442         _asn1_set_name(p,temp);
00443 
00444         is_tag_implicit=0;
00445       }
00446       else{  /* CONST_IMPLICIT */
00447         if(!is_tag_implicit){
00448           if((type_field(node->type)==TYPE_SEQUENCE) || 
00449              (type_field(node->type)==TYPE_SEQUENCE_OF) ||
00450              (type_field(node->type)==TYPE_SET) ||
00451              (type_field(node->type)==TYPE_SET_OF)) class|=STRUCTURED;
00452           class_implicit=class;
00453           tag_implicit=strtoul(p->value,NULL,10);
00454           is_tag_implicit=1;
00455         }
00456       }
00457       }
00458       p=p->right;
00459     }
00460   }
00461   
00462   if(is_tag_implicit){
00463     _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
00464   }
00465   else{
00466     switch(type_field(node->type)){
00467     case TYPE_NULL:
00468       _asn1_tag_der(UNIVERSAL,TAG_NULL,tag_der,&tag_len);
00469       break;
00470     case TYPE_BOOLEAN:
00471       _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,tag_der,&tag_len);
00472       break;
00473     case TYPE_INTEGER:
00474       _asn1_tag_der(UNIVERSAL,TAG_INTEGER,tag_der,&tag_len);
00475       break;
00476     case TYPE_ENUMERATED:
00477       _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,tag_der,&tag_len);
00478       break;
00479     case TYPE_OBJECT_ID:
00480       _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,tag_der,&tag_len);
00481       break;
00482     case TYPE_TIME:
00483       if(node->type&CONST_UTC){
00484       _asn1_tag_der(UNIVERSAL,TAG_UTCTime,tag_der,&tag_len);
00485       }
00486       else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,tag_der,&tag_len);
00487       break;
00488     case TYPE_OCTET_STRING:
00489       _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,tag_der,&tag_len);
00490       break;
00491     case TYPE_GENERALSTRING:
00492       _asn1_tag_der(UNIVERSAL,TAG_GENERALSTRING,tag_der,&tag_len);
00493       break;
00494     case TYPE_BIT_STRING:
00495       _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,tag_der,&tag_len);
00496       break;
00497     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
00498       _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,tag_der,&tag_len);
00499       break;
00500     case TYPE_SET: case TYPE_SET_OF:
00501       _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,tag_der,&tag_len);
00502       break;
00503     case TYPE_TAG:
00504       tag_len=0;
00505       break;
00506     case TYPE_CHOICE:
00507       tag_len=0;
00508       break;
00509     case TYPE_ANY:
00510       tag_len=0;
00511       break;
00512     default:
00513       return ASN1_GENERIC_ERROR;
00514     }
00515   }
00516 
00517   *max_len -= tag_len;
00518   if(*max_len>=0)
00519     memcpy(der+*counter,tag_der,tag_len);
00520   *counter+=tag_len;
00521 
00522   if(*max_len<0) return ASN1_MEM_ERROR;
00523 
00524   return ASN1_SUCCESS;
00525 }
00526 
00527 /******************************************************/
00528 /* Function : _asn1_ordering_set                      */
00529 /* Description: puts the elements of a SET type in    */
00530 /* the correct order according to DER rules.          */
00531 /* Parameters:                                        */
00532 /*   der: string with the DER coding.                 */
00533 /*   node: pointer to the SET element.                */
00534 /* Return:                                            */
00535 /******************************************************/
00536 void
00537 _asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
00538 {
00539   struct vet{
00540     int end;
00541     unsigned long value;
00542     struct vet *next,*prev;
00543   };
00544 
00545   int counter,len,len2;
00546   struct vet *first,*last,*p_vet,*p2_vet;
00547   node_asn *p;
00548   unsigned char class,*temp;
00549   unsigned long tag;
00550 
00551   counter=0;
00552 
00553   if(type_field(node->type)!=TYPE_SET) return;
00554 
00555   p=node->down;
00556   while((type_field(p->type)==TYPE_TAG)  || (type_field(p->type)==TYPE_SIZE)) p=p->right;
00557 
00558   if((p==NULL) || (p->right==NULL)) return;
00559 
00560   first=last=NULL;
00561   while(p){
00562     p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
00563     if (p_vet==NULL) return;
00564     
00565     p_vet->next=NULL;
00566     p_vet->prev=last;
00567     if(first==NULL) first=p_vet;
00568     else last->next=p_vet;
00569     last=p_vet;
00570 
00571     /* tag value calculation */
00572     if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
00573       return;
00574     p_vet->value=(class<<24)|tag;
00575     counter+=len2;
00576 
00577     /* extraction  and length */
00578     len2=_asn1_get_length_der(der+counter,der_len-counter,&len);
00579     if (len2<0) return;
00580     counter+=len+len2;
00581 
00582     p_vet->end=counter;
00583     p=p->right;
00584   }
00585 
00586   p_vet=first;
00587 
00588   while(p_vet){
00589     p2_vet=p_vet->next;
00590     counter=0;
00591     while(p2_vet){
00592       if(p_vet->value>p2_vet->value){
00593       /* change position */
00594       temp=(unsigned char *)_asn1_alloca( p_vet->end-counter);
00595       if (temp==NULL) return;
00596       
00597       memcpy(temp,der+counter,p_vet->end-counter);
00598       memcpy(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
00599       memcpy(der+counter+p2_vet->end-p_vet->end,temp,p_vet->end-counter);
00600       _asn1_afree(temp);
00601       
00602       tag=p_vet->value;
00603       p_vet->value=p2_vet->value;
00604       p2_vet->value=tag;
00605       
00606       p_vet->end=counter+(p2_vet->end-p_vet->end);
00607       }
00608       counter=p_vet->end;
00609       
00610       p2_vet=p2_vet->next;
00611       p_vet=p_vet->next;
00612     }
00613 
00614     if(p_vet!=first) p_vet->prev->next=NULL;
00615     else first=NULL;
00616     _asn1_afree(p_vet);
00617     p_vet=first;
00618   }
00619 }
00620 
00621 /******************************************************/
00622 /* Function : _asn1_ordering_set_of                   */
00623 /* Description: puts the elements of a SET OF type in */
00624 /* the correct order according to DER rules.          */
00625 /* Parameters:                                        */
00626 /*   der: string with the DER coding.                 */
00627 /*   node: pointer to the SET OF element.             */
00628 /* Return:                                            */
00629 /******************************************************/
00630 void
00631 _asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node)
00632 {
00633   struct vet{
00634     int end;
00635     struct vet *next,*prev;
00636   };
00637 
00638   int counter,len,len2,change;
00639   struct vet *first,*last,*p_vet,*p2_vet;
00640   node_asn *p;
00641   unsigned char *temp,class;
00642   unsigned long k,max;
00643 
00644   counter=0;
00645 
00646   if(type_field(node->type)!=TYPE_SET_OF) return;
00647 
00648   p=node->down;
00649   while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
00650   p=p->right;
00651 
00652   if((p==NULL) || (p->right==NULL)) return;
00653 
00654   first=last=NULL;
00655   while(p){
00656     p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
00657     if (p_vet==NULL) return;
00658     
00659     p_vet->next=NULL;
00660     p_vet->prev=last;
00661     if(first==NULL) first=p_vet;
00662     else last->next=p_vet;
00663     last=p_vet;
00664 
00665     /* extraction of tag and length */
00666     if (der_len-counter > 0) {
00667 
00668        if (_asn1_get_tag_der(der+counter, der_len - counter, &class,&len,NULL)!=ASN1_SUCCESS)
00669           return;
00670        counter+=len;
00671     
00672        len2=_asn1_get_length_der(der+counter,der_len-counter,&len);
00673        if (len2<0) return;
00674        counter+=len+len2;
00675     }
00676 
00677     p_vet->end=counter;
00678     p=p->right;
00679   }
00680 
00681   p_vet=first;
00682 
00683   while(p_vet){
00684     p2_vet=p_vet->next;
00685     counter=0;
00686     while(p2_vet){
00687       if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
00688       max=p_vet->end-counter;
00689       else
00690       max=p2_vet->end-p_vet->end;
00691 
00692       change=-1;
00693       for(k=0;k<max;k++) 
00694       if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
00695       else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
00696 
00697       if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
00698       change=1;
00699 
00700       if(change==1){
00701       /* change position */
00702       temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
00703       if (temp==NULL) return;
00704       
00705       memcpy(temp,der+counter,(p_vet->end)-counter);
00706       memcpy(der+counter,der+(p_vet->end),(p2_vet->end)-(p_vet->end));
00707       memcpy(der+counter+(p2_vet->end)-(p_vet->end),temp,(p_vet->end)-counter);
00708       _asn1_afree(temp);
00709       
00710       p_vet->end=counter+(p2_vet->end-p_vet->end);
00711       }
00712       counter=p_vet->end;
00713       
00714       p2_vet=p2_vet->next;
00715       p_vet=p_vet->next;
00716     }
00717 
00718     if(p_vet!=first) p_vet->prev->next=NULL;
00719     else first=NULL;
00720     _asn1_afree(p_vet);
00721     p_vet=first;
00722   }
00723 }
00724 
00725 /**
00726   * asn1_der_coding - Creates the DER encoding for the NAME structure
00727   * @element: pointer to an ASN1 element
00728   * @name: the name of the structure you want to encode (it must be inside *POINTER).
00729   * @ider: vector that will contain the DER encoding. DER must be a pointer to memory cells already allocated.
00730   * @len: number of bytes of *der: der[0]..der[len-1], Initialy holds the sizeof of der vector.
00731   * @errorDescription : return the error description or an empty string if success.
00732   * Description:
00733   *
00734   * Creates the DER encoding for the NAME structure (inside *POINTER structure).
00735   * 
00736   * Returns:
00737   *
00738   *   ASN1_SUCCESS\: DER encoding OK
00739   *
00740   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
00741   *
00742   *   ASN1_VALUE_NOT_FOUND\: there is an element without a value.
00743   *
00744   *   ASN1_MEM_ERROR\: der vector isn't big enough. Also in this case LEN
00745   *   will contain the length needed.
00746   *
00747   **/
00748 asn1_retCode 
00749 asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
00750                 char *ErrorDescription)
00751 {
00752   node_asn *node,*p,*p2;
00753   char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
00754   int counter,counter_old,len2,len3,move,max_len,max_len_old;
00755   asn1_retCode ris;
00756   unsigned char* der = ider;
00757 
00758   node=_asn1_find_node(element,name);
00759   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00760 
00761   max_len=*len;
00762 
00763   counter=0;
00764   move=DOWN;
00765   p=node;
00766   while(1){
00767     
00768     counter_old=counter;
00769     max_len_old=max_len;
00770     if(move!=UP){
00771       ris=_asn1_insert_tag_der(p,der,&counter,&max_len);
00772     }
00773     switch(type_field(p->type)){
00774     case TYPE_NULL:
00775       max_len--;
00776       if(max_len>=0)
00777       der[counter++]=0;
00778       move=RIGHT;
00779       break;
00780     case TYPE_BOOLEAN:
00781       if((p->type&CONST_DEFAULT) && (p->value==NULL)){
00782       counter=counter_old;
00783       max_len=max_len_old;
00784       }
00785       else{
00786       if(p->value==NULL){
00787         _asn1_error_description_value_not_found(p,ErrorDescription);
00788         return ASN1_VALUE_NOT_FOUND;
00789       }
00790       max_len -= 2;
00791       if(max_len>=0){
00792         der[counter++]=1;
00793         if(p->value[0]=='F') der[counter++]=0;
00794         else der[counter++]=0xFF;
00795       }
00796       else 
00797         counter+=2;
00798       }
00799       move=RIGHT;
00800       break;
00801     case TYPE_INTEGER: case TYPE_ENUMERATED:
00802       if((p->type&CONST_DEFAULT) && (p->value==NULL)){
00803       counter=counter_old;
00804       max_len=max_len_old;
00805       }
00806       else{
00807       if(p->value==NULL){
00808         _asn1_error_description_value_not_found(p,ErrorDescription);
00809         return ASN1_VALUE_NOT_FOUND;
00810       }
00811       len2=_asn1_get_length_der(p->value,p->value_len, &len3);
00812       if (len2<0) return ASN1_DER_ERROR;
00813       max_len -= len2+len3;
00814       if(max_len>=0)
00815         memcpy(der+counter,p->value,len3+len2);
00816       counter+=len3+len2;
00817       }
00818       move=RIGHT;
00819       break;
00820     case TYPE_OBJECT_ID:
00821       if((p->type&CONST_DEFAULT) && (p->value==NULL)){
00822       counter=counter_old;
00823       max_len=max_len_old;
00824       }
00825       else{
00826       if(p->value==NULL){
00827         _asn1_error_description_value_not_found(p,ErrorDescription);
00828         return ASN1_VALUE_NOT_FOUND;
00829       }
00830       len2=max_len;
00831       ris=_asn1_objectid_der(p->value,der+counter,&len2);
00832       if(ris==ASN1_MEM_ALLOC_ERROR) return ris;
00833       max_len-=len2;
00834       counter+=len2;
00835       }
00836       move=RIGHT;
00837       break;
00838     case TYPE_TIME:
00839       if(p->value==NULL){
00840       _asn1_error_description_value_not_found(p,ErrorDescription);
00841       return ASN1_VALUE_NOT_FOUND;
00842       }
00843       len2=max_len;
00844       ris=_asn1_time_der(p->value,der+counter,&len2);
00845       max_len-=len2;
00846       counter+=len2;
00847       move=RIGHT;
00848       break;
00849     case TYPE_OCTET_STRING:
00850       if(p->value==NULL){
00851       _asn1_error_description_value_not_found(p,ErrorDescription);
00852       return ASN1_VALUE_NOT_FOUND;
00853       }
00854       len2=_asn1_get_length_der(p->value,p->value_len,&len3);
00855       if (len2<0) return ASN1_DER_ERROR;
00856       max_len-=len2+len3;
00857       if(max_len>=0)
00858       memcpy(der+counter,p->value,len3+len2);
00859       counter+=len3+len2;
00860       move=RIGHT;
00861       break;
00862     case TYPE_GENERALSTRING:
00863       if(p->value==NULL){
00864       _asn1_error_description_value_not_found(p,ErrorDescription);
00865       return ASN1_VALUE_NOT_FOUND;
00866       }
00867       len2=_asn1_get_length_der(p->value,p->value_len,&len3);
00868       if (len2<0) return ASN1_DER_ERROR;
00869       max_len-=len2+len3;
00870       if(max_len>=0)
00871       memcpy(der+counter,p->value,len3+len2);
00872       counter+=len3+len2;
00873       move=RIGHT;
00874       break;
00875     case TYPE_BIT_STRING:
00876       if(p->value==NULL){
00877       _asn1_error_description_value_not_found(p,ErrorDescription);
00878       return ASN1_VALUE_NOT_FOUND;
00879       }
00880       len2=_asn1_get_length_der(p->value,p->value_len,&len3);
00881       if (len2<0) return ASN1_DER_ERROR;
00882       max_len-=len2+len3;
00883       if(max_len>=0)
00884       memcpy(der+counter,p->value,len3+len2);
00885       counter+=len3+len2;
00886       move=RIGHT;
00887       break;
00888     case TYPE_SEQUENCE: case TYPE_SET: 
00889       if(move!=UP){
00890       _asn1_ltostr(counter,temp);
00891       _asn1_set_value(p,temp,strlen(temp)+1);
00892       if(p->down==NULL){
00893         move=UP;
00894         continue;
00895       }
00896       else{
00897         p2=p->down;
00898         while(p2 && (type_field(p2->type)==TYPE_TAG)) p2=p2->right;
00899         if(p2){
00900           p=p2;
00901           move=RIGHT;
00902           continue;
00903         }
00904         move=UP;
00905         continue;
00906       }
00907       }
00908       else{   /* move==UP */
00909       len2=strtol(p->value,NULL,10);
00910       _asn1_set_value(p,NULL,0);
00911       if((type_field(p->type)==TYPE_SET) && (max_len>=0))
00912         _asn1_ordering_set(der+len2, max_len-len2,p);
00913       _asn1_length_der(counter-len2,temp,&len3);
00914       max_len-=len3;
00915       if(max_len>=0){
00916         memmove(der+len2+len3,der+len2,counter-len2);
00917         memcpy(der+len2,temp,len3);
00918       }
00919       counter+=len3;
00920       move=RIGHT;
00921       }
00922       break;
00923     case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
00924       if(move!=UP){
00925       _asn1_ltostr(counter,temp);
00926       _asn1_set_value(p,temp,strlen(temp)+1);
00927       p=p->down;
00928       while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
00929       if(p->right){
00930         p=p->right;
00931         move=RIGHT;
00932         continue;
00933       }
00934       else p=_asn1_find_up(p);
00935       move=UP;
00936       }
00937       if(move==UP){
00938       len2=strtol(p->value,NULL,10);
00939       _asn1_set_value(p,NULL,0);
00940       if((type_field(p->type)==TYPE_SET_OF) && (max_len-len2>0)) {
00941         _asn1_ordering_set_of(der+len2, max_len-len2,p);
00942         }
00943       _asn1_length_der(counter-len2,temp,&len3);
00944       max_len-=len3;
00945       if(max_len>=0){
00946         memmove(der+len2+len3,der+len2,counter-len2);
00947         memcpy(der+len2,temp,len3);
00948       }
00949       counter+=len3;
00950       move=RIGHT;
00951       }
00952       break;
00953     case TYPE_ANY:
00954       if(p->value==NULL){
00955       _asn1_error_description_value_not_found(p,ErrorDescription);
00956       return ASN1_VALUE_NOT_FOUND;
00957       }
00958       len2=_asn1_get_length_der(p->value,p->value_len,&len3);
00959       if (len2<0) return ASN1_DER_ERROR;
00960       max_len-=len2;
00961       if(max_len>=0)
00962       memcpy(der+counter,p->value+len3,len2);
00963       counter+=len2;
00964       move=RIGHT;
00965       break;
00966     default:
00967        move=(move==UP)?RIGHT:DOWN;
00968       break;
00969     }
00970 
00971     if((move!=DOWN) && (counter!=counter_old)){
00972       ris=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
00973     }
00974 
00975     if(p==node && move!=DOWN) break;
00976 
00977     if(move==DOWN){
00978       if(p->down) p=p->down;
00979       else move=RIGHT;
00980     }
00981     if(move==RIGHT){
00982       if(p->right) p=p->right;
00983       else move=UP;
00984     }
00985    if(move==UP) p=_asn1_find_up(p);
00986   }
00987 
00988   *len=counter;
00989 
00990   if(max_len<0) return ASN1_MEM_ERROR;
00991 
00992   return ASN1_SUCCESS;
00993 }
00994 
00995 
00996 
00997 
00998 
00999 
01000 
01001 
01002 
01003 
01004 
01005 
01006 
01007 
01008 

Generated by  Doxygen 1.5.1