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

parser_aux.c

00001 /*
00002  *      Copyright (C) 2000,2001 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 #include <int.h>
00022 #include <errors.h>
00023 #include "parser_aux.h"
00024 #include "der.h"
00025 #include "gstr.h"
00026 #include "structure.h"
00027 #include "element.h"
00028 
00029 char _asn1_identifierMissing[MAX_NAME_SIZE+1]; /* identifier name not found */
00030 
00031 /***********************************************/
00032 /* Type: list_type                             */
00033 /* Description: type used in the list during   */
00034 /* the structure creation.                     */
00035 /***********************************************/
00036 typedef struct list_struct{
00037   node_asn           *node;
00038   struct list_struct *next;
00039 } list_type;
00040 
00041 
00042 /* Pointer to the first element of the list */
00043 list_type *firstElement=NULL;
00044 
00045 /******************************************************/
00046 /* Function : _asn1_add_node                          */
00047 /* Description: creates a new NODE_ASN element and    */
00048 /* puts it in the list pointed by firstElement.       */
00049 /* Parameters:                                        */
00050 /*   type: type of the new element (see TYPE_         */
00051 /*         and CONST_ constants).                     */
00052 /* Return: pointer to the new element.                */
00053 /******************************************************/
00054 node_asn *
00055 _asn1_add_node(unsigned int type)
00056 {
00057   list_type *listElement;
00058   node_asn *punt;
00059 
00060   punt=(node_asn *) _asn1_malloc(sizeof(node_asn));
00061   if (punt==NULL) return NULL;
00062   
00063   listElement=(list_type *) _asn1_malloc(sizeof(list_type));
00064   if(listElement==NULL){
00065     _asn1_free(punt);
00066     return NULL;
00067   }
00068 
00069   listElement->node=punt;
00070   listElement->next=firstElement;
00071   firstElement=listElement;
00072 
00073   punt->left=NULL;
00074   punt->name=NULL;
00075   punt->type=type; 
00076   punt->value=NULL;
00077   punt->down=NULL;
00078   punt->right=NULL; 
00079 
00080   return punt;
00081 }
00082 
00083 /******************************************************************/
00084 /* Function : _asn1_find_mode                                     */
00085 /* Description: searches an element called NAME starting from     */
00086 /*              POINTER. The name is composed by differents       */
00087 /*              identifiers separated by dots.When *POINTER has a */
00088 /*              name, the first identifier must be the name of    */
00089 /*              *POINTER, otherwise it must be the name of one    */
00090 /*              child of *POINTER.                                */
00091 /* Parameters:                                                    */
00092 /*   pointer: NODE_ASN element pointer.                           */
00093 /*   name: null terminated string with the element's name to find.*/
00094 /* Return: the searching result. NULL if not find.                */
00095 /******************************************************************/
00096 node_asn *
00097 _asn1_find_node(node_asn *pointer,const char *name)
00098 {
00099   node_asn *p;
00100   char *n_end,n[MAX_NAME_SIZE+1];
00101   const char *n_start;
00102 
00103   if(pointer == NULL) return NULL;
00104 
00105   if(name==NULL) return NULL;
00106 
00107   p=pointer;
00108   n_start=name;
00109 
00110   if(p->name != NULL){ /* has *pointer a name ? */
00111     n_end=strchr(n_start,'.');     /* search the first dot */
00112     if(n_end){
00113       memcpy(n,n_start,n_end-n_start);
00114       n[n_end-n_start]=0;
00115       n_start=n_end;
00116       n_start++;
00117     }
00118     else{
00119       _asn1_str_cpy(n,sizeof(n),n_start);
00120       n_start=NULL;
00121     }
00122     
00123     while(p){
00124       if((p->name) && (!strcmp(p->name,n))) break;
00125       else p=p->right;
00126     } /* while */
00127     
00128     if(p==NULL) return NULL;
00129   }
00130   else{ /* *pointer doesn't have a name */
00131     if(n_start[0]==0)
00132       return p;
00133   }
00134 
00135   while(n_start){   /* Has the end of NAME been reached? */
00136     n_end=strchr(n_start,'.');    /* search the next dot */
00137     if(n_end){
00138       memcpy(n,n_start,n_end-n_start);
00139       n[n_end-n_start]=0;
00140       n_start=n_end;
00141       n_start++;
00142     }
00143     else{
00144       _asn1_str_cpy(n,sizeof(n),n_start);
00145       n_start=NULL;
00146     }
00147 
00148     if(p->down==NULL) return NULL;
00149 
00150     p=p->down;
00151 
00152     /* The identifier "?LAST" indicates the last element 
00153        in the right chain. */
00154     if(!strcmp(n,"?LAST")){
00155       if(p==NULL) return NULL;
00156       while(p->right) p=p->right;
00157     }
00158     else{   /* no "?LAST" */
00159       while(p){
00160       if((p->name) && (!strcmp(p->name,n))) break;
00161       else p=p->right;
00162       }
00163       if(p==NULL) return NULL;
00164     }
00165   } /* while */
00166 
00167   return p;
00168 }
00169 
00170 
00171 /******************************************************************/
00172 /* Function : _asn1_set_value                                     */
00173 /* Description: sets the field VALUE in a NODE_ASN element. The   */
00174 /*              previus value (if exist) will be lost             */
00175 /* Parameters:                                                    */
00176 /*   node: element pointer.                                       */
00177 /*   value: pointer to the value that you want to set.            */
00178 /*   len: character number of value.                              */
00179 /* Return: pointer to the NODE_ASN element.                       */
00180 /******************************************************************/
00181 node_asn *
00182 _asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len)
00183 {
00184 
00185   if(node==NULL) return node;
00186   if(node->value){
00187     _asn1_free(node->value);
00188     node->value=NULL;  
00189     node->value_len = 0;
00190   }
00191   if(!len) return node;
00192   node->value=(unsigned char *) _asn1_malloc(len);
00193   if (node->value==NULL) return NULL;
00194   node->value_len = len;
00195   
00196   memcpy(node->value,value,len);
00197   return node;
00198 }
00199 
00200 /******************************************************************/
00201 /* Function : _asn1_set_name                                      */
00202 /* Description: sets the field NAME in a NODE_ASN element. The    */
00203 /*              previus value (if exist) will be lost             */
00204 /* Parameters:                                                    */
00205 /*   node: element pointer.                                       */
00206 /*   name: a null terminated string with the name that you want   */
00207 /*         to set.                                                */
00208 /* Return: pointer to the NODE_ASN element.                       */
00209 /******************************************************************/
00210 node_asn *
00211 _asn1_set_name(node_asn *node,const char *name)
00212 {
00213   if(node==NULL) return node;
00214 
00215   if(node->name){
00216     _asn1_free(node->name);
00217     node->name=NULL;
00218   }
00219 
00220   if(name==NULL) return node;
00221 
00222   if(strlen(name))
00223       {
00224       node->name=(char *) _asn1_strdup( name);
00225       if (node->name==NULL) return NULL;
00226       }
00227   else node->name=NULL;
00228   return node;
00229 }
00230 
00231 /******************************************************************/
00232 /* Function : _asn1_set_right                                     */
00233 /* Description: sets the field RIGHT in a NODE_ASN element.       */
00234 /* Parameters:                                                    */
00235 /*   node: element pointer.                                       */
00236 /*   right: pointer to a NODE_ASN element that you want be pointed*/
00237 /*          by NODE.                                              */
00238 /* Return: pointer to *NODE.                                      */
00239 /******************************************************************/
00240 node_asn *
00241 _asn1_set_right(node_asn *node,node_asn *right)
00242 {
00243   if(node==NULL) return node;
00244   node->right=right;
00245   if(right) right->left=node;
00246   return node;
00247 }
00248 
00249 /******************************************************************/
00250 /* Function : _asn1_get_right                                     */
00251 /* Description: returns the element pointed by the RIGHT field of */
00252 /*              a NODE_ASN element.                               */
00253 /* Parameters:                                                    */
00254 /*   node: NODE_ASN element pointer.                              */
00255 /* Return: field RIGHT of NODE.                                   */
00256 /******************************************************************/
00257 node_asn *
00258 _asn1_get_right(node_asn *node)
00259 {
00260   if(node==NULL) return NULL;
00261   return node->right;
00262 }
00263 
00264 /******************************************************************/
00265 /* Function : _asn1_get_last_right                                */
00266 /* Description: return the last element along the right chain.    */
00267 /* Parameters:                                                    */
00268 /*   node: starting element pointer.                              */
00269 /* Return: pointer to the last element along the right chain.     */
00270 /******************************************************************/
00271 node_asn *
00272 _asn1_get_last_right(node_asn *node)
00273 {
00274   node_asn *p;
00275 
00276   if(node==NULL) return NULL;
00277   p=node;
00278   while(p->right) p=p->right;
00279   return p;
00280 }
00281 
00282 /******************************************************************/
00283 /* Function : _asn1_set_down                                      */
00284 /* Description: sets the field DOWN in a NODE_ASN element.        */
00285 /* Parameters:                                                    */
00286 /*   node: element pointer.                                       */
00287 /*   down: pointer to a NODE_ASN element that you want be pointed */
00288 /*          by NODE.                                              */
00289 /* Return: pointer to *NODE.                                      */
00290 /******************************************************************/
00291 node_asn *
00292 _asn1_set_down(node_asn *node,node_asn *down)
00293 {
00294   if(node==NULL) return node;
00295   node->down=down;
00296   if(down) down->left=node;
00297   return node;
00298 }
00299 
00300 /******************************************************************/
00301 /* Function : _asn1_get_down                                      */
00302 /* Description: returns the element pointed by the DOWN field of  */
00303 /*              a NODE_ASN element.                               */
00304 /* Parameters:                                                    */
00305 /*   node: NODE_ASN element pointer.                              */
00306 /* Return: field DOWN of NODE.                                    */
00307 /******************************************************************/
00308 node_asn *
00309 _asn1_get_down(node_asn *node)
00310 {
00311   if(node==NULL) return NULL;
00312   return node->down;
00313 }
00314 
00315 /******************************************************************/
00316 /* Function : _asn1_get_name                                      */
00317 /* Description: returns the name of a NODE_ASN element.           */
00318 /* Parameters:                                                    */
00319 /*   node: NODE_ASN element pointer.                              */
00320 /* Return: a null terminated string.                              */
00321 /******************************************************************/
00322 char *
00323 _asn1_get_name(node_asn *node)
00324 {
00325   if(node==NULL) return NULL;
00326   return node->name;
00327 }
00328 
00329 /******************************************************************/
00330 /* Function : _asn1_mod_type                                      */
00331 /* Description: change the field TYPE of an NODE_ASN element.     */
00332 /*              The new value is the old one | (bitwise or) the   */
00333 /*              paramener VALUE.                                  */
00334 /* Parameters:                                                    */
00335 /*   node: NODE_ASN element pointer.                              */
00336 /*   value: the integer value that must be or-ed with the current */
00337 /*          value of field TYPE.                                  */
00338 /* Return: NODE pointer.                                          */
00339 /******************************************************************/
00340 node_asn *
00341 _asn1_mod_type(node_asn *node,unsigned int value)
00342 {
00343   if(node==NULL) return node;
00344   node->type|=value;
00345   return node;
00346 }
00347 
00348 
00349 /******************************************************************/
00350 /* Function : _asn1_remove_node                                   */
00351 /* Description: gets free the memory allocated for an NODE_ASN    */
00352 /*              element (not the elements pointed by it).         */
00353 /* Parameters:                                                    */
00354 /*   node: NODE_ASN element pointer.                              */
00355 /******************************************************************/
00356 void
00357 _asn1_remove_node(node_asn *node)
00358 {
00359   if(node==NULL) return;
00360 
00361   if (node->name!=NULL)
00362         _asn1_free(node->name);
00363   if (node->value!=NULL)
00364         _asn1_free(node->value);
00365   _asn1_free(node);
00366 }
00367 
00368 /******************************************************************/
00369 /* Function : _asn1_find_up                                       */
00370 /* Description: return the father of the NODE_ASN element.        */
00371 /* Parameters:                                                    */
00372 /*   node: NODE_ASN element pointer.                              */
00373 /* Return: Null if not found.                                     */ 
00374 /******************************************************************/
00375 node_asn *
00376 _asn1_find_up(node_asn *node)
00377 {
00378   node_asn *p;
00379 
00380   if(node==NULL) return NULL;
00381 
00382   p=node;
00383 
00384   while((p->left!=NULL) && (p->left->right==p)) p=p->left;
00385 
00386   return p->left;
00387 }
00388 
00389 /******************************************************************/
00390 /* Function : _asn1_delete_list                                   */
00391 /* Description: deletes the list elements (not the elements       */
00392 /*  pointed by them).                                             */
00393 /******************************************************************/
00394 void
00395 _asn1_delete_list(void)
00396 {
00397   list_type *listElement;
00398 
00399   while(firstElement){
00400     listElement=firstElement;
00401     firstElement=firstElement->next;
00402     _asn1_free(listElement);
00403   }
00404 }
00405 
00406 /******************************************************************/
00407 /* Function : _asn1_delete_list_and nodes                         */
00408 /* Description: deletes the list elements and the elements        */
00409 /*  pointed by them.                                              */
00410 /******************************************************************/
00411 void
00412 _asn1_delete_list_and_nodes(void)
00413 {
00414   list_type *listElement;
00415 
00416   while(firstElement){
00417     listElement=firstElement;
00418     firstElement=firstElement->next;
00419     _asn1_remove_node(listElement->node);
00420     _asn1_free(listElement);
00421   }
00422 }
00423 
00424 
00425 char *
00426 _asn1_ltostr(long v,char *str)
00427 {
00428   long d,r;
00429   char temp[20];
00430   int count,k,start;
00431 
00432   if(v<0){
00433     str[0]='-';
00434     start=1;
00435     v=-v;
00436   }
00437   else start=0;
00438 
00439   count=0;
00440   do{
00441     d=v/10;
00442     r=v-d*10;
00443     temp[start+count]='0'+(char)r;
00444     count++;
00445     v=d;
00446   }while(v);
00447 
00448   for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
00449   str[count+start]=0;
00450   return str;
00451 }
00452 
00453 
00454 /******************************************************************/
00455 /* Function : _asn1_change_integer_value                          */
00456 /* Description: converts into DER coding the value assign to an   */
00457 /*   INTEGER constant.                                            */
00458 /* Parameters:                                                    */
00459 /*   node: root of an ASN1element.                                */
00460 /* Return:                                                        */
00461 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
00462 /*   otherwise ASN1_SUCCESS                                             */
00463 /******************************************************************/
00464 asn1_retCode 
00465 _asn1_change_integer_value(ASN1_TYPE node)
00466 {
00467   node_asn *p;
00468   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
00469   unsigned char val2[SIZEOF_UNSIGNED_LONG_INT+1];
00470   int len;
00471 
00472   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00473 
00474   p=node;
00475   while(p){
00476     if((type_field(p->type)==TYPE_INTEGER) && (p->type&CONST_ASSIGN)){
00477       if(p->value){
00478       _asn1_convert_integer(p->value,val,sizeof(val), &len);      
00479       _asn1_octet_der(val,len,val2,&len);
00480       _asn1_set_value(p,val2,len);
00481       }
00482     }
00483 
00484     if(p->down){
00485       p=p->down;
00486     }
00487     else{
00488       if(p==node) p=NULL;
00489       else if(p->right) p=p->right;
00490       else{
00491       while(1){
00492         p=_asn1_find_up(p);
00493         if(p==node){
00494           p=NULL;
00495           break;
00496         }
00497         if(p->right){
00498           p=p->right;
00499           break;
00500         }
00501       }
00502       }
00503     }
00504   }
00505 
00506   return ASN1_SUCCESS;
00507 }
00508 
00509 
00510 /******************************************************************/
00511 /* Function : _asn1_expand_object_id                              */
00512 /* Description: expand the IDs of an OBJECT IDENTIFIER constant.  */
00513 /* Parameters:                                                    */
00514 /*   node: root of an ASN1 element.                               */
00515 /* Return:                                                        */
00516 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
00517 /*   otherwise ASN1_SUCCESS                                             */
00518 /******************************************************************/
00519 asn1_retCode
00520 _asn1_expand_object_id(ASN1_TYPE node)
00521 {
00522   node_asn *p,*p2,*p3,*p4,*p5;
00523   char name_root[MAX_NAME_SIZE],name2[2*MAX_NAME_SIZE+1];
00524   int move;
00525  
00526   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00527 
00528   _asn1_str_cpy(name_root, sizeof(name_root), node->name);
00529 
00530   p=node;
00531   move=DOWN;
00532 
00533   while(!((p==node) && (move==UP))){
00534     if(move!=UP){
00535       if((type_field(p->type)==TYPE_OBJECT_ID) && (p->type&CONST_ASSIGN)){
00536       p2=p->down;
00537         if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
00538         if(p2->value && !isdigit(p2->value[0])){
00539           _asn1_str_cpy(name2, sizeof(name2), name_root);
00540           _asn1_str_cat(name2, sizeof(name2), ".");
00541           _asn1_str_cat(name2, sizeof(name2), p2->value);
00542           p3=_asn1_find_node(node,name2);
00543           if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
00544              !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
00545           _asn1_set_down(p,p2->right);
00546           _asn1_remove_node(p2);
00547           p2=p;
00548           p4=p3->down;
00549           while(p4){
00550             if(type_field(p4->type)==TYPE_CONSTANT){
00551             p5=_asn1_add_node_only(TYPE_CONSTANT);
00552             _asn1_set_name(p5,p4->name);
00553             _asn1_set_value(p5,p4->value,strlen(p4->value)+1);
00554             if(p2==p){
00555               _asn1_set_right(p5,p->down);
00556               _asn1_set_down(p,p5);
00557             }
00558             else{
00559               _asn1_set_right(p5,p2->right);
00560               _asn1_set_right(p2,p5);
00561             }
00562             p2=p5;
00563             }
00564             p4=p4->right;
00565           }
00566           move=DOWN;
00567           continue;
00568         }
00569       }
00570       }
00571       move=DOWN;
00572     }
00573     else move=RIGHT;
00574 
00575     if(move==DOWN){
00576       if(p->down) p=p->down;
00577       else move=RIGHT;
00578     }
00579     
00580     if(p==node) {move=UP; continue;}
00581 
00582     if(move==RIGHT){
00583       if(p->right) p=p->right;
00584       else move=UP;
00585     }
00586     if(move==UP) p=_asn1_find_up(p);
00587   }
00588 
00589 
00590   /*******************************/
00591   /*       expand DEFAULT        */
00592   /*******************************/
00593   p=node;
00594   move=DOWN;
00595 
00596   while(!((p==node) && (move==UP))){
00597     if(move!=UP){
00598       if((type_field(p->type)==TYPE_OBJECT_ID) && 
00599        (p->type&CONST_DEFAULT)){
00600       p2=p->down;
00601         if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
00602         _asn1_str_cpy(name2, sizeof(name2), name_root);
00603         _asn1_str_cat(name2, sizeof(name2), ".");
00604         _asn1_str_cat(name2, sizeof(name2), p2->value);
00605         p3=_asn1_find_node(node,name2);
00606         if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
00607            !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
00608         p4=p3->down;
00609         name2[0]=0;
00610         while(p4){
00611           if(type_field(p4->type)==TYPE_CONSTANT){
00612             if(name2[0]) _asn1_str_cat(name2,sizeof(name2),".");
00613             _asn1_str_cat(name2,sizeof(name2),p4->value);
00614           }
00615           p4=p4->right;
00616         }
00617         _asn1_set_value(p2,name2,strlen(name2)+1);
00618       }
00619       }
00620       move=DOWN;
00621     }
00622     else move=RIGHT;
00623 
00624     if(move==DOWN){
00625       if(p->down) p=p->down;
00626       else move=RIGHT;
00627     }
00628     
00629     if(p==node) {move=UP; continue;}
00630 
00631     if(move==RIGHT){
00632       if(p->right) p=p->right;
00633       else move=UP;
00634     }
00635     if(move==UP) p=_asn1_find_up(p);
00636   }
00637 
00638   return ASN1_SUCCESS;
00639 }
00640 
00641 
00642 /******************************************************************/
00643 /* Function : _asn1_type_set_config                               */
00644 /* Description: sets the CONST_SET and CONST_NOT_USED properties  */
00645 /*   in the fields of the SET elements.                           */
00646 /* Parameters:                                                    */
00647 /*   node: root of an ASN1 element.                               */
00648 /* Return:                                                        */
00649 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
00650 /*   otherwise ASN1_SUCCESS                                             */
00651 /******************************************************************/
00652 asn1_retCode 
00653 _asn1_type_set_config(ASN1_TYPE node)
00654 {
00655   node_asn *p,*p2;
00656   int move;
00657  
00658   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00659 
00660   p=node;
00661   move=DOWN;
00662 
00663   while(!((p==node) && (move==UP))){
00664     if(move!=UP){
00665       if(type_field(p->type)==TYPE_SET){
00666       p2=p->down;
00667       while(p2){
00668         if(type_field(p2->type)!=TYPE_TAG) 
00669           p2->type|=CONST_SET|CONST_NOT_USED;
00670         p2=p2->right;
00671       }
00672       }
00673       move=DOWN;
00674     }
00675     else move=RIGHT;
00676 
00677     if(move==DOWN){
00678       if(p->down) p=p->down;
00679       else move=RIGHT;
00680     }
00681 
00682     if(p==node) {move=UP; continue;}
00683 
00684     if(move==RIGHT){
00685       if(p->right) p=p->right;
00686       else move=UP;
00687     }
00688     if(move==UP) p=_asn1_find_up(p);
00689   }
00690 
00691   return ASN1_SUCCESS;
00692 }
00693 
00694 
00695 /******************************************************************/
00696 /* Function : _asn1_check_identifier                              */
00697 /* Description: checks the definitions of all the identifiers     */
00698 /*   and the first element of an OBJECT_ID (e.g. {pkix 0 4}).     */
00699 /*   The _asn1_identifierMissing global variable is filled if     */
00700 /*   necessary.                                                   */
00701 /* Parameters:                                                    */
00702 /*   node: root of an ASN1 element.                               */
00703 /* Return:                                                        */
00704 /*   ASN1_ELEMENT_NOT_FOUND      if NODE is NULL,                 */
00705 /*   ASN1_IDENTIFIER_NOT_FOUND   if an identifier is not defined, */
00706 /*   otherwise ASN1_SUCCESS                                       */
00707 /******************************************************************/
00708 asn1_retCode 
00709 _asn1_check_identifier(ASN1_TYPE node)
00710 {
00711   node_asn *p,*p2;
00712   char name2[MAX_NAME_SIZE*2+2];
00713 
00714   if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00715 
00716   p=node;
00717   while(p){
00718     if(type_field(p->type)==TYPE_IDENTIFIER){
00719       _asn1_str_cpy(name2, sizeof(name2), node->name);
00720       _asn1_str_cat(name2, sizeof(name2), ".");
00721       _asn1_str_cat(name2, sizeof(name2), p->value);
00722       p2=_asn1_find_node(node,name2);
00723       if(p2==NULL){
00724       strcpy(_asn1_identifierMissing,p->value);
00725       return ASN1_IDENTIFIER_NOT_FOUND;
00726       } 
00727     }
00728     else if((type_field(p->type)==TYPE_OBJECT_ID) && 
00729           (p->type&CONST_DEFAULT)){
00730       p2=p->down;
00731       if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
00732       _asn1_str_cpy(name2, sizeof(name2), node->name);
00733       _asn1_str_cat(name2, sizeof(name2), ".");
00734       _asn1_str_cat(name2, sizeof(name2), p2->value);
00735       strcpy(_asn1_identifierMissing,p2->value);
00736       p2=_asn1_find_node(node,name2);
00737       if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
00738          !(p2->type&CONST_ASSIGN))
00739         return ASN1_IDENTIFIER_NOT_FOUND;
00740       else
00741         _asn1_identifierMissing[0]=0;
00742       }
00743     }
00744     else if((type_field(p->type)==TYPE_OBJECT_ID) && 
00745           (p->type&CONST_ASSIGN)){
00746       p2=p->down;
00747       if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
00748       if(p2->value && !isdigit(p2->value[0])){
00749         _asn1_str_cpy(name2, sizeof(name2), node->name);
00750         _asn1_str_cat(name2, sizeof(name2), ".");
00751         _asn1_str_cat(name2, sizeof(name2), p2->value);
00752         strcpy(_asn1_identifierMissing,p2->value);
00753         p2=_asn1_find_node(node,name2);
00754         if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
00755            !(p2->type&CONST_ASSIGN))
00756           return ASN1_IDENTIFIER_NOT_FOUND;
00757         else
00758           _asn1_identifierMissing[0]=0;
00759       }
00760       }
00761     }
00762     
00763     if(p->down){
00764       p=p->down;
00765     }
00766     else if(p->right) p=p->right;
00767     else{
00768       while(1){
00769       p=_asn1_find_up(p);
00770       if(p==node){
00771         p=NULL;
00772         break;
00773       }
00774       if(p->right){
00775         p=p->right;
00776         break;
00777       }
00778       }
00779     }
00780   }
00781 
00782   return ASN1_SUCCESS;
00783 }
00784 
00785 
00786 /******************************************************************/
00787 /* Function : _asn1_set_default_tag                               */
00788 /* Description: sets the default IMPLICIT or EXPLICIT property in */
00789 /*   the tagged elements that don't have this declaration.        */
00790 /* Parameters:                                                    */
00791 /*   node: pointer to a DEFINITIONS element.                      */
00792 /* Return:                                                        */
00793 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to    */
00794 /*     a DEFINITIONS element,                                     */
00795 /*   otherwise ASN1_SUCCESS                                             */
00796 /******************************************************************/
00797 asn1_retCode 
00798 _asn1_set_default_tag(ASN1_TYPE node)
00799 {
00800   node_asn *p;
00801 
00802   if((node==NULL) || (type_field(node->type)!=TYPE_DEFINITIONS))
00803     return ASN1_ELEMENT_NOT_FOUND; 
00804 
00805   p=node;
00806   while(p){
00807     if((type_field(p->type)==TYPE_TAG) &&
00808           !(p->type&CONST_EXPLICIT) &&
00809           !(p->type&CONST_IMPLICIT)){
00810       if(node->type&CONST_EXPLICIT) p->type|=CONST_EXPLICIT;
00811       else p->type|=CONST_IMPLICIT;
00812     }
00813 
00814     if(p->down){
00815       p=p->down;
00816     }
00817     else if(p->right) p=p->right;
00818     else{
00819       while(1){
00820         p=_asn1_find_up(p);
00821         if(p==node){
00822           p=NULL;
00823           break;
00824         }
00825         if(p->right){
00826           p=p->right;
00827           break;
00828         }
00829       }
00830     }
00831   }
00832 
00833   return ASN1_SUCCESS;
00834 }
00835 
00836 
00837 
00838 static const char*
00839 parse_version_number( const char *s, int *number )
00840 {
00841     int val = 0;
00842 
00843     if( *s == '0' && isdigit(s[1]) )
00844       return NULL; /* leading zeros are not allowed */
00845     for ( ; isdigit(*s); s++ ) {
00846       val *= 10;
00847       val += *s - '0';
00848     }
00849     *number = val;
00850     return val < 0? NULL : s;
00851 }
00852 
00853 /* The parse version functions were copied from libgcrypt.
00854  */
00855 static const char *
00856 parse_version_string( const char *s, int *major, int *minor, int *micro )
00857 {
00858     s = parse_version_number( s, major );
00859     if( !s || *s != '.' )
00860       return NULL;
00861     s++;
00862     s = parse_version_number( s, minor );
00863     if( !s || *s != '.' )
00864       return NULL;
00865     s++;
00866     s = parse_version_number( s, micro );
00867     if( !s )
00868       return NULL;
00869     return s; /* patchlevel */
00870 }
00871 
00872 /**
00873   * asn1_check_version - This function checks the library's version
00874   * @req_version: the version to check
00875   *
00876   * Check that the the version of the library is at minimum the requested one
00877   * and return the version string; return NULL if the condition is not
00878   * satisfied.  If a NULL is passed to this function, no check is done,
00879   * but the version string is simply returned.
00880   *
00881   **/
00882 const char *
00883 asn1_check_version( const char *req_version )
00884 {
00885     const char *ver = LIBTASN1_VERSION;
00886     int my_major, my_minor, my_micro;
00887     int rq_major, rq_minor, rq_micro;
00888     const char *my_plvl, *rq_plvl;
00889 
00890     if ( !req_version )
00891       return ver;
00892 
00893     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
00894     if ( !my_plvl )
00895       return NULL;  /* very strange our own version is bogus */
00896     rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
00897                                                 &rq_micro );
00898     if ( !rq_plvl )
00899       return NULL;  /* req version string is invalid */
00900 
00901     if ( my_major > rq_major
00902       || (my_major == rq_major && my_minor > rq_minor)
00903       || (my_major == rq_major && my_minor == rq_minor
00904                          && my_micro > rq_micro)
00905       || (my_major == rq_major && my_minor == rq_minor
00906                          && my_micro == rq_micro
00907                          && strcmp( my_plvl, rq_plvl ) >= 0) ) {
00908       return ver;
00909     }
00910     return NULL;
00911 }
00912 
00913 

Generated by  Doxygen 1.5.1