OID with dots
[platform/upstream/libtasn1.git] / lib / element.c
1 /*
2  *      Copyright (C) 2000,2001 Fabio Fiorina
3  *
4  * This file is part of LIBASN1.
5  *
6  * The LIBTASN1 library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public   
8  * License as published by the Free Software Foundation; either 
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  */
20
21 /*****************************************************/
22 /* File: element.c                                   */
23 /* Description: Functions with the read and write    */
24 /*   functions.                                      */
25 /*****************************************************/
26
27
28 #include <int.h>
29 #include <errors.h>
30 #include "parser_aux.h"
31 #include "der.h"
32 #include <gstr.h>
33 #include "structure.h"
34
35 void
36 _asn1_hierarchical_name(node_asn *node,char *name,int name_size)
37 {
38   char *aux;
39   node_asn *p;
40   
41   p=node;
42
43   name[0]=0;
44
45   while(p != NULL){
46     if(p->name != NULL){
47       aux=(char*)malloc(strlen(name)+1);
48       strcpy(aux,name);
49       _asn1_str_cpy(name,name_size,p->name);
50       _asn1_str_cat(name,name_size,".");
51       _asn1_str_cat(name,name_size,aux);
52       free(aux);
53     }
54     p=_asn1_find_up(p);
55   }
56   name[strlen(name)-1]=0;
57 }
58
59
60 /******************************************************************/
61 /* Function : _asn1_convert_integer                               */
62 /* Description: converts an integer from a null terminated string */
63 /*              to der decoding. The convertion from a null       */
64 /*              terminated string to an integer is made with      */
65 /*              the 'strtol' function.                            */
66 /* Parameters:                                                    */
67 /*   value: null terminated string to convert.                    */
68 /*   value_out: convertion result (memory must be already         */
69 /*              allocated).                                       */
70 /*   value_out_size: number of bytes of value_out.                */
71 /*   len: number of significant byte of value_out.                */
72 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS                                */
73 /******************************************************************/
74 asn1_retCode
75 _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len)
76 {
77   char negative;
78   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
79   long valtmp;
80   int k,k2;
81
82   valtmp=strtol(value,NULL,10);
83   
84   for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++){
85     val[SIZEOF_UNSIGNED_LONG_INT-k-1]=(valtmp >> (8*k)) & 0xFF;
86   }
87
88   if(val[0]&0x80) negative=1;
89   else negative=0;
90   
91   for(k=0;k<SIZEOF_UNSIGNED_LONG_INT-1;k++){
92     if(negative && (val[k]!=0xFF)) break;
93     else if(!negative && val[k]) break;
94   }
95         
96   if((negative && !(val[k]&0x80)) ||
97      (!negative && (val[k]&0x80))) k--; 
98
99   if (SIZEOF_UNSIGNED_LONG_INT-k> value_out_size)
100     /* VALUE_OUT is too short to contain the value convertion */
101     return ASN1_MEM_ERROR;
102
103   for(k2=k;k2<SIZEOF_UNSIGNED_LONG_INT;k2++)
104     value_out[k2-k]=val[k2];
105
106   *len=SIZEOF_UNSIGNED_LONG_INT-k;
107
108
109 #ifdef LIBTASN1_DEBUG_INTEGER
110   _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value,*len);
111   for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++)
112     _libtasn1_log(", vOut[%d]=%d",k,value_out[k]);
113   _libtasn1_log("\n");
114 #endif
115
116
117   return ASN1_SUCCESS;
118 }
119
120
121 int 
122 _asn1_append_sequence_set(node_asn *node)
123 {
124   node_asn *p,*p2;
125   char temp[10];
126   long n;
127
128   if(!node || !(node->down)) return ASN1_GENERIC_ERROR;
129
130   p=node->down;
131   while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
132   p2=_asn1_copy_structure3(p);
133   while(p->right) p=p->right;
134   _asn1_set_right(p,p2);
135   
136   if(p->name==NULL) _asn1_str_cpy(temp,sizeof(temp),"?1");
137   else{
138     n=strtol(p->name+1,NULL,0);
139     n++;
140     temp[0]='?';
141     _asn1_ltostr(n,temp+1);
142   } 
143   _asn1_set_name(p2,temp);
144   p2->type |= CONST_OPTION;
145
146   return ASN1_SUCCESS;
147 }
148
149
150 /**
151   * asn1_write_value - Set the value of one element inside a structure.
152   * @node_root: pointer to a structure
153   * @name: the name of the element inside the structure that you want to set.
154   * @value: vector used to specify the value to set. If len is >0, 
155   * VALUE must be a two's complement form integer.
156   * if len=0 *VALUE must be a null terminated string with an integer value. 
157   * @len: number of bytes of *value to use to set the value: value[0]..value[len-1]
158   *  or 0 if value is a null terminated string
159   * Description:
160   *
161   * Set the value of one element inside a structure.
162   * 
163   * Returns:
164   * 
165   *   ASN1_SUCCESS\: set value OK
166   *
167   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
168   *
169   *   ASN1_VALUE_NOT_VALID\: VALUE has a wrong format.
170   * 
171   * Examples:  
172   *   description for each type
173   *
174   *\begin{itemize}
175   * \item INTEGER\: VALUE must contain a two's complement form integer.
176   *            value[0]=0xFF ,               len=1 -> integer=-1
177   *            value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1
178   *            value[0]=0x01 ,               len=1 -> integer= 1
179   *            value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1
180   *            value="123"                 , len=0 -> integer= 123
181   *
182   * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
183   *
184   * \item BOOLEAN\: VALUE must be the null terminated string "TRUE" or "FALSE" and LEN != 0
185   *            value="TRUE" , len=1 -> boolean=TRUE
186   *            value="FALSE" , len=1 -> boolean=FALSE
187   *
188   * \item OBJECT IDENTIFIER\: VALUE must be a null terminated string with each number separated by
189   *                      a dot (e.g. "1.2.3.543.1"). 
190   *                      LEN != 0
191   *            value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha
192   *
193   * \item UTCTime\: VALUE must be a null terminated string in one of these formats\:
194   *            "YYMMDDhhmmssZ" "YYMMDDhhmmssZ" "YYMMDDhhmmss+hh'mm'" "YYMMDDhhmmss-hh'mm'"
195   *            "YYMMDDhhmm+hh'mm'" "YYMMDDhhmm-hh'mm'".  
196   *            LEN != 0
197   *            value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 at 12h 00m  Greenwich Mean Time
198   *
199   * \item GeneralizedTime\: VALUE must be in one of this format\:
200   *                    "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.s+hh'mm'" 
201   *                    "YYYYMMDDhhmmss.s-hh'mm'" "YYYYMMDDhhmm+hh'mm'" "YYYYMMDDhhmm-hh'mm'" 
202   *                    where ss.s indicates the seconds with any precision like "10.1" or "01.02".
203   *                    LEN != 0
204   *            value="2001010112001.12-0700" , len=1 -> time=Jannuary 1st, 2001 at 12h 00m 01.12s 
205   *                                                     Pacific Daylight Time
206   *
207   * \item OCTET STRING\: VALUE contains the octet string and LEN is the number of octet.
208   *            value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3  -> three bytes octet string
209   *
210   * \item GeneralString\: VALUE contains the generalstring and LEN is the number of octet.
211   *            value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3  -> three bytes generalstring
212   *
213   * \item BIT STRING\: VALUE contains the bit string organized by bytes and LEN is the number of bits.
214   *            value="$\backslash$xCF" , len=6 -> bit string="110011" (six bits)
215   *
216   * \item CHOICE\: if NAME indicates a choice type, VALUE must specify one of the alternatives with a
217   *           null terminated string. LEN != 0
218   *           Using "pkix.asn"\:
219   *           result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
220   *
221   * \item ANY\: VALUE indicates the der encoding of a structure.
222   *        LEN != 0 
223   *
224   * \item SEQUENCE OF\: VALUE must be the null terminated string "NEW" and LEN != 0. With this 
225   *                instruction another element is appended in the sequence. The name of this
226   *                element will be "?1" if it's the first one, "?2" for the second and so on.
227   *
228   *           Using "pkix.asn"\:   
229   *
230   *           result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
231   *
232   * \item SET OF\: the same as SEQUENCE OF. 
233   *           Using "pkix.asn":
234   *
235   *           result=asn1_write_value(cert,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
236   *\end{itemize}
237   *
238   * If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
239   *
240   *           Using "pkix.asn"\:
241   *
242   *           result=asn1_write_value(cert,"tbsCertificate.issuerUniqueID",NULL,0);
243   * 
244   **/
245 asn1_retCode 
246 asn1_write_value(node_asn *node_root,const char *name,
247                  const unsigned char *value,int len)
248 {
249   node_asn *node,*p,*p2;
250   unsigned char *temp,*value_temp=NULL,*default_temp=NULL;
251   int len2,k,k2,negative;
252
253   node=_asn1_find_node(node_root,name);
254   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
255
256   if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
257     asn1_delete_structure(&node);
258     return ASN1_SUCCESS;
259   }
260
261   if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){
262     p=node->down;
263     while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
264
265     while(p->right)
266       asn1_delete_structure(&p->right);
267
268     return ASN1_SUCCESS;
269   }
270
271   switch(type_field(node->type)){
272   case TYPE_BOOLEAN:
273     if(!strcmp(value,"TRUE")){
274       if(node->type&CONST_DEFAULT){
275         p=node->down;
276         while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
277         if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0);
278         else _asn1_set_value(node,"T",1);
279       }
280       else _asn1_set_value(node,"T",1);
281     }
282     else if(!strcmp(value,"FALSE")){
283       if(node->type&CONST_DEFAULT){
284         p=node->down;
285         while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
286         if(p->type&CONST_FALSE) _asn1_set_value(node,NULL,0);
287         else _asn1_set_value(node,"F",1);
288       }
289       else _asn1_set_value(node,"F",1);
290     }
291     else return ASN1_VALUE_NOT_VALID;
292     break;
293   case TYPE_INTEGER: case TYPE_ENUMERATED:
294     if(len==0){
295       if((isdigit(value[0])) || (value[0]=='-')){
296         value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
297         if (value_temp==NULL) return ASN1_MEM_ERROR;
298
299         _asn1_convert_integer(value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
300       }
301       else{ /* is an identifier like v1 */
302         if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
303         p=node->down;
304         while(p){
305           if(type_field(p->type)==TYPE_CONSTANT){
306             if((p->name) && (!strcmp(p->name,value))){
307               value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
308               if (value_temp==NULL) return ASN1_MEM_ERROR;
309
310               _asn1_convert_integer(p->value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
311               break;
312             }
313           }
314           p=p->right;
315         }
316         if(p==NULL) return ASN1_VALUE_NOT_VALID;
317       }
318     }
319     else{ /* len != 0 */
320       value_temp=(unsigned char *)_asn1_alloca(len);
321       if (value_temp==NULL) return ASN1_MEM_ERROR;
322       memcpy(value_temp,value,len);
323     }
324
325
326     if(value_temp[0]&0x80) negative=1;
327     else negative=0;
328
329     if(negative && (type_field(node->type)==TYPE_ENUMERATED)) 
330       {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;}
331
332     for(k=0;k<len-1;k++)
333       if(negative && (value_temp[k]!=0xFF)) break;
334       else if(!negative && value_temp[k]) break;
335
336     if((negative && !(value_temp[k]&0x80)) ||
337        (!negative && (value_temp[k]&0x80))) k--; 
338
339     _asn1_length_der(len-k,NULL,&len2);
340     temp=(unsigned char *)_asn1_alloca(len-k+len2);
341     if (temp==NULL) return ASN1_MEM_ERROR;
342
343     _asn1_octet_der(value_temp+k,len-k,temp,&len2);
344     _asn1_set_value(node,temp,len2);
345
346     _asn1_afree(temp);
347
348
349     if(node->type&CONST_DEFAULT){
350       p=node->down;
351       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
352       if((isdigit(p->value[0])) || (p->value[0]=='-')){
353         default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
354         if (default_temp==NULL) return ASN1_MEM_ERROR;
355
356         _asn1_convert_integer(p->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
357       }
358       else{ /* is an identifier like v1 */
359         if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
360         p2=node->down;
361         while(p2){
362           if(type_field(p2->type)==TYPE_CONSTANT){
363             if((p2->name) && (!strcmp(p2->name,p->value))){
364               default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
365               if (default_temp==NULL) return ASN1_MEM_ERROR;
366
367               _asn1_convert_integer(p2->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
368               break;
369             }
370           }
371           p2=p2->right;
372         }
373         if(p2==NULL) return ASN1_VALUE_NOT_VALID;
374       }
375
376
377       if((len-k)==len2){
378         for(k2=0;k2<len2;k2++) 
379           if(value_temp[k+k2]!=default_temp[k2]){
380             break;
381           }
382         if(k2==len2) _asn1_set_value(node,NULL,0);
383       }
384       _asn1_afree(default_temp);
385     }
386     _asn1_afree(value_temp);
387     break;
388   case TYPE_OBJECT_ID:
389     for(k=0;k<strlen(value);k++)
390       if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+')) 
391         return ASN1_VALUE_NOT_VALID; 
392     _asn1_set_value(node,value,strlen(value)+1);
393     break;
394   case TYPE_TIME:
395     if(node->type&CONST_UTC){
396       if(strlen(value)<11) return ASN1_VALUE_NOT_VALID;
397       for(k=0;k<10;k++) 
398         if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
399       switch(strlen(value)){
400       case 11:
401       if(value[10]!='Z') return ASN1_VALUE_NOT_VALID;
402       break;
403       case 13:
404         if((!isdigit(value[10])) || (!isdigit(value[11])) ||
405            (value[12]!='Z')) return ASN1_VALUE_NOT_VALID;
406         break;
407       case 15:
408         if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID;
409         for(k=11;k<15;k++) 
410           if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
411         break;
412       case 17:
413         if((!isdigit(value[10])) || (!isdigit(value[11]))) 
414            return ASN1_VALUE_NOT_VALID;
415         if((value[12]!='+') && (value[12]!='-')) return ASN1_VALUE_NOT_VALID;
416         for(k=13;k<17;k++) 
417           if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
418         break; 
419       default:
420         return ASN1_VALUE_NOT_FOUND;
421       }
422       _asn1_set_value(node,value,strlen(value)+1);
423     }
424     else{  /* GENERALIZED TIME */
425       if(value) _asn1_set_value(node,value,strlen(value)+1);
426     }
427     break;
428   case  TYPE_OCTET_STRING:
429     if(len==0)
430       len=strlen(value);
431     _asn1_length_der(len,NULL,&len2);
432     temp=(unsigned char *)_asn1_alloca(len+len2);
433     if (temp==NULL) return ASN1_MEM_ERROR;
434
435     _asn1_octet_der(value,len,temp,&len2);
436     _asn1_set_value(node,temp,len2);
437     _asn1_afree(temp);
438     break;
439   case  TYPE_GENERALSTRING:
440     if(len==0)
441       len=strlen(value);
442     _asn1_length_der(len,NULL,&len2);
443     temp=(unsigned char *)_asn1_alloca(len+len2);
444     if (temp==NULL) return ASN1_MEM_ERROR;
445
446     _asn1_octet_der(value,len,temp,&len2);
447     _asn1_set_value(node,temp,len2);
448     _asn1_afree(temp);
449     break;
450   case  TYPE_BIT_STRING:
451     if(len==0)
452       len=strlen(value);
453     _asn1_length_der((len>>3)+2,NULL,&len2);
454     temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2);
455     if (temp==NULL) return ASN1_MEM_ERROR;
456
457     _asn1_bit_der(value,len,temp,&len2);
458     _asn1_set_value(node,temp,len2);
459     _asn1_afree(temp);
460     break;
461   case  TYPE_CHOICE:
462     p=node->down;
463     while(p){
464       if(!strcmp(p->name,value)){
465         p2=node->down;
466         while(p2){
467           if(p2!=p){asn1_delete_structure(&p2); p2=node->down;}
468           else p2=p2->right;
469         }
470         break;
471       }
472       p=p->right;
473     }
474     if(!p) return ASN1_ELEMENT_NOT_FOUND;
475     break;
476   case TYPE_ANY:
477     _asn1_length_der(len,NULL,&len2);
478     temp=(unsigned char *)_asn1_alloca(len+len2);
479     if (temp==NULL) return ASN1_MEM_ERROR;
480
481     _asn1_octet_der(value,len,temp,&len2);
482     _asn1_set_value(node,temp,len2);
483     _asn1_afree(temp);
484     break;
485   case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
486     if(strcmp(value,"NEW")) return ASN1_VALUE_NOT_VALID;    
487     _asn1_append_sequence_set(node);
488     break;
489   default:
490     return  ASN1_ELEMENT_NOT_FOUND;
491     break;
492   }
493
494   return ASN1_SUCCESS;
495 }
496
497
498 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
499         *len = data_size; \
500         if (ptr_size < data_size) { \
501                 return ASN1_MEM_ERROR; \
502         } else { \
503                 memcpy( ptr, data, data_size); \
504         }
505
506 #define PUT_STR_VALUE( ptr, ptr_size, data) \
507         *len = strlen(data) + 1; \
508         if (ptr_size < *len) { \
509                 return ASN1_MEM_ERROR; \
510         } else { \
511                 /* this strcpy is checked */ \
512                 strcpy(ptr, data); \
513         }
514                 
515 #define ADD_STR_VALUE( ptr, ptr_size, data) \
516         *len = strlen(data) + 1; \
517         if (ptr_size < strlen(ptr)+(*len)) { \
518                 return ASN1_MEM_ERROR; \
519         } else { \
520                 /* this strcat is checked */ \
521                 strcat(ptr, data); \
522         }
523
524 /**
525   * asn1_read_value - Returns the value of one element inside a structure
526   * @root: pointer to a structure
527   * @name: the name of the element inside a structure that you want to read.
528   * @value: vector that will contain the element's content. 
529   * VALUE must be a pointer to memory cells already allocated.
530   * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
531   *
532   * Description:
533   *
534   * Returns the value of one element inside a structure.
535   * 
536   * Returns:
537   *
538   *   ASN1_SUCCESS\: set value OK
539   *
540   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
541   *
542   *   ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected.
543   * 
544   * Examples: 
545   *   a description for each type
546   *
547   *\begin{itemize}
548   * \item INTEGER\: VALUE will contain a two's complement form integer.
549   *            integer=-1  -> value[0]=0xFF , len=1
550   *            integer=1   -> value[0]=0x01 , len=1
551   *
552   * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
553   *
554   * \item BOOLEAN\: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
555   *
556   * \item OBJECT IDENTIFIER\: VALUE will be a null terminated string with each number separated by
557   *                      a dot (i.e. "1.2.3.543.1"). 
558   *                      LEN = strlen(VALUE)+1
559   *
560   * \item UTCTime\: VALUE will be a null terminated string in one of these formats\: 
561   *            "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
562   *            LEN=strlen(VALUE)+1
563   *
564   * \item GeneralizedTime\: VALUE will be a null terminated string in the same format used to set
565   *                    the value
566   *
567   * \item OCTET STRING\: VALUE will contain the octet string and LEN will be the number of octet.
568   *
569   * \item GeneralString\: VALUE will contain the generalstring and LEN will be the number of octet.
570   *
571   * \item BIT STRING\: VALUE will contain the bit string organized by bytes and LEN will be the 
572   *               number of bits.
573   *
574   * \item CHOICE\: if NAME indicates a choice type, VALUE will specify the alternative selected
575   *
576   * \item ANY\: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure 
577   *        actually used.
578   *\end{itemize}
579   * 
580   * If an element is OPTIONAL and the function "read_value" returns ASN1_ELEMENT_NOT_FOUND, it 
581   * means that this element wasn't present in the der encoding that created the structure.
582   * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
583   * 
584   **/
585 asn1_retCode 
586 asn1_read_value(node_asn *root,const char *name,unsigned char *value, int *len)
587 {
588   node_asn *node,*p;
589   int len2,len3;
590   int value_size = *len;
591
592   node=_asn1_find_node(root,name);
593   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
594
595   if((type_field(node->type)!=TYPE_NULL) && 
596      (type_field(node->type)!=TYPE_CHOICE) &&  
597      !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) &&
598      (node->value==NULL)) 
599     return ASN1_VALUE_NOT_FOUND;
600
601   switch(type_field(node->type)){
602   case TYPE_NULL:
603     PUT_STR_VALUE( value, value_size, "NULL");
604     break;
605   case TYPE_BOOLEAN:
606     if((node->type&CONST_DEFAULT) && (node->value==NULL)){
607       p=node->down;
608       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
609       if(p->type&CONST_TRUE) {
610         PUT_STR_VALUE( value, value_size, "TRUE");
611       } else {
612         PUT_STR_VALUE(value, value_size, "FALSE");
613       }
614     }
615     else if(node->value[0]=='T') {
616         PUT_STR_VALUE(value, value_size, "TRUE");
617     }
618     else {
619         PUT_STR_VALUE(value, value_size, "FALSE");
620     }
621     break;
622   case TYPE_INTEGER: case TYPE_ENUMERATED:
623     if((node->type&CONST_DEFAULT) && (node->value==NULL)){
624       p=node->down;
625       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
626       if (_asn1_convert_integer(p->value,value,value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
627     }
628     else{
629       len2=-1;
630       if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
631     }
632     break;
633   case TYPE_OBJECT_ID:
634     if(node->type&CONST_ASSIGN){
635       value[0]=0;
636       p=node->down;
637       while(p){
638         if(type_field(p->type)==TYPE_CONSTANT){
639           value_size-=strlen(p->value)+1;
640           if(value_size<1) return ASN1_MEM_ERROR;
641           strcat(value,p->value); 
642           if(p->right) {
643             strcat(value,".");
644           }
645         }
646         p=p->right;
647       }
648       *len = strlen(value) + 1;
649     } else {
650       PUT_STR_VALUE(value, value_size, node->value);
651     }
652     break;
653   case TYPE_TIME:
654     PUT_STR_VALUE( value, value_size, node->value);
655     break;
656   case TYPE_OCTET_STRING:
657     len2=-1;
658     if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
659     break;
660   case TYPE_GENERALSTRING:
661     len2=-1;
662     if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
663     break;
664   case TYPE_BIT_STRING:
665     len2=-1;
666     if (_asn1_get_bit_der(node->value,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
667     break;
668   case TYPE_CHOICE:
669     PUT_STR_VALUE( value, value_size, node->down->name);
670     break; 
671   case TYPE_ANY:
672     len3=-1;
673     len2=_asn1_get_length_der(node->value,&len3);
674     PUT_VALUE( value, value_size, node->value+len3, len2);
675     break;
676   default:
677     return  ASN1_ELEMENT_NOT_FOUND;
678     break;
679   }
680   return ASN1_SUCCESS;
681 }
682
683
684 /**
685   * asn1_read_tag - Returns the TAG of one element inside a structure
686   * @root: pointer to a structure
687   * @name: the name of the element inside a structure.
688   * @tag:  variable that will contain the TAG value. 
689   * @class: variable that will specify the TAG type.
690   *
691   * Description:
692   *
693   * Returns the TAG and the CLASS of one element inside a structure.
694   * CLASS can have one of these constants: ASN1_CLASS_APPLICATION,
695   * ASN1_CLASS_UNIVERSAL, ASN1_CLASS_PRIVATE or ASN1_CLASS_CONTEXT_SPECIFIC.
696   * 
697   * Returns:
698   *
699   *   ASN1_SUCCESS\: set value OK
700   *
701   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
702   * 
703   **/
704 asn1_retCode 
705 asn1_read_tag(node_asn *root,const char *name,int *tag, int *class)
706 {
707   node_asn *node,*p,*pTag;
708  
709   node=_asn1_find_node(root,name);
710   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
711
712   p=node->down;
713
714   /* pTag will points to the IMPLICIT TAG */
715   pTag=NULL;
716   if(node->type&CONST_TAG){
717     while(p){
718       if(type_field(p->type)==TYPE_TAG){
719          if(p->type&CONST_IMPLICIT)
720            pTag=p;
721          else
722            pTag=NULL;
723       }
724       p=p->right;
725     }
726   }
727
728   if(pTag){
729     *tag=strtoul(p->value,NULL,10);
730     /*
731     if(p->type&CONST_APPLICATION) *class=ASN1_CLASS_APPLICATION;
732     else if(p->type&CONST_UNIVERSAL) *class=ASN1_CLASS_UNIVERSAL;
733     else if(p->type&CONST_PRIVATE) *class=ASN1_CLASS_PRIVATE;
734     else *class=ASN1_CLASS_CONTEXT_SPECIFIC;
735     */
736   }
737   else{
738     /*
739     *class=ASN!_CLASS_UNIVERSAL;
740     switch(type_field(node->type)){
741     case TYPE_NULL:
742       *tag=ASN1_TAG_NULL;break;
743     case TYPE_BOOLEAN:
744       *tag=ASN1_TAG_BOOLEAN;break;
745     case TYPE_INTEGER:
746       *tag=ASN1_TAG_INTEGER;break;
747     case TYPE_ENUMERATED:
748       *tag=ASN1_TAG_ENUMERATED;break;
749     case TYPE_OBJECT_ID:
750       *tag=ASN1_TAG_OBJECT_ID;break;
751     case TYPE_TIME:
752       if(node->type&CONST_UTC){
753         *tag=ASN1_TAG_UTCTime;
754       }
755       else *tag=ASN1_TAG_GENERALIZEDTime;
756       break;
757     case TYPE_OCTET_STRING:
758       *tag=ASN1_TAG_OCTET_STRING;break;
759     case TYPE_GENERALSTRING:
760       *tag=ASN1_TAG_GENERALSTRING;break;
761     case TYPE_BIT_STRING:
762       *tag=ASN1_TAG_BIT_STRING;break;
763     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
764       *tag=ASN1_TAG_SEQUENCE;break;
765     case TYPE_SET: case TYPE_SET_OF:
766       *tag=ASN1_TAG_SET;break;
767     case TYPE_TAG:
768     case TYPE_CHOICE:
769     case TYPE_ANY:
770       break;
771     default:
772       break
773     }
774     */
775   }
776
777
778   return ASN1_SUCCESS;
779
780 }
781
782
783
784