Simplify unused debug code.
[platform/upstream/libtasn1.git] / lib / element.c
1 /*
2  *      Copyright (C) 2004, 2006, 2008, 2009 Free Software Foundation
3  *      Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina
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 - Set the value of one element inside a structure.
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   **/
276 asn1_retCode
277 asn1_write_value (ASN1_TYPE node_root, const char *name,
278                   const void *ivalue, int len)
279 {
280   ASN1_TYPE node, p, p2;
281   unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
282   int len2, k, k2, negative;
283   size_t i;
284   const unsigned char *value = ivalue;
285
286   node = asn1_find_node (node_root, name);
287   if (node == NULL)
288     return ASN1_ELEMENT_NOT_FOUND;
289
290   if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
291     {
292       asn1_delete_structure (&node);
293       return ASN1_SUCCESS;
294     }
295
296   if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
297       && (len == 0))
298     {
299       p = node->down;
300       while ((type_field (p->type) == TYPE_TAG)
301              || (type_field (p->type) == TYPE_SIZE))
302         p = p->right;
303
304       while (p->right)
305         asn1_delete_structure (&p->right);
306
307       return ASN1_SUCCESS;
308     }
309
310   switch (type_field (node->type))
311     {
312     case TYPE_BOOLEAN:
313       if (!strcmp (value, "TRUE"))
314         {
315           if (node->type & CONST_DEFAULT)
316             {
317               p = node->down;
318               while (type_field (p->type) != TYPE_DEFAULT)
319                 p = p->right;
320               if (p->type & CONST_TRUE)
321                 _asn1_set_value (node, NULL, 0);
322               else
323                 _asn1_set_value (node, "T", 1);
324             }
325           else
326             _asn1_set_value (node, "T", 1);
327         }
328       else if (!strcmp (value, "FALSE"))
329         {
330           if (node->type & CONST_DEFAULT)
331             {
332               p = node->down;
333               while (type_field (p->type) != TYPE_DEFAULT)
334                 p = p->right;
335               if (p->type & CONST_FALSE)
336                 _asn1_set_value (node, NULL, 0);
337               else
338                 _asn1_set_value (node, "F", 1);
339             }
340           else
341             _asn1_set_value (node, "F", 1);
342         }
343       else
344         return ASN1_VALUE_NOT_VALID;
345       break;
346     case TYPE_INTEGER:
347     case TYPE_ENUMERATED:
348       if (len == 0)
349         {
350           if ((isdigit (value[0])) || (value[0] == '-'))
351             {
352               value_temp =
353                 (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
354               if (value_temp == NULL)
355                 return ASN1_MEM_ALLOC_ERROR;
356
357               _asn1_convert_integer (value, value_temp,
358                                      SIZEOF_UNSIGNED_LONG_INT, &len);
359             }
360           else
361             {                   /* is an identifier like v1 */
362               if (!(node->type & CONST_LIST))
363                 return ASN1_VALUE_NOT_VALID;
364               p = node->down;
365               while (p)
366                 {
367                   if (type_field (p->type) == TYPE_CONSTANT)
368                     {
369                       if ((p->name) && (!strcmp (p->name, value)))
370                         {
371                           value_temp =
372                             (unsigned char *)
373                             _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
374                           if (value_temp == NULL)
375                             return ASN1_MEM_ALLOC_ERROR;
376
377                           _asn1_convert_integer (p->value,
378                                                  value_temp,
379                                                  SIZEOF_UNSIGNED_LONG_INT,
380                                                  &len);
381                           break;
382                         }
383                     }
384                   p = p->right;
385                 }
386               if (p == NULL)
387                 return ASN1_VALUE_NOT_VALID;
388             }
389         }
390       else
391         {                       /* len != 0 */
392           value_temp = (unsigned char *) _asn1_malloc (len);
393           if (value_temp == NULL)
394             return ASN1_MEM_ALLOC_ERROR;
395           memcpy (value_temp, value, len);
396         }
397
398
399       if (value_temp[0] & 0x80)
400         negative = 1;
401       else
402         negative = 0;
403
404       if (negative && (type_field (node->type) == TYPE_ENUMERATED))
405         {
406           _asn1_free (value_temp);
407           return ASN1_VALUE_NOT_VALID;
408         }
409
410       for (k = 0; k < len - 1; k++)
411         if (negative && (value_temp[k] != 0xFF))
412           break;
413         else if (!negative && value_temp[k])
414           break;
415
416       if ((negative && !(value_temp[k] & 0x80)) ||
417           (!negative && (value_temp[k] & 0x80)))
418         k--;
419
420       _asn1_set_value_octet (node, value_temp+k, len-k);
421
422       if (node->type & CONST_DEFAULT)
423         {
424           p = node->down;
425           while (type_field (p->type) != TYPE_DEFAULT)
426             p = p->right;
427           if ((isdigit (p->value[0])) || (p->value[0] == '-'))
428             {
429               default_temp =
430                 (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
431               if (default_temp == NULL)
432                 {
433                   _asn1_free (value_temp);
434                   return ASN1_MEM_ALLOC_ERROR;
435                 }
436
437               _asn1_convert_integer (p->value, default_temp,
438                                      SIZEOF_UNSIGNED_LONG_INT, &len2);
439             }
440           else
441             {                   /* is an identifier like v1 */
442               if (!(node->type & CONST_LIST))
443                 {
444                   _asn1_free (value_temp);
445                   return ASN1_VALUE_NOT_VALID;
446                 }
447               p2 = node->down;
448               while (p2)
449                 {
450                   if (type_field (p2->type) == TYPE_CONSTANT)
451                     {
452                       if ((p2->name) && (!strcmp (p2->name, p->value)))
453                         {
454                           default_temp =
455                             (unsigned char *)
456                             _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
457                           if (default_temp == NULL)
458                             {
459                               _asn1_free (value_temp);
460                               return ASN1_MEM_ALLOC_ERROR;
461                             }
462
463                           _asn1_convert_integer (p2->value,
464                                                  default_temp,
465                                                  SIZEOF_UNSIGNED_LONG_INT,
466                                                  &len2);
467                           break;
468                         }
469                     }
470                   p2 = p2->right;
471                 }
472               if (p2 == NULL)
473                 {
474                   _asn1_free (value_temp);
475                   return ASN1_VALUE_NOT_VALID;
476                 }
477             }
478
479
480           if ((len - k) == len2)
481             {
482               for (k2 = 0; k2 < len2; k2++)
483                 if (value_temp[k + k2] != default_temp[k2])
484                   {
485                     break;
486                   }
487               if (k2 == len2)
488                 _asn1_set_value (node, NULL, 0);
489             }
490           _asn1_free (default_temp);
491         }
492       _asn1_free (value_temp);
493       break;
494     case TYPE_OBJECT_ID:
495       for (i = 0; i < strlen (value); i++)
496         if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
497           return ASN1_VALUE_NOT_VALID;
498       if (node->type & CONST_DEFAULT)
499         {
500           p = node->down;
501           while (type_field (p->type) != TYPE_DEFAULT)
502             p = p->right;
503           if (!strcmp (value, p->value))
504             {
505               _asn1_set_value (node, NULL, 0);
506               break;
507             }
508         }
509       _asn1_set_value (node, value, strlen (value) + 1);
510       break;
511     case TYPE_TIME:
512       if (node->type & CONST_UTC)
513         {
514           if (strlen (value) < 11)
515             return ASN1_VALUE_NOT_VALID;
516           for (k = 0; k < 10; k++)
517             if (!isdigit (value[k]))
518               return ASN1_VALUE_NOT_VALID;
519           switch (strlen (value))
520             {
521             case 11:
522               if (value[10] != 'Z')
523                 return ASN1_VALUE_NOT_VALID;
524               break;
525             case 13:
526               if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
527                   (value[12] != 'Z'))
528                 return ASN1_VALUE_NOT_VALID;
529               break;
530             case 15:
531               if ((value[10] != '+') && (value[10] != '-'))
532                 return ASN1_VALUE_NOT_VALID;
533               for (k = 11; k < 15; k++)
534                 if (!isdigit (value[k]))
535                   return ASN1_VALUE_NOT_VALID;
536               break;
537             case 17:
538               if ((!isdigit (value[10])) || (!isdigit (value[11])))
539                 return ASN1_VALUE_NOT_VALID;
540               if ((value[12] != '+') && (value[12] != '-'))
541                 return ASN1_VALUE_NOT_VALID;
542               for (k = 13; k < 17; k++)
543                 if (!isdigit (value[k]))
544                   return ASN1_VALUE_NOT_VALID;
545               break;
546             default:
547               return ASN1_VALUE_NOT_FOUND;
548             }
549           _asn1_set_value (node, value, strlen (value) + 1);
550         }
551       else
552         {                       /* GENERALIZED TIME */
553           if (value)
554             _asn1_set_value (node, value, strlen (value) + 1);
555         }
556       break;
557     case TYPE_OCTET_STRING:
558       if (len == 0)
559         len = strlen (value);
560       _asn1_set_value_octet (node, value, len);
561       break;
562     case TYPE_GENERALSTRING:
563       if (len == 0)
564         len = strlen (value);
565       _asn1_set_value_octet (node, value, len);
566       break;
567     case TYPE_BIT_STRING:
568       if (len == 0)
569         len = strlen (value);
570       asn1_length_der ((len >> 3) + 2, NULL, &len2);
571       temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
572       if (temp == NULL)
573         return ASN1_MEM_ALLOC_ERROR;
574
575       asn1_bit_der (value, len, temp, &len2);
576       _asn1_set_value_m (node, temp, len2);
577       temp = NULL;
578       break;
579     case TYPE_CHOICE:
580       p = node->down;
581       while (p)
582         {
583           if (!strcmp (p->name, value))
584             {
585               p2 = node->down;
586               while (p2)
587                 {
588                   if (p2 != p)
589                     {
590                       asn1_delete_structure (&p2);
591                       p2 = node->down;
592                     }
593                   else
594                     p2 = p2->right;
595                 }
596               break;
597             }
598           p = p->right;
599         }
600       if (!p)
601         return ASN1_ELEMENT_NOT_FOUND;
602       break;
603     case TYPE_ANY:
604       _asn1_set_value_octet (node, value, len);
605       break;
606     case TYPE_SEQUENCE_OF:
607     case TYPE_SET_OF:
608       if (strcmp (value, "NEW"))
609         return ASN1_VALUE_NOT_VALID;
610       _asn1_append_sequence_set (node);
611       break;
612     default:
613       return ASN1_ELEMENT_NOT_FOUND;
614       break;
615     }
616
617   return ASN1_SUCCESS;
618 }
619
620
621 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
622         *len = data_size; \
623         if (ptr_size < data_size) { \
624                 return ASN1_MEM_ERROR; \
625         } else { \
626                 memcpy( ptr, data, data_size); \
627         }
628
629 #define PUT_STR_VALUE( ptr, ptr_size, data) \
630         *len = strlen(data) + 1; \
631         if (ptr_size < *len) { \
632                 return ASN1_MEM_ERROR; \
633         } else { \
634                 /* this strcpy is checked */ \
635                 strcpy(ptr, data); \
636         }
637
638 #define ADD_STR_VALUE( ptr, ptr_size, data) \
639         *len = (int) strlen(data) + 1; \
640         if (ptr_size < (int) strlen(ptr)+(*len)) { \
641                 return ASN1_MEM_ERROR; \
642         } else { \
643                 /* this strcat is checked */ \
644                 strcat(ptr, data); \
645         }
646
647 /**
648   * asn1_read_value - Returns the value of one element inside a structure
649   * @root: pointer to a structure.
650   * @name: the name of the element inside a structure that you want to read.
651   * @ivalue: vector that will contain the element's content, must be a
652   *   pointer to memory cells already allocated.
653   * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
654   *   holds the sizeof value.
655   *
656   * Returns the value of one element inside a structure.
657   *
658   * If an element is OPTIONAL and the function "read_value" returns
659   * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
660   * in the der encoding that created the structure.  The first element
661   * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
662   * so on.
663   *
664   * INTEGER: VALUE will contain a two's complement form integer.
665   *
666   *            integer=-1  -> value[0]=0xFF , len=1.
667   *            integer=1   -> value[0]=0x01 , len=1.
668   *
669   * ENUMERATED: As INTEGER (but only with not negative numbers).
670   *
671   * BOOLEAN: VALUE will be the null terminated string "TRUE" or
672   *   "FALSE" and LEN=5 or LEN=6.
673   *
674   * OBJECT IDENTIFIER: VALUE will be a null terminated string with
675   *   each number separated by a dot (i.e. "1.2.3.543.1").
676   *
677   *                      LEN = strlen(VALUE)+1
678   *
679   * UTCTime: VALUE will be a null terminated string in one of these
680   *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
681   *   LEN=strlen(VALUE)+1.
682   *
683   * GeneralizedTime: VALUE will be a null terminated string in the
684   *   same format used to set the value.
685   *
686   * OCTET STRING: VALUE will contain the octet string and LEN will be
687   *   the number of octets.
688   *
689   * GeneralString: VALUE will contain the generalstring and LEN will
690   *   be the number of octets.
691   *
692   * BIT STRING: VALUE will contain the bit string organized by bytes
693   *   and LEN will be the number of bits.
694   *
695   * CHOICE: If NAME indicates a choice type, VALUE will specify the
696   *   alternative selected.
697   *
698   * ANY: If NAME indicates an any type, VALUE will indicate the DER
699   *   encoding of the structure actually used.
700   *
701   * Returns:
702   *
703   *   ASN1_SUCCESS: Set value OK.
704   *
705   *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
706   *
707   *   ASN1_VALUE_NOT_FOUND: There isn't any value for the element selected.
708   *
709   *   ASN1_MEM_ERROR: The value vector isn't big enough to store the result.
710   *   In this case LEN will contain the number of bytes needed.
711   *
712   **/
713 asn1_retCode
714 asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
715 {
716   ASN1_TYPE node, p, p2;
717   int len2, len3;
718   int value_size = *len;
719   unsigned char *value = ivalue;
720
721   node = asn1_find_node (root, name);
722   if (node == NULL)
723     return ASN1_ELEMENT_NOT_FOUND;
724
725   if ((type_field (node->type) != TYPE_NULL) &&
726       (type_field (node->type) != TYPE_CHOICE) &&
727       !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
728       (node->value == NULL))
729     return ASN1_VALUE_NOT_FOUND;
730
731   switch (type_field (node->type))
732     {
733     case TYPE_NULL:
734       PUT_STR_VALUE (value, value_size, "NULL");
735       break;
736     case TYPE_BOOLEAN:
737       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
738         {
739           p = node->down;
740           while (type_field (p->type) != TYPE_DEFAULT)
741             p = p->right;
742           if (p->type & CONST_TRUE)
743             {
744               PUT_STR_VALUE (value, value_size, "TRUE");
745             }
746           else
747             {
748               PUT_STR_VALUE (value, value_size, "FALSE");
749             }
750         }
751       else if (node->value[0] == 'T')
752         {
753           PUT_STR_VALUE (value, value_size, "TRUE");
754         }
755       else
756         {
757           PUT_STR_VALUE (value, value_size, "FALSE");
758         }
759       break;
760     case TYPE_INTEGER:
761     case TYPE_ENUMERATED:
762       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
763         {
764           p = node->down;
765           while (type_field (p->type) != TYPE_DEFAULT)
766             p = p->right;
767           if ((isdigit (p->value[0])) || (p->value[0] == '-')
768               || (p->value[0] == '+'))
769             {
770               if (_asn1_convert_integer
771                   (p->value, value, value_size, len) != ASN1_SUCCESS)
772                 return ASN1_MEM_ERROR;
773             }
774           else
775             {                   /* is an identifier like v1 */
776               p2 = node->down;
777               while (p2)
778                 {
779                   if (type_field (p2->type) == TYPE_CONSTANT)
780                     {
781                       if ((p2->name) && (!strcmp (p2->name, p->value)))
782                         {
783                           if (_asn1_convert_integer
784                               (p2->value, value, value_size,
785                                len) != ASN1_SUCCESS)
786                             return ASN1_MEM_ERROR;
787                           break;
788                         }
789                     }
790                   p2 = p2->right;
791                 }
792             }
793         }
794       else
795         {
796           len2 = -1;
797           if (asn1_get_octet_der
798               (node->value, node->value_len, &len2, value, value_size,
799                len) != ASN1_SUCCESS)
800             return ASN1_MEM_ERROR;
801         }
802       break;
803     case TYPE_OBJECT_ID:
804       if (node->type & CONST_ASSIGN)
805         {
806           value[0] = 0;
807           p = node->down;
808           while (p)
809             {
810               if (type_field (p->type) == TYPE_CONSTANT)
811                 {
812                   ADD_STR_VALUE (value, value_size, p->value);
813                   if (p->right)
814                     {
815                       ADD_STR_VALUE (value, value_size, ".");
816                     }
817                 }
818               p = p->right;
819             }
820           *len = strlen (value) + 1;
821         }
822       else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
823         {
824           p = node->down;
825           while (type_field (p->type) != TYPE_DEFAULT)
826             p = p->right;
827           PUT_STR_VALUE (value, value_size, p->value);
828         }
829       else
830         {
831           PUT_STR_VALUE (value, value_size, node->value);
832         }
833       break;
834     case TYPE_TIME:
835       PUT_STR_VALUE (value, value_size, node->value);
836       break;
837     case TYPE_OCTET_STRING:
838       len2 = -1;
839       if (asn1_get_octet_der
840           (node->value, node->value_len, &len2, value, value_size,
841            len) != ASN1_SUCCESS)
842         return ASN1_MEM_ERROR;
843       break;
844     case TYPE_GENERALSTRING:
845       len2 = -1;
846       if (asn1_get_octet_der
847           (node->value, node->value_len, &len2, value, value_size,
848            len) != ASN1_SUCCESS)
849         return ASN1_MEM_ERROR;
850       break;
851     case TYPE_BIT_STRING:
852       len2 = -1;
853       if (asn1_get_bit_der
854           (node->value, node->value_len, &len2, value, value_size,
855            len) != ASN1_SUCCESS)
856         return ASN1_MEM_ERROR;
857       break;
858     case TYPE_CHOICE:
859       PUT_STR_VALUE (value, value_size, node->down->name);
860       break;
861     case TYPE_ANY:
862       len3 = -1;
863       len2 = asn1_get_length_der (node->value, node->value_len, &len3);
864       if (len2 < 0)
865         return ASN1_DER_ERROR;
866       PUT_VALUE (value, value_size, node->value + len3, len2);
867       break;
868     default:
869       return ASN1_ELEMENT_NOT_FOUND;
870       break;
871     }
872   return ASN1_SUCCESS;
873 }
874
875
876 /**
877   * asn1_read_tag - Returns the TAG of one element inside a structure
878   * @root: pointer to a structure
879   * @name: the name of the element inside a structure.
880   * @tagValue:  variable that will contain the TAG value.
881   * @classValue: variable that will specify the TAG type.
882   *
883   * Returns the TAG and the CLASS of one element inside a structure.
884   * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
885   * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
886   * %ASN1_CLASS_CONTEXT_SPECIFIC.
887   *
888   * Returns:
889   *
890   *   ASN1_SUCCESS: Set value OK.
891   *
892   *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
893   *
894   **/
895 asn1_retCode
896 asn1_read_tag (ASN1_TYPE root, const char *name, int *tagValue,
897                int *classValue)
898 {
899   ASN1_TYPE node, p, pTag;
900
901   node = asn1_find_node (root, name);
902   if (node == NULL)
903     return ASN1_ELEMENT_NOT_FOUND;
904
905   p = node->down;
906
907   /* pTag will points to the IMPLICIT TAG */
908   pTag = NULL;
909   if (node->type & CONST_TAG)
910     {
911       while (p)
912         {
913           if (type_field (p->type) == TYPE_TAG)
914             {
915               if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
916                 pTag = p;
917               else if (p->type & CONST_EXPLICIT)
918                 pTag = NULL;
919             }
920           p = p->right;
921         }
922     }
923
924   if (pTag)
925     {
926       *tagValue = strtoul (pTag->value, NULL, 10);
927
928       if (pTag->type & CONST_APPLICATION)
929         *classValue = ASN1_CLASS_APPLICATION;
930       else if (pTag->type & CONST_UNIVERSAL)
931         *classValue = ASN1_CLASS_UNIVERSAL;
932       else if (pTag->type & CONST_PRIVATE)
933         *classValue = ASN1_CLASS_PRIVATE;
934       else
935         *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
936     }
937   else
938     {
939       *classValue = ASN1_CLASS_UNIVERSAL;
940
941       switch (type_field (node->type))
942         {
943         case TYPE_NULL:
944           *tagValue = ASN1_TAG_NULL;
945           break;
946         case TYPE_BOOLEAN:
947           *tagValue = ASN1_TAG_BOOLEAN;
948           break;
949         case TYPE_INTEGER:
950           *tagValue = ASN1_TAG_INTEGER;
951           break;
952         case TYPE_ENUMERATED:
953           *tagValue = ASN1_TAG_ENUMERATED;
954           break;
955         case TYPE_OBJECT_ID:
956           *tagValue = ASN1_TAG_OBJECT_ID;
957           break;
958         case TYPE_TIME:
959           if (node->type & CONST_UTC)
960             {
961               *tagValue = ASN1_TAG_UTCTime;
962             }
963           else
964             *tagValue = ASN1_TAG_GENERALIZEDTime;
965           break;
966         case TYPE_OCTET_STRING:
967           *tagValue = ASN1_TAG_OCTET_STRING;
968           break;
969         case TYPE_GENERALSTRING:
970           *tagValue = ASN1_TAG_GENERALSTRING;
971           break;
972         case TYPE_BIT_STRING:
973           *tagValue = ASN1_TAG_BIT_STRING;
974           break;
975         case TYPE_SEQUENCE:
976         case TYPE_SEQUENCE_OF:
977           *tagValue = ASN1_TAG_SEQUENCE;
978           break;
979         case TYPE_SET:
980         case TYPE_SET_OF:
981           *tagValue = ASN1_TAG_SET;
982           break;
983         case TYPE_TAG:
984         case TYPE_CHOICE:
985         case TYPE_ANY:
986           break;
987         default:
988           break;
989         }
990     }
991
992
993   return ASN1_SUCCESS;
994
995 }