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

element.c

00001 /*
00002  *      Copyright (C) 2000,2001,2002,2003 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 /* File: element.c                                   */
00023 /* Description: Functions with the read and write    */
00024 /*   functions.                                      */
00025 /*****************************************************/
00026 
00027 
00028 #include <int.h>
00029 #include <errors.h>
00030 #include "parser_aux.h"
00031 #include "der.h"
00032 #include <gstr.h>
00033 #include "structure.h"
00034 
00035 void
00036 _asn1_hierarchical_name(node_asn *node,char *name,int name_size)
00037 {
00038   node_asn *p;
00039   char tmp_name[64];
00040 
00041   p=node;
00042 
00043   name[0]=0;
00044 
00045   while(p != NULL){
00046     if(p->name != NULL){
00047       _asn1_str_cpy(tmp_name,sizeof(tmp_name),name),
00048 
00049       _asn1_str_cpy(name,name_size,p->name);
00050       _asn1_str_cat(name,name_size,".");
00051       _asn1_str_cat(name,name_size,tmp_name);
00052     }
00053     p=_asn1_find_up(p);
00054   }
00055 
00056   if(name[0]==0) _asn1_str_cpy(name,name_size,"ROOT");
00057 }
00058 
00059 
00060 /******************************************************************/
00061 /* Function : _asn1_convert_integer                               */
00062 /* Description: converts an integer from a null terminated string */
00063 /*              to der decoding. The convertion from a null       */
00064 /*              terminated string to an integer is made with      */
00065 /*              the 'strtol' function.                            */
00066 /* Parameters:                                                    */
00067 /*   value: null terminated string to convert.                    */
00068 /*   value_out: convertion result (memory must be already         */
00069 /*              allocated).                                       */
00070 /*   value_out_size: number of bytes of value_out.                */
00071 /*   len: number of significant byte of value_out.                */
00072 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS                         */
00073 /******************************************************************/
00074 asn1_retCode
00075 _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len)
00076 {
00077   char negative;
00078   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
00079   long valtmp;
00080   int k,k2;
00081 
00082   valtmp=strtol(value,NULL,10);
00083   
00084   for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++){
00085     val[SIZEOF_UNSIGNED_LONG_INT-k-1]=(valtmp >> (8*k)) & 0xFF;
00086   }
00087 
00088   if(val[0]&0x80) negative=1;
00089   else negative=0;
00090 
00091   for(k=0;k<SIZEOF_UNSIGNED_LONG_INT-1;k++){
00092     if(negative && (val[k]!=0xFF)) break;
00093     else if(!negative && val[k]) break;
00094   }
00095       
00096   if((negative && !(val[k]&0x80)) ||
00097      (!negative && (val[k]&0x80))) k--; 
00098 
00099   *len=SIZEOF_UNSIGNED_LONG_INT-k;  
00100 
00101   if (SIZEOF_UNSIGNED_LONG_INT-k> value_out_size)
00102     /* VALUE_OUT is too short to contain the value convertion */
00103     return ASN1_MEM_ERROR;
00104 
00105   for(k2=k;k2<SIZEOF_UNSIGNED_LONG_INT;k2++)
00106     value_out[k2-k]=val[k2];
00107 
00108 
00109 #ifdef LIBTASN1_DEBUG_INTEGER
00110   _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value,*len);
00111   for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++)
00112     _libtasn1_log(", vOut[%d]=%d",k,value_out[k]);
00113   _libtasn1_log("\n");
00114 #endif
00115 
00116 
00117   return ASN1_SUCCESS;
00118 }
00119 
00120 
00121 int 
00122 _asn1_append_sequence_set(node_asn *node)
00123 {
00124   node_asn *p,*p2;
00125   char temp[10];
00126   long n;
00127 
00128   if(!node || !(node->down)) return ASN1_GENERIC_ERROR;
00129 
00130   p=node->down;
00131   while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
00132   p2=_asn1_copy_structure3(p);
00133   while(p->right) p=p->right;
00134   _asn1_set_right(p,p2);
00135   
00136   if(p->name==NULL) _asn1_str_cpy(temp,sizeof(temp),"?1");
00137   else{
00138     n=strtol(p->name+1,NULL,0);
00139     n++;
00140     temp[0]='?';
00141     _asn1_ltostr(n,temp+1);
00142   } 
00143   _asn1_set_name(p2,temp);
00144   /*  p2->type |= CONST_OPTION; */
00145 
00146   return ASN1_SUCCESS;
00147 }
00148 
00149 
00150 /**
00151   * asn1_write_value - Set the value of one element inside a structure.
00152   * @node_root: pointer to a structure
00153   * @name: the name of the element inside the structure that you want to set.
00154   * @ivalue: vector used to specify the value to set. If len is >0, 
00155   * VALUE must be a two's complement form integer.
00156   * if len=0 *VALUE must be a null terminated string with an integer value. 
00157   * @len: number of bytes of *value to use to set the value: value[0]..value[len-1]
00158   *  or 0 if value is a null terminated string
00159   * Description:
00160   *
00161   * Set the value of one element inside a structure.
00162   * 
00163   * Returns:
00164   * 
00165   *   ASN1_SUCCESS\: set value OK
00166   *
00167   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
00168   *
00169   *   ASN1_VALUE_NOT_VALID\: VALUE has a wrong format.
00170   * 
00171   * Examples:  
00172   *   description for each type
00173   *
00174   *\begin{itemize}
00175   * \item INTEGER\: VALUE must contain a two's complement form integer.
00176   *            value[0]=0xFF ,               len=1 -> integer=-1
00177   *            value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1
00178   *            value[0]=0x01 ,               len=1 -> integer= 1
00179   *            value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1
00180   *            value="123"                 , len=0 -> integer= 123
00181   *
00182   * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
00183   *
00184   * \item BOOLEAN\: VALUE must be the null terminated string "TRUE" or "FALSE" and LEN != 0
00185   *            value="TRUE" , len=1 -> boolean=TRUE
00186   *            value="FALSE" , len=1 -> boolean=FALSE
00187   *
00188   * \item OBJECT IDENTIFIER\: VALUE must be a null terminated string with each number separated by
00189   *                      a dot (e.g. "1.2.3.543.1"). 
00190   *                      LEN != 0
00191   *            value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha
00192   *
00193   * \item UTCTime\: VALUE must be a null terminated string in one of these formats\:
00194   *            "YYMMDDhhmmssZ" "YYMMDDhhmmssZ" "YYMMDDhhmmss+hh'mm'" "YYMMDDhhmmss-hh'mm'"
00195   *            "YYMMDDhhmm+hh'mm'" "YYMMDDhhmm-hh'mm'".  
00196   *            LEN != 0
00197   *            value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 at 12h 00m  Greenwich Mean Time
00198   *
00199   * \item GeneralizedTime\: VALUE must be in one of this format\:
00200   *                    "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.s+hh'mm'" 
00201   *                    "YYYYMMDDhhmmss.s-hh'mm'" "YYYYMMDDhhmm+hh'mm'" "YYYYMMDDhhmm-hh'mm'" 
00202   *                    where ss.s indicates the seconds with any precision like "10.1" or "01.02".
00203   *                    LEN != 0
00204   *            value="2001010112001.12-0700" , len=1 -> time=Jannuary 1st, 2001 at 12h 00m 01.12s 
00205   *                                                     Pacific Daylight Time
00206   *
00207   * \item OCTET STRING\: VALUE contains the octet string and LEN is the number of octet.
00208   *            value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3  -> three bytes octet string
00209   *
00210   * \item GeneralString\: VALUE contains the generalstring and LEN is the number of octet.
00211   *            value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3  -> three bytes generalstring
00212   *
00213   * \item BIT STRING\: VALUE contains the bit string organized by bytes and LEN is the number of bits.
00214   *            value="$\backslash$xCF" , len=6 -> bit string="110011" (six bits)
00215   *
00216   * \item CHOICE\: if NAME indicates a choice type, VALUE must specify one of the alternatives with a
00217   *           null terminated string. LEN != 0
00218   *           Using "pkix.asn"\:
00219   *           result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
00220   *
00221   * \item ANY\: VALUE indicates the der encoding of a structure.
00222   *        LEN != 0 
00223   *
00224   * \item SEQUENCE OF\: VALUE must be the null terminated string "NEW" and LEN != 0. With this 
00225   *                instruction another element is appended in the sequence. The name of this
00226   *                element will be "?1" if it's the first one, "?2" for the second and so on.
00227   *
00228   *           Using "pkix.asn"\:   
00229   *
00230   *           result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
00231   *
00232   * \item SET OF\: the same as SEQUENCE OF. 
00233   *           Using "pkix.asn":
00234   *
00235   *           result=asn1_write_value(cert,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
00236   *\end{itemize}
00237   *
00238   * If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
00239   *
00240   *           Using "pkix.asn"\:
00241   *
00242   *           result=asn1_write_value(cert,"tbsCertificate.issuerUniqueID",NULL,0);
00243   * 
00244   **/
00245 asn1_retCode 
00246 asn1_write_value(node_asn *node_root,const char *name,
00247              const void *ivalue,int len)
00248 {
00249   node_asn *node,*p,*p2;
00250   unsigned char *temp,*value_temp=NULL,*default_temp=NULL;
00251   int len2,k,k2,negative;
00252   const unsigned char* value = ivalue;
00253 
00254   node=_asn1_find_node(node_root,name);
00255   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
00256 
00257   if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
00258     asn1_delete_structure(&node);
00259     return ASN1_SUCCESS;
00260   }
00261 
00262   if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){
00263     p=node->down;
00264     while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
00265 
00266     while(p->right)
00267       asn1_delete_structure(&p->right);
00268 
00269     return ASN1_SUCCESS;
00270   }
00271 
00272   switch(type_field(node->type)){
00273   case TYPE_BOOLEAN:
00274     if(!strcmp(value,"TRUE")){
00275       if(node->type&CONST_DEFAULT){
00276       p=node->down;
00277       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00278       if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0);
00279       else _asn1_set_value(node,"T",1);
00280       }
00281       else _asn1_set_value(node,"T",1);
00282     }
00283     else if(!strcmp(value,"FALSE")){
00284       if(node->type&CONST_DEFAULT){
00285       p=node->down;
00286       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00287       if(p->type&CONST_FALSE) _asn1_set_value(node,NULL,0);
00288       else _asn1_set_value(node,"F",1);
00289       }
00290       else _asn1_set_value(node,"F",1);
00291     }
00292     else return ASN1_VALUE_NOT_VALID;
00293     break;
00294   case TYPE_INTEGER: case TYPE_ENUMERATED:
00295     if(len==0){
00296       if((isdigit(value[0])) || (value[0]=='-')){
00297       value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
00298       if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00299 
00300       _asn1_convert_integer(value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
00301       }
00302       else{ /* is an identifier like v1 */
00303       if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
00304       p=node->down;
00305       while(p){
00306         if(type_field(p->type)==TYPE_CONSTANT){
00307           if((p->name) && (!strcmp(p->name,value))){
00308             value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
00309             if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00310 
00311             _asn1_convert_integer(p->value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
00312             break;
00313           }
00314         }
00315         p=p->right;
00316       }
00317       if(p==NULL) return ASN1_VALUE_NOT_VALID;
00318       }
00319     }
00320     else{ /* len != 0 */
00321       value_temp=(unsigned char *)_asn1_alloca(len);
00322       if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00323       memcpy(value_temp,value,len);
00324     }
00325 
00326 
00327     if(value_temp[0]&0x80) negative=1;
00328     else negative=0;
00329 
00330     if(negative && (type_field(node->type)==TYPE_ENUMERATED)) 
00331       {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;}
00332 
00333     for(k=0;k<len-1;k++)
00334       if(negative && (value_temp[k]!=0xFF)) break;
00335       else if(!negative && value_temp[k]) break;
00336 
00337     if((negative && !(value_temp[k]&0x80)) ||
00338        (!negative && (value_temp[k]&0x80))) k--; 
00339 
00340     _asn1_length_der(len-k,NULL,&len2);
00341     temp=(unsigned char *)_asn1_alloca(len-k+len2);
00342     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00343 
00344     _asn1_octet_der(value_temp+k,len-k,temp,&len2);
00345     _asn1_set_value(node,temp,len2);
00346 
00347     _asn1_afree(temp);
00348 
00349 
00350     if(node->type&CONST_DEFAULT){
00351       p=node->down;
00352       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00353       if((isdigit(p->value[0])) || (p->value[0]=='-')){
00354       default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
00355         if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00356 
00357       _asn1_convert_integer(p->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
00358       }
00359       else{ /* is an identifier like v1 */
00360       if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
00361       p2=node->down;
00362       while(p2){
00363         if(type_field(p2->type)==TYPE_CONSTANT){
00364           if((p2->name) && (!strcmp(p2->name,p->value))){
00365             default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
00366             if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00367 
00368             _asn1_convert_integer(p2->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
00369             break;
00370           }
00371         }
00372         p2=p2->right;
00373       }
00374       if(p2==NULL) return ASN1_VALUE_NOT_VALID;
00375       }
00376 
00377 
00378       if((len-k)==len2){
00379       for(k2=0;k2<len2;k2++) 
00380         if(value_temp[k+k2]!=default_temp[k2]){
00381           break;
00382         }
00383       if(k2==len2) _asn1_set_value(node,NULL,0);
00384       }
00385       _asn1_afree(default_temp);
00386     }
00387     _asn1_afree(value_temp);
00388     break;
00389   case TYPE_OBJECT_ID:
00390     for(k=0;k<strlen(value);k++)
00391       if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+')) 
00392       return ASN1_VALUE_NOT_VALID; 
00393     if(node->type&CONST_DEFAULT){
00394       p=node->down;
00395       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00396       if(!strcmp(value,p->value)){
00397       _asn1_set_value(node,NULL,0);
00398       break;
00399       } 
00400     }
00401     _asn1_set_value(node,value,strlen(value)+1);
00402     break;
00403   case TYPE_TIME:
00404     if(node->type&CONST_UTC){
00405       if(strlen(value)<11) return ASN1_VALUE_NOT_VALID;
00406       for(k=0;k<10;k++) 
00407       if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
00408       switch(strlen(value)){
00409       case 11:
00410       if(value[10]!='Z') return ASN1_VALUE_NOT_VALID;
00411       break;
00412       case 13:
00413       if((!isdigit(value[10])) || (!isdigit(value[11])) ||
00414          (value[12]!='Z')) return ASN1_VALUE_NOT_VALID;
00415       break;
00416       case 15:
00417       if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID;
00418       for(k=11;k<15;k++) 
00419         if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
00420       break;
00421       case 17:
00422       if((!isdigit(value[10])) || (!isdigit(value[11]))) 
00423          return ASN1_VALUE_NOT_VALID;
00424       if((value[12]!='+') && (value[12]!='-')) return ASN1_VALUE_NOT_VALID;
00425       for(k=13;k<17;k++) 
00426         if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
00427       break; 
00428       default:
00429       return ASN1_VALUE_NOT_FOUND;
00430       }
00431       _asn1_set_value(node,value,strlen(value)+1);
00432     }
00433     else{  /* GENERALIZED TIME */
00434       if(value) _asn1_set_value(node,value,strlen(value)+1);
00435     }
00436     break;
00437   case  TYPE_OCTET_STRING:
00438     if(len==0)
00439       len=strlen(value);
00440     _asn1_length_der(len,NULL,&len2);
00441     temp=(unsigned char *)_asn1_alloca(len+len2);
00442     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00443 
00444     _asn1_octet_der(value,len,temp,&len2);
00445     _asn1_set_value(node,temp,len2);
00446     _asn1_afree(temp);
00447     break;
00448   case  TYPE_GENERALSTRING:
00449     if(len==0)
00450       len=strlen(value);
00451     _asn1_length_der(len,NULL,&len2);
00452     temp=(unsigned char *)_asn1_alloca(len+len2);
00453     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00454 
00455     _asn1_octet_der(value,len,temp,&len2);
00456     _asn1_set_value(node,temp,len2);
00457     _asn1_afree(temp);
00458     break;
00459   case  TYPE_BIT_STRING:
00460     if(len==0)
00461       len=strlen(value);
00462     _asn1_length_der((len>>3)+2,NULL,&len2);
00463     temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2);
00464     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00465 
00466     _asn1_bit_der(value,len,temp,&len2);
00467     _asn1_set_value(node,temp,len2);
00468     _asn1_afree(temp);
00469     break;
00470   case  TYPE_CHOICE:
00471     p=node->down;
00472     while(p){
00473       if(!strcmp(p->name,value)){
00474       p2=node->down;
00475       while(p2){
00476         if(p2!=p){asn1_delete_structure(&p2); p2=node->down;}
00477         else p2=p2->right;
00478       }
00479       break;
00480       }
00481       p=p->right;
00482     }
00483     if(!p) return ASN1_ELEMENT_NOT_FOUND;
00484     break;
00485   case TYPE_ANY:
00486     _asn1_length_der(len,NULL,&len2);
00487     temp=(unsigned char *)_asn1_alloca(len+len2);
00488     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
00489 
00490     _asn1_octet_der(value,len,temp,&len2);
00491     _asn1_set_value(node,temp,len2);
00492     _asn1_afree(temp);
00493     break;
00494   case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
00495     if(strcmp(value,"NEW")) return ASN1_VALUE_NOT_VALID;    
00496     _asn1_append_sequence_set(node);
00497     break;
00498   default:
00499     return  ASN1_ELEMENT_NOT_FOUND;
00500     break;
00501   }
00502 
00503   return ASN1_SUCCESS;
00504 }
00505 
00506 
00507 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
00508       *len = data_size; \
00509       if (ptr_size < data_size) { \
00510             return ASN1_MEM_ERROR; \
00511       } else { \
00512             memcpy( ptr, data, data_size); \
00513       }
00514 
00515 #define PUT_STR_VALUE( ptr, ptr_size, data) \
00516       *len = strlen(data) + 1; \
00517       if (ptr_size < *len) { \
00518             return ASN1_MEM_ERROR; \
00519       } else { \
00520             /* this strcpy is checked */ \
00521             strcpy(ptr, data); \
00522       }
00523             
00524 #define ADD_STR_VALUE( ptr, ptr_size, data) \
00525       *len = strlen(data) + 1; \
00526       if (ptr_size < strlen(ptr)+(*len)) { \
00527             return ASN1_MEM_ERROR; \
00528       } else { \
00529             /* this strcat is checked */ \
00530             strcat(ptr, data); \
00531       }
00532 
00533 /**
00534   * asn1_read_value - Returns the value of one element inside a structure
00535   * @root: pointer to a structure
00536   * @name: the name of the element inside a structure that you want to read.
00537   * @ivalue: vector that will contain the element's content. 
00538   * VALUE must be a pointer to memory cells already allocated.
00539   * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
00540   *
00541   * Description:
00542   *
00543   * Returns the value of one element inside a structure.
00544   * 
00545   * Returns:
00546   *
00547   *   ASN1_SUCCESS\: set value OK
00548   *
00549   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
00550   *
00551   *   ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected.
00552   *
00553   *   ASN1_MEM_ERROR\: the value vector isn't big enough to store the result.
00554   *   In this case LEN will contain the number of bytes needed.
00555   * 
00556   * Examples: 
00557   *   a description for each type
00558   *
00559   *\begin{itemize}
00560   * \item INTEGER\: VALUE will contain a two's complement form integer.
00561   *            integer=-1  -> value[0]=0xFF , len=1
00562   *            integer=1   -> value[0]=0x01 , len=1
00563   *
00564   * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
00565   *
00566   * \item BOOLEAN\: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
00567   *
00568   * \item OBJECT IDENTIFIER\: VALUE will be a null terminated string with each number separated by
00569   *                      a dot (i.e. "1.2.3.543.1"). 
00570   *                      LEN = strlen(VALUE)+1
00571   *
00572   * \item UTCTime\: VALUE will be a null terminated string in one of these formats\: 
00573   *            "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
00574   *            LEN=strlen(VALUE)+1
00575   *
00576   * \item GeneralizedTime\: VALUE will be a null terminated string in the same format used to set
00577   *                    the value
00578   *
00579   * \item OCTET STRING\: VALUE will contain the octet string and LEN will be the number of octet.
00580   *
00581   * \item GeneralString\: VALUE will contain the generalstring and LEN will be the number of octet.
00582   *
00583   * \item BIT STRING\: VALUE will contain the bit string organized by bytes and LEN will be the 
00584   *               number of bits.
00585   *
00586   * \item CHOICE\: if NAME indicates a choice type, VALUE will specify the alternative selected
00587   *
00588   * \item ANY\: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure 
00589   *        actually used.
00590   *\end{itemize}
00591   * 
00592   * If an element is OPTIONAL and the function "read_value" returns ASN1_ELEMENT_NOT_FOUND, it 
00593   * means that this element wasn't present in the der encoding that created the structure.
00594   * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
00595   * 
00596   **/
00597 asn1_retCode 
00598 asn1_read_value(node_asn *root,const char *name,void* ivalue, int *len)
00599 {
00600   node_asn *node,*p,*p2;
00601   int len2,len3;
00602   int value_size = *len;
00603   unsigned char* value = ivalue;
00604 
00605   node=_asn1_find_node(root,name);
00606   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
00607 
00608   if((type_field(node->type)!=TYPE_NULL) && 
00609      (type_field(node->type)!=TYPE_CHOICE) &&  
00610      !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) &&
00611      (node->value==NULL)) 
00612     return ASN1_VALUE_NOT_FOUND;
00613 
00614   switch(type_field(node->type)){
00615   case TYPE_NULL:
00616     PUT_STR_VALUE( value, value_size, "NULL");
00617     break;
00618   case TYPE_BOOLEAN:
00619     if((node->type&CONST_DEFAULT) && (node->value==NULL)){
00620       p=node->down;
00621       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00622       if(p->type&CONST_TRUE) {
00623             PUT_STR_VALUE( value, value_size, "TRUE");
00624       } else {
00625             PUT_STR_VALUE(value, value_size, "FALSE");
00626       }
00627     }
00628     else if(node->value[0]=='T') {
00629       PUT_STR_VALUE(value, value_size, "TRUE");
00630     }
00631     else {
00632       PUT_STR_VALUE(value, value_size, "FALSE");
00633     }
00634     break;
00635   case TYPE_INTEGER: case TYPE_ENUMERATED:
00636     if((node->type&CONST_DEFAULT) && (node->value==NULL)){
00637       p=node->down;
00638       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00639       if((isdigit(p->value[0])) || (p->value[0]=='-') || (p->value[0]=='+')){
00640       if (_asn1_convert_integer(p->value,value,value_size, len) != 
00641           ASN1_SUCCESS) 
00642         return ASN1_MEM_ERROR;
00643       }
00644       else{ /* is an identifier like v1 */
00645       p2=node->down;
00646       while(p2){
00647         if(type_field(p2->type)==TYPE_CONSTANT){
00648           if((p2->name) && (!strcmp(p2->name,p->value))){
00649             if (_asn1_convert_integer(p2->value,value,value_size, len) != 
00650               ASN1_SUCCESS) 
00651             return ASN1_MEM_ERROR;
00652             break;
00653           }
00654         }
00655         p2=p2->right;
00656       }
00657       }
00658     }
00659     else{
00660       len2=-1;
00661       if (_asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
00662     }
00663     break;
00664   case TYPE_OBJECT_ID:
00665     if(node->type&CONST_ASSIGN){
00666       value[0]=0;
00667       p=node->down;
00668       while(p){
00669       if(type_field(p->type)==TYPE_CONSTANT){
00670         ADD_STR_VALUE(value,value_size,p->value);       
00671         if(p->right) {
00672         ADD_STR_VALUE(value,value_size,".");
00673         }
00674       }
00675       p=p->right;
00676       }
00677       *len = strlen(value) + 1;
00678     } 
00679     else if((node->type&CONST_DEFAULT) && (node->value==NULL)){
00680       p=node->down;
00681       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
00682       PUT_STR_VALUE(value, value_size, p->value);
00683       }
00684     else {
00685       PUT_STR_VALUE(value, value_size, node->value);
00686     }
00687     break;
00688   case TYPE_TIME:
00689     PUT_STR_VALUE( value, value_size, node->value);
00690     break;
00691   case TYPE_OCTET_STRING:
00692     len2=-1;
00693     if (_asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
00694     break;
00695   case TYPE_GENERALSTRING:
00696     len2=-1;
00697     if (_asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
00698     break;
00699   case TYPE_BIT_STRING:
00700     len2=-1;
00701     if (_asn1_get_bit_der(node->value,node->value_len,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
00702     break;
00703   case TYPE_CHOICE:
00704     PUT_STR_VALUE( value, value_size, node->down->name);
00705     break; 
00706   case TYPE_ANY:
00707     len3=-1;
00708     len2=_asn1_get_length_der(node->value,node->value_len,&len3);
00709     if (len2 < 0) return ASN1_DER_ERROR;
00710     PUT_VALUE( value, value_size, node->value+len3, len2);
00711     break;
00712   default:
00713     return  ASN1_ELEMENT_NOT_FOUND;
00714     break;
00715   }
00716   return ASN1_SUCCESS;
00717 }
00718 
00719 
00720 /**
00721   * asn1_read_tag - Returns the TAG of one element inside a structure
00722   * @root: pointer to a structure
00723   * @name: the name of the element inside a structure.
00724   * @tagValue:  variable that will contain the TAG value. 
00725   * @classValue: variable that will specify the TAG type.
00726   *
00727   * Description:
00728   *
00729   * Returns the TAG and the CLASS of one element inside a structure.
00730   * CLASS can have one of these constants: ASN1_CLASS_APPLICATION,
00731   * ASN1_CLASS_UNIVERSAL, ASN1_CLASS_PRIVATE or ASN1_CLASS_CONTEXT_SPECIFIC.
00732   * 
00733   * Returns:
00734   *
00735   *   ASN1_SUCCESS\: set value OK
00736   *
00737   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
00738   * 
00739   **/
00740 asn1_retCode 
00741 asn1_read_tag(node_asn *root,const char *name,int *tagValue, int *classValue)
00742 {
00743   node_asn *node,*p,*pTag;
00744  
00745   node=_asn1_find_node(root,name);
00746   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
00747 
00748   p=node->down;
00749 
00750   /* pTag will points to the IMPLICIT TAG */
00751   pTag=NULL;
00752   if(node->type&CONST_TAG){
00753     while(p){
00754       if(type_field(p->type)==TYPE_TAG){
00755       if((p->type&CONST_IMPLICIT) && (pTag==NULL))
00756         pTag=p;
00757       else if(p->type&CONST_EXPLICIT)
00758         pTag=NULL;
00759       }
00760       p=p->right;
00761     }
00762   }
00763 
00764   if(pTag){
00765     *tagValue=strtoul(pTag->value,NULL,10);
00766   
00767     if(pTag->type&CONST_APPLICATION) *classValue=ASN1_CLASS_APPLICATION;
00768     else if(pTag->type&CONST_UNIVERSAL) *classValue=ASN1_CLASS_UNIVERSAL;
00769     else if(pTag->type&CONST_PRIVATE) *classValue=ASN1_CLASS_PRIVATE;
00770     else *classValue=ASN1_CLASS_CONTEXT_SPECIFIC;
00771   }
00772   else{
00773     *classValue=ASN1_CLASS_UNIVERSAL;
00774 
00775     switch(type_field(node->type)){
00776     case TYPE_NULL:
00777       *tagValue=ASN1_TAG_NULL;break;
00778     case TYPE_BOOLEAN:
00779       *tagValue=ASN1_TAG_BOOLEAN;break;
00780     case TYPE_INTEGER:
00781       *tagValue=ASN1_TAG_INTEGER;break;
00782     case TYPE_ENUMERATED:
00783       *tagValue=ASN1_TAG_ENUMERATED;break;
00784     case TYPE_OBJECT_ID:
00785       *tagValue=ASN1_TAG_OBJECT_ID;break;
00786     case TYPE_TIME:
00787       if(node->type&CONST_UTC){
00788       *tagValue=ASN1_TAG_UTCTime;
00789       }
00790       else *tagValue=ASN1_TAG_GENERALIZEDTime;
00791       break;
00792     case TYPE_OCTET_STRING:
00793       *tagValue=ASN1_TAG_OCTET_STRING;break;
00794     case TYPE_GENERALSTRING:
00795       *tagValue=ASN1_TAG_GENERALSTRING;break;
00796     case TYPE_BIT_STRING:
00797       *tagValue=ASN1_TAG_BIT_STRING;break;
00798     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
00799       *tagValue=ASN1_TAG_SEQUENCE;break;
00800     case TYPE_SET: case TYPE_SET_OF:
00801       *tagValue=ASN1_TAG_SET;break;
00802     case TYPE_TAG:
00803     case TYPE_CHOICE:
00804     case TYPE_ANY:
00805       break;
00806     default:
00807       break;
00808     }
00809   }
00810 
00811 
00812   return ASN1_SUCCESS;
00813 
00814 }
00815 
00816 
00817 
00818 

Generated by  Doxygen 1.5.1