Doc fixes, from Martijn Koster <mak@greenhills.co.uk>.
[platform/upstream/libtasn1.git] / lib / element.c
1 /*
2  *      Copyright (C) 2000,2001,2002,2003 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   node_asn *p;
39   char tmp_name[64];
40
41   p=node;
42
43   name[0]=0;
44
45   while(p != NULL){
46     if(p->name != NULL){
47       _asn1_str_cpy(tmp_name,sizeof(tmp_name),name),
48
49       _asn1_str_cpy(name,name_size,p->name);
50       _asn1_str_cat(name,name_size,".");
51       _asn1_str_cat(name,name_size,tmp_name);
52     }
53     p=_asn1_find_up(p);
54   }
55
56   if(name[0]==0) _asn1_str_cpy(name,name_size,"ROOT");
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   *len=SIZEOF_UNSIGNED_LONG_INT-k;  
100
101   if (SIZEOF_UNSIGNED_LONG_INT-k> value_out_size)
102     /* VALUE_OUT is too short to contain the value conversion */
103     return ASN1_MEM_ERROR;
104
105   for(k2=k;k2<SIZEOF_UNSIGNED_LONG_INT;k2++)
106     value_out[k2-k]=val[k2];
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   * @ivalue: 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 octets.
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 octets.
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 void *ivalue,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   const unsigned char* value = ivalue;
253
254   node=_asn1_find_node(node_root,name);
255   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
256
257   if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
258     asn1_delete_structure(&node);
259     return ASN1_SUCCESS;
260   }
261
262   if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){
263     p=node->down;
264     while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
265
266     while(p->right)
267       asn1_delete_structure(&p->right);
268
269     return ASN1_SUCCESS;
270   }
271
272   switch(type_field(node->type)){
273   case TYPE_BOOLEAN:
274     if(!strcmp(value,"TRUE")){
275       if(node->type&CONST_DEFAULT){
276         p=node->down;
277         while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
278         if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0);
279         else _asn1_set_value(node,"T",1);
280       }
281       else _asn1_set_value(node,"T",1);
282     }
283     else if(!strcmp(value,"FALSE")){
284       if(node->type&CONST_DEFAULT){
285         p=node->down;
286         while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
287         if(p->type&CONST_FALSE) _asn1_set_value(node,NULL,0);
288         else _asn1_set_value(node,"F",1);
289       }
290       else _asn1_set_value(node,"F",1);
291     }
292     else return ASN1_VALUE_NOT_VALID;
293     break;
294   case TYPE_INTEGER: case TYPE_ENUMERATED:
295     if(len==0){
296       if((isdigit(value[0])) || (value[0]=='-')){
297         value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
298         if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
299
300         _asn1_convert_integer(value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
301       }
302       else{ /* is an identifier like v1 */
303         if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
304         p=node->down;
305         while(p){
306           if(type_field(p->type)==TYPE_CONSTANT){
307             if((p->name) && (!strcmp(p->name,value))){
308               value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
309               if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
310
311               _asn1_convert_integer(p->value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
312               break;
313             }
314           }
315           p=p->right;
316         }
317         if(p==NULL) return ASN1_VALUE_NOT_VALID;
318       }
319     }
320     else{ /* len != 0 */
321       value_temp=(unsigned char *)_asn1_alloca(len);
322       if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
323       memcpy(value_temp,value,len);
324     }
325
326
327     if(value_temp[0]&0x80) negative=1;
328     else negative=0;
329
330     if(negative && (type_field(node->type)==TYPE_ENUMERATED)) 
331       {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;}
332
333     for(k=0;k<len-1;k++)
334       if(negative && (value_temp[k]!=0xFF)) break;
335       else if(!negative && value_temp[k]) break;
336
337     if((negative && !(value_temp[k]&0x80)) ||
338        (!negative && (value_temp[k]&0x80))) k--; 
339
340     _asn1_length_der(len-k,NULL,&len2);
341     temp=(unsigned char *)_asn1_alloca(len-k+len2);
342     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
343
344     _asn1_octet_der(value_temp+k,len-k,temp,&len2);
345     _asn1_set_value(node,temp,len2);
346
347     _asn1_afree(temp);
348
349
350     if(node->type&CONST_DEFAULT){
351       p=node->down;
352       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
353       if((isdigit(p->value[0])) || (p->value[0]=='-')){
354         default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
355         if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
356
357         _asn1_convert_integer(p->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
358       }
359       else{ /* is an identifier like v1 */
360         if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
361         p2=node->down;
362         while(p2){
363           if(type_field(p2->type)==TYPE_CONSTANT){
364             if((p2->name) && (!strcmp(p2->name,p->value))){
365               default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
366               if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
367
368               _asn1_convert_integer(p2->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
369               break;
370             }
371           }
372           p2=p2->right;
373         }
374         if(p2==NULL) return ASN1_VALUE_NOT_VALID;
375       }
376
377
378       if((len-k)==len2){
379         for(k2=0;k2<len2;k2++) 
380           if(value_temp[k+k2]!=default_temp[k2]){
381             break;
382           }
383         if(k2==len2) _asn1_set_value(node,NULL,0);
384       }
385       _asn1_afree(default_temp);
386     }
387     _asn1_afree(value_temp);
388     break;
389   case TYPE_OBJECT_ID:
390     for(k=0;k<strlen(value);k++)
391       if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+')) 
392         return ASN1_VALUE_NOT_VALID; 
393     if(node->type&CONST_DEFAULT){
394       p=node->down;
395       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
396       if(!strcmp(value,p->value)){
397         _asn1_set_value(node,NULL,0);
398         break;
399       } 
400     }
401     _asn1_set_value(node,value,strlen(value)+1);
402     break;
403   case TYPE_TIME:
404     if(node->type&CONST_UTC){
405       if(strlen(value)<11) return ASN1_VALUE_NOT_VALID;
406       for(k=0;k<10;k++) 
407         if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
408       switch(strlen(value)){
409       case 11:
410       if(value[10]!='Z') return ASN1_VALUE_NOT_VALID;
411       break;
412       case 13:
413         if((!isdigit(value[10])) || (!isdigit(value[11])) ||
414            (value[12]!='Z')) return ASN1_VALUE_NOT_VALID;
415         break;
416       case 15:
417         if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID;
418         for(k=11;k<15;k++) 
419           if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
420         break;
421       case 17:
422         if((!isdigit(value[10])) || (!isdigit(value[11]))) 
423            return ASN1_VALUE_NOT_VALID;
424         if((value[12]!='+') && (value[12]!='-')) return ASN1_VALUE_NOT_VALID;
425         for(k=13;k<17;k++) 
426           if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
427         break; 
428       default:
429         return ASN1_VALUE_NOT_FOUND;
430       }
431       _asn1_set_value(node,value,strlen(value)+1);
432     }
433     else{  /* GENERALIZED TIME */
434       if(value) _asn1_set_value(node,value,strlen(value)+1);
435     }
436     break;
437   case  TYPE_OCTET_STRING:
438     if(len==0)
439       len=strlen(value);
440     _asn1_length_der(len,NULL,&len2);
441     temp=(unsigned char *)_asn1_alloca(len+len2);
442     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
443
444     _asn1_octet_der(value,len,temp,&len2);
445     _asn1_set_value(node,temp,len2);
446     _asn1_afree(temp);
447     break;
448   case  TYPE_GENERALSTRING:
449     if(len==0)
450       len=strlen(value);
451     _asn1_length_der(len,NULL,&len2);
452     temp=(unsigned char *)_asn1_alloca(len+len2);
453     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
454
455     _asn1_octet_der(value,len,temp,&len2);
456     _asn1_set_value(node,temp,len2);
457     _asn1_afree(temp);
458     break;
459   case  TYPE_BIT_STRING:
460     if(len==0)
461       len=strlen(value);
462     _asn1_length_der((len>>3)+2,NULL,&len2);
463     temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2);
464     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
465
466     _asn1_bit_der(value,len,temp,&len2);
467     _asn1_set_value(node,temp,len2);
468     _asn1_afree(temp);
469     break;
470   case  TYPE_CHOICE:
471     p=node->down;
472     while(p){
473       if(!strcmp(p->name,value)){
474         p2=node->down;
475         while(p2){
476           if(p2!=p){asn1_delete_structure(&p2); p2=node->down;}
477           else p2=p2->right;
478         }
479         break;
480       }
481       p=p->right;
482     }
483     if(!p) return ASN1_ELEMENT_NOT_FOUND;
484     break;
485   case TYPE_ANY:
486     _asn1_length_der(len,NULL,&len2);
487     temp=(unsigned char *)_asn1_alloca(len+len2);
488     if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
489
490     _asn1_octet_der(value,len,temp,&len2);
491     _asn1_set_value(node,temp,len2);
492     _asn1_afree(temp);
493     break;
494   case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
495     if(strcmp(value,"NEW")) return ASN1_VALUE_NOT_VALID;    
496     _asn1_append_sequence_set(node);
497     break;
498   default:
499     return  ASN1_ELEMENT_NOT_FOUND;
500     break;
501   }
502
503   return ASN1_SUCCESS;
504 }
505
506
507 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
508         *len = data_size; \
509         if (ptr_size < data_size) { \
510                 return ASN1_MEM_ERROR; \
511         } else { \
512                 memcpy( ptr, data, data_size); \
513         }
514
515 #define PUT_STR_VALUE( ptr, ptr_size, data) \
516         *len = strlen(data) + 1; \
517         if (ptr_size < *len) { \
518                 return ASN1_MEM_ERROR; \
519         } else { \
520                 /* this strcpy is checked */ \
521                 strcpy(ptr, data); \
522         }
523                 
524 #define ADD_STR_VALUE( ptr, ptr_size, data) \
525         *len = strlen(data) + 1; \
526         if (ptr_size < strlen(ptr)+(*len)) { \
527                 return ASN1_MEM_ERROR; \
528         } else { \
529                 /* this strcat is checked */ \
530                 strcat(ptr, data); \
531         }
532
533 /**
534   * asn1_read_value - Returns the value of one element inside a structure
535   * @root: pointer to a structure
536   * @name: the name of the element inside a structure that you want to read.
537   * @ivalue: vector that will contain the element's content. 
538   * VALUE must be a pointer to memory cells already allocated.
539   * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
540   *
541   * Description:
542   *
543   * Returns the value of one element inside a structure.
544   * 
545   * Returns:
546   *
547   *   ASN1_SUCCESS\: set value OK
548   *
549   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
550   *
551   *   ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected.
552   *
553   *   ASN1_MEM_ERROR\: the value vector isn't big enough to store the result.
554   *   In this case LEN will contain the number of bytes needed.
555   * 
556   * Examples: 
557   *   a description for each type
558   *
559   *\begin{itemize}
560   * \item INTEGER\: VALUE will contain a two's complement form integer.
561   *            integer=-1  -> value[0]=0xFF , len=1
562   *            integer=1   -> value[0]=0x01 , len=1
563   *
564   * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
565   *
566   * \item BOOLEAN\: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
567   *
568   * \item OBJECT IDENTIFIER\: VALUE will be a null terminated string with each number separated by
569   *                      a dot (i.e. "1.2.3.543.1"). 
570   *                      LEN = strlen(VALUE)+1
571   *
572   * \item UTCTime\: VALUE will be a null terminated string in one of these formats\: 
573   *            "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
574   *            LEN=strlen(VALUE)+1
575   *
576   * \item GeneralizedTime\: VALUE will be a null terminated string in the same format used to set
577   *                    the value
578   *
579   * \item OCTET STRING\: VALUE will contain the octet string and LEN will be the number of octets.
580   *
581   * \item GeneralString\: VALUE will contain the generalstring and LEN will be the number of octets.
582   *
583   * \item BIT STRING\: VALUE will contain the bit string organized by bytes and LEN will be the 
584   *               number of bits.
585   *
586   * \item CHOICE\: if NAME indicates a choice type, VALUE will specify the alternative selected
587   *
588   * \item ANY\: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure 
589   *        actually used.
590   *\end{itemize}
591   * 
592   * If an element is OPTIONAL and the function "read_value" returns ASN1_ELEMENT_NOT_FOUND, it 
593   * means that this element wasn't present in the der encoding that created the structure.
594   * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
595   * 
596   **/
597 asn1_retCode 
598 asn1_read_value(node_asn *root,const char *name,void* ivalue, int *len)
599 {
600   node_asn *node,*p,*p2;
601   int len2,len3;
602   int value_size = *len;
603   unsigned char* value = ivalue;
604
605   node=_asn1_find_node(root,name);
606   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
607
608   if((type_field(node->type)!=TYPE_NULL) && 
609      (type_field(node->type)!=TYPE_CHOICE) &&  
610      !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) &&
611      (node->value==NULL)) 
612     return ASN1_VALUE_NOT_FOUND;
613
614   switch(type_field(node->type)){
615   case TYPE_NULL:
616     PUT_STR_VALUE( value, value_size, "NULL");
617     break;
618   case TYPE_BOOLEAN:
619     if((node->type&CONST_DEFAULT) && (node->value==NULL)){
620       p=node->down;
621       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
622       if(p->type&CONST_TRUE) {
623         PUT_STR_VALUE( value, value_size, "TRUE");
624       } else {
625         PUT_STR_VALUE(value, value_size, "FALSE");
626       }
627     }
628     else if(node->value[0]=='T') {
629         PUT_STR_VALUE(value, value_size, "TRUE");
630     }
631     else {
632         PUT_STR_VALUE(value, value_size, "FALSE");
633     }
634     break;
635   case TYPE_INTEGER: case TYPE_ENUMERATED:
636     if((node->type&CONST_DEFAULT) && (node->value==NULL)){
637       p=node->down;
638       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
639       if((isdigit(p->value[0])) || (p->value[0]=='-') || (p->value[0]=='+')){
640         if (_asn1_convert_integer(p->value,value,value_size, len) != 
641             ASN1_SUCCESS) 
642           return ASN1_MEM_ERROR;
643       }
644       else{ /* is an identifier like v1 */
645         p2=node->down;
646         while(p2){
647           if(type_field(p2->type)==TYPE_CONSTANT){
648             if((p2->name) && (!strcmp(p2->name,p->value))){
649               if (_asn1_convert_integer(p2->value,value,value_size, len) != 
650                   ASN1_SUCCESS) 
651                 return ASN1_MEM_ERROR;
652               break;
653             }
654           }
655           p2=p2->right;
656         }
657       }
658     }
659     else{
660       len2=-1;
661       if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
662     }
663     break;
664   case TYPE_OBJECT_ID:
665     if(node->type&CONST_ASSIGN){
666       value[0]=0;
667       p=node->down;
668       while(p){
669         if(type_field(p->type)==TYPE_CONSTANT){
670           ADD_STR_VALUE(value,value_size,p->value);       
671           if(p->right) {
672           ADD_STR_VALUE(value,value_size,".");
673           }
674         }
675         p=p->right;
676       }
677       *len = strlen(value) + 1;
678     } 
679     else if((node->type&CONST_DEFAULT) && (node->value==NULL)){
680       p=node->down;
681       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
682       PUT_STR_VALUE(value, value_size, p->value);
683       }
684     else {
685       PUT_STR_VALUE(value, value_size, node->value);
686     }
687     break;
688   case TYPE_TIME:
689     PUT_STR_VALUE( value, value_size, node->value);
690     break;
691   case TYPE_OCTET_STRING:
692     len2=-1;
693     if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
694     break;
695   case TYPE_GENERALSTRING:
696     len2=-1;
697     if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
698     break;
699   case TYPE_BIT_STRING:
700     len2=-1;
701     if (_asn1_get_bit_der(node->value,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
702     break;
703   case TYPE_CHOICE:
704     PUT_STR_VALUE( value, value_size, node->down->name);
705     break; 
706   case TYPE_ANY:
707     len3=-1;
708     len2=_asn1_get_length_der(node->value,&len3);
709     PUT_VALUE( value, value_size, node->value+len3, len2);
710     break;
711   default:
712     return  ASN1_ELEMENT_NOT_FOUND;
713     break;
714   }
715   return ASN1_SUCCESS;
716 }
717
718
719 /**
720   * asn1_read_tag - Returns the TAG of one element inside a structure
721   * @root: pointer to a structure
722   * @name: the name of the element inside a structure.
723   * @tagValue:  variable that will contain the TAG value. 
724   * @classValue: variable that will specify the TAG type.
725   *
726   * Description:
727   *
728   * Returns the TAG and the CLASS of one element inside a structure.
729   * CLASS can have one of these constants: ASN1_CLASS_APPLICATION,
730   * ASN1_CLASS_UNIVERSAL, ASN1_CLASS_PRIVATE or ASN1_CLASS_CONTEXT_SPECIFIC.
731   * 
732   * Returns:
733   *
734   *   ASN1_SUCCESS\: set value OK
735   *
736   *   ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
737   * 
738   **/
739 asn1_retCode 
740 asn1_read_tag(node_asn *root,const char *name,int *tagValue, int *classValue)
741 {
742   node_asn *node,*p,*pTag;
743  
744   node=_asn1_find_node(root,name);
745   if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
746
747   p=node->down;
748
749   /* pTag will points to the IMPLICIT TAG */
750   pTag=NULL;
751   if(node->type&CONST_TAG){
752     while(p){
753       if(type_field(p->type)==TYPE_TAG){
754         if((p->type&CONST_IMPLICIT) && (pTag==NULL))
755           pTag=p;
756         else if(p->type&CONST_EXPLICIT)
757           pTag=NULL;
758       }
759       p=p->right;
760     }
761   }
762
763   if(pTag){
764     *tagValue=strtoul(pTag->value,NULL,10);
765   
766     if(pTag->type&CONST_APPLICATION) *classValue=ASN1_CLASS_APPLICATION;
767     else if(pTag->type&CONST_UNIVERSAL) *classValue=ASN1_CLASS_UNIVERSAL;
768     else if(pTag->type&CONST_PRIVATE) *classValue=ASN1_CLASS_PRIVATE;
769     else *classValue=ASN1_CLASS_CONTEXT_SPECIFIC;
770   }
771   else{
772     *classValue=ASN1_CLASS_UNIVERSAL;
773
774     switch(type_field(node->type)){
775     case TYPE_NULL:
776       *tagValue=ASN1_TAG_NULL;break;
777     case TYPE_BOOLEAN:
778       *tagValue=ASN1_TAG_BOOLEAN;break;
779     case TYPE_INTEGER:
780       *tagValue=ASN1_TAG_INTEGER;break;
781     case TYPE_ENUMERATED:
782       *tagValue=ASN1_TAG_ENUMERATED;break;
783     case TYPE_OBJECT_ID:
784       *tagValue=ASN1_TAG_OBJECT_ID;break;
785     case TYPE_TIME:
786       if(node->type&CONST_UTC){
787         *tagValue=ASN1_TAG_UTCTime;
788       }
789       else *tagValue=ASN1_TAG_GENERALIZEDTime;
790       break;
791     case TYPE_OCTET_STRING:
792       *tagValue=ASN1_TAG_OCTET_STRING;break;
793     case TYPE_GENERALSTRING:
794       *tagValue=ASN1_TAG_GENERALSTRING;break;
795     case TYPE_BIT_STRING:
796       *tagValue=ASN1_TAG_BIT_STRING;break;
797     case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
798       *tagValue=ASN1_TAG_SEQUENCE;break;
799     case TYPE_SET: case TYPE_SET_OF:
800       *tagValue=ASN1_TAG_SET;break;
801     case TYPE_TAG:
802     case TYPE_CHOICE:
803     case TYPE_ANY:
804       break;
805     default:
806       break;
807     }
808   }
809
810
811   return ASN1_SUCCESS;
812
813 }