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