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