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