ddbdb99a7b7c64fd4da7dbb4a40fea4987cf71a1
[platform/upstream/libtasn1.git] / lib / element.c
1 /*
2  * Copyright (C) 2000-2014 Free Software Foundation, Inc.
3  *
4  * This file is part of LIBTASN1.
5  *
6  * The LIBTASN1 library is free software; you can redistribute it
7  * and/or modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA
20  */
21
22 /*****************************************************/
23 /* File: element.c                                   */
24 /* Description: Functions with the read and write    */
25 /*   functions.                                      */
26 /*****************************************************/
27
28
29 #include <int.h>
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "structure.h"
33
34 #include "element.h"
35
36 void
37 _asn1_hierarchical_name (asn1_node node, char *name, int name_size)
38 {
39   asn1_node p;
40   char tmp_name[64];
41
42   p = node;
43
44   name[0] = 0;
45
46   while (p != NULL)
47     {
48       if (p->name[0] != 0)
49         {
50           _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
51             _asn1_str_cpy (name, name_size, p->name);
52           _asn1_str_cat (name, name_size, ".");
53           _asn1_str_cat (name, name_size, tmp_name);
54         }
55       p = _asn1_find_up (p);
56     }
57
58   if (name[0] == 0)
59     _asn1_str_cpy (name, name_size, "ROOT");
60 }
61
62
63 /******************************************************************/
64 /* Function : _asn1_convert_integer                               */
65 /* Description: converts an integer from a null terminated string */
66 /*              to der decoding. The convertion from a null       */
67 /*              terminated string to an integer is made with      */
68 /*              the 'strtol' function.                            */
69 /* Parameters:                                                    */
70 /*   value: null terminated string to convert.                    */
71 /*   value_out: convertion result (memory must be already         */
72 /*              allocated).                                       */
73 /*   value_out_size: number of bytes of value_out.                */
74 /*   len: number of significant byte of value_out.                */
75 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS                         */
76 /******************************************************************/
77 int
78 _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
79                        int value_out_size, int *len)
80 {
81   char negative;
82   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
83   long valtmp;
84   int k, k2;
85
86   valtmp = _asn1_strtol (value, NULL, 10);
87
88   for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
89     {
90       val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
91     }
92
93   if (val[0] & 0x80)
94     negative = 1;
95   else
96     negative = 0;
97
98   for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
99     {
100       if (negative && (val[k] != 0xFF))
101         break;
102       else if (!negative && val[k])
103         break;
104     }
105
106   if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
107     k--;
108
109   *len = SIZEOF_UNSIGNED_LONG_INT - k;
110
111   if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
112     /* VALUE_OUT is too short to contain the value conversion */
113     return ASN1_MEM_ERROR;
114
115   for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
116     value_out[k2 - k] = val[k2];
117
118 #if 0
119   printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
120   for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
121     printf (", vOut[%d]=%d", k, value_out[k]);
122   printf ("\n");
123 #endif
124
125   return ASN1_SUCCESS;
126 }
127
128
129 int
130 _asn1_append_sequence_set (asn1_node node)
131 {
132   asn1_node p, p2;
133   char temp[10];
134   long n;
135
136   if (!node || !(node->down))
137     return ASN1_GENERIC_ERROR;
138
139   p = node->down;
140   while ((type_field (p->type) == ASN1_ETYPE_TAG)
141          || (type_field (p->type) == ASN1_ETYPE_SIZE))
142     p = p->right;
143   p2 = _asn1_copy_structure3 (p);
144   while (p->right)
145     p = p->right;
146   _asn1_set_right (p, p2);
147
148   if (p->name[0] == 0)
149     _asn1_str_cpy (temp, sizeof (temp), "?1");
150   else
151     {
152       n = strtol (p->name + 1, NULL, 0);
153       n++;
154       temp[0] = '?';
155       _asn1_ltostr (n, temp + 1);
156     }
157   _asn1_set_name (p2, temp);
158   /*  p2->type |= CONST_OPTION; */
159
160   return ASN1_SUCCESS;
161 }
162
163
164 /**
165  * asn1_write_value:
166  * @node_root: pointer to a structure
167  * @name: the name of the element inside the structure that you want to set.
168  * @ivalue: vector used to specify the value to set. If len is >0,
169  *   VALUE must be a two's complement form integer.  if len=0 *VALUE
170  *   must be a null terminated string with an integer value.
171  * @len: number of bytes of *value to use to set the value:
172  *   value[0]..value[len-1] or 0 if value is a null terminated string
173  *
174  * Set the value of one element inside a structure.
175  *
176  * If an element is OPTIONAL and you want to delete it, you must use
177  * the value=NULL and len=0.  Using "pkix.asn":
178  *
179  * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
180  * NULL, 0);
181  *
182  * Description for each type:
183  *
184  * INTEGER: VALUE must contain a two's complement form integer.
185  *
186  *            value[0]=0xFF ,               len=1 -> integer=-1.
187  *            value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
188  *            value[0]=0x01 ,               len=1 -> integer= 1.
189  *            value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
190  *            value="123"                 , len=0 -> integer= 123.
191  *
192  * ENUMERATED: As INTEGER (but only with not negative numbers).
193  *
194  * BOOLEAN: VALUE must be the null terminated string "TRUE" or
195  *   "FALSE" and LEN != 0.
196  *
197  *            value="TRUE" , len=1 -> boolean=TRUE.
198  *            value="FALSE" , len=1 -> boolean=FALSE.
199  *
200  * OBJECT IDENTIFIER: VALUE must be a null terminated string with
201  *   each number separated by a dot (e.g. "1.2.3.543.1").  LEN != 0.
202  *
203  *            value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
204  *
205  * UTCTime: VALUE must be a null terminated string in one of these
206  *   formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
207  *   "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
208  *   "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'".  LEN != 0.
209  *
210  *            value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
211  *            at 12h 00m Greenwich Mean Time
212  *
213  * GeneralizedTime: VALUE must be in one of this format:
214  *   "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
215  *   "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
216  *   "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
217  *   indicates the seconds with any precision like "10.1" or "01.02".
218  *   LEN != 0
219  *
220  *            value="2001010112001.12-0700" , len=1 -> time=Jannuary
221  *            1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
222  *
223  * OCTET STRING: VALUE contains the octet string and LEN is the
224  *   number of octets.
225  *
226  *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
227  *            len=3 -> three bytes octet string
228  *
229  * GeneralString: VALUE contains the generalstring and LEN is the
230  *   number of octets.
231  *
232  *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
233  *            len=3 -> three bytes generalstring
234  *
235  * BIT STRING: VALUE contains the bit string organized by bytes and
236  *   LEN is the number of bits.
237  *
238  *   value="$\backslash$xCF" , len=6 -> bit string="110011" (six
239  *   bits)
240  *
241  * CHOICE: if NAME indicates a choice type, VALUE must specify one of
242  *   the alternatives with a null terminated string. LEN != 0. Using
243  *   "pkix.asn"\:
244  *
245  *           result=asn1_write_value(cert,
246  *           "certificate1.tbsCertificate.subject", "rdnSequence",
247  *           1);
248  *
249  * ANY: VALUE indicates the der encoding of a structure.  LEN != 0.
250  *
251  * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
252  *   LEN != 0. With this instruction another element is appended in
253  *   the sequence. The name of this element will be "?1" if it's the
254  *   first one, "?2" for the second and so on.
255  *
256  *   Using "pkix.asn"\:
257  *
258  *   result=asn1_write_value(cert,
259  *   "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
260  *
261  * SET OF: the same as SEQUENCE OF.  Using "pkix.asn":
262  *
263  *           result=asn1_write_value(cert,
264  *           "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
265  *
266  * Returns: %ASN1_SUCCESS if the value was set,
267  *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
268  *   %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
269  **/
270 int
271 asn1_write_value (asn1_node node_root, const char *name,
272                   const void *ivalue, int len)
273 {
274   asn1_node node, p, p2;
275   unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
276   int len2, k, k2, negative;
277   size_t i;
278   const unsigned char *value = ivalue;
279   unsigned int type;
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   type = type_field (node->type);
292
293   if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0))
294     {
295       p = node->down;
296       while ((type_field (p->type) == ASN1_ETYPE_TAG)
297              || (type_field (p->type) == ASN1_ETYPE_SIZE))
298         p = p->right;
299
300       while (p->right)
301         asn1_delete_structure (&p->right);
302
303       return ASN1_SUCCESS;
304     }
305
306   /* Don't allow element deletion for other types */
307   if (value == NULL)
308     {
309       return ASN1_VALUE_NOT_VALID;
310     }
311
312   switch (type)
313     {
314     case ASN1_ETYPE_BOOLEAN:
315       if (!_asn1_strcmp (value, "TRUE"))
316         {
317           if (node->type & CONST_DEFAULT)
318             {
319               p = node->down;
320               while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
321                 p = p->right;
322               if (p->type & CONST_TRUE)
323                 _asn1_set_value (node, NULL, 0);
324               else
325                 _asn1_set_value (node, "T", 1);
326             }
327           else
328             _asn1_set_value (node, "T", 1);
329         }
330       else if (!_asn1_strcmp (value, "FALSE"))
331         {
332           if (node->type & CONST_DEFAULT)
333             {
334               p = node->down;
335               while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
336                 p = p->right;
337               if (p->type & CONST_FALSE)
338                 _asn1_set_value (node, NULL, 0);
339               else
340                 _asn1_set_value (node, "F", 1);
341             }
342           else
343             _asn1_set_value (node, "F", 1);
344         }
345       else
346         return ASN1_VALUE_NOT_VALID;
347       break;
348     case ASN1_ETYPE_INTEGER:
349     case ASN1_ETYPE_ENUMERATED:
350       if (len == 0)
351         {
352           if ((isdigit (value[0])) || (value[0] == '-'))
353             {
354               value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
355               if (value_temp == NULL)
356                 return ASN1_MEM_ALLOC_ERROR;
357
358               _asn1_convert_integer (value, value_temp,
359                                      SIZEOF_UNSIGNED_LONG_INT, &len);
360             }
361           else
362             {                   /* is an identifier like v1 */
363               if (!(node->type & CONST_LIST))
364                 return ASN1_VALUE_NOT_VALID;
365               p = node->down;
366               while (p)
367                 {
368                   if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
369                     {
370                       if (!_asn1_strcmp (p->name, value))
371                         {
372                           value_temp = 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 = malloc (len);
392           if (value_temp == NULL)
393             return ASN1_MEM_ALLOC_ERROR;
394           memcpy (value_temp, value, len);
395         }
396
397       if (value_temp[0] & 0x80)
398         negative = 1;
399       else
400         negative = 0;
401
402       if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
403         {
404           free (value_temp);
405           return ASN1_VALUE_NOT_VALID;
406         }
407
408       for (k = 0; k < len - 1; k++)
409         if (negative && (value_temp[k] != 0xFF))
410           break;
411         else if (!negative && value_temp[k])
412           break;
413
414       if ((negative && !(value_temp[k] & 0x80)) ||
415           (!negative && (value_temp[k] & 0x80)))
416         k--;
417
418       _asn1_set_value_lv (node, value_temp + k, len - k);
419
420       if (node->type & CONST_DEFAULT)
421         {
422           p = node->down;
423           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
424             p = p->right;
425           if ((isdigit (p->value[0])) || (p->value[0] == '-'))
426             {
427               default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
428               if (default_temp == NULL)
429                 {
430                   free (value_temp);
431                   return ASN1_MEM_ALLOC_ERROR;
432                 }
433
434               _asn1_convert_integer (p->value, default_temp,
435                                      SIZEOF_UNSIGNED_LONG_INT, &len2);
436             }
437           else
438             {                   /* is an identifier like v1 */
439               if (!(node->type & CONST_LIST))
440                 {
441                   free (value_temp);
442                   return ASN1_VALUE_NOT_VALID;
443                 }
444               p2 = node->down;
445               while (p2)
446                 {
447                   if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
448                     {
449                       if (!_asn1_strcmp (p2->name, p->value))
450                         {
451                           default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
452                           if (default_temp == NULL)
453                             {
454                               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                   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           free (default_temp);
486         }
487       free (value_temp);
488       break;
489     case ASN1_ETYPE_OBJECT_ID:
490       for (i = 0; i < _asn1_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) != ASN1_ETYPE_DEFAULT)
497             p = p->right;
498           if (!_asn1_strcmp (value, p->value))
499             {
500               _asn1_set_value (node, NULL, 0);
501               break;
502             }
503         }
504       _asn1_set_value (node, value, _asn1_strlen (value) + 1);
505       break;
506     case ASN1_ETYPE_UTC_TIME:
507       {
508         len = _asn1_strlen (value);
509         if (len < 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 (len)
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, len);
545       }
546       break;
547     case ASN1_ETYPE_GENERALIZED_TIME:
548       len = _asn1_strlen (value);
549       _asn1_set_value (node, value, len);
550       break;
551     case ASN1_ETYPE_OCTET_STRING:
552     case ASN1_ETYPE_GENERALSTRING:
553     case ASN1_ETYPE_NUMERIC_STRING:
554     case ASN1_ETYPE_IA5_STRING:
555     case ASN1_ETYPE_TELETEX_STRING:
556     case ASN1_ETYPE_PRINTABLE_STRING:
557     case ASN1_ETYPE_UNIVERSAL_STRING:
558     case ASN1_ETYPE_BMP_STRING:
559     case ASN1_ETYPE_UTF8_STRING:
560     case ASN1_ETYPE_VISIBLE_STRING:
561       if (len == 0)
562         len = _asn1_strlen (value);
563       _asn1_set_value_lv (node, value, len);
564       break;
565     case ASN1_ETYPE_BIT_STRING:
566       if (len == 0)
567         len = _asn1_strlen (value);
568       asn1_length_der ((len >> 3) + 2, NULL, &len2);
569       temp = malloc ((len >> 3) + 2 + len2);
570       if (temp == NULL)
571         return ASN1_MEM_ALLOC_ERROR;
572
573       asn1_bit_der (value, len, temp, &len2);
574       _asn1_set_value_m (node, temp, len2);
575       temp = NULL;
576       break;
577     case ASN1_ETYPE_CHOICE:
578       p = node->down;
579       while (p)
580         {
581           if (!_asn1_strcmp (p->name, value))
582             {
583               p2 = node->down;
584               while (p2)
585                 {
586                   if (p2 != p)
587                     {
588                       asn1_delete_structure (&p2);
589                       p2 = node->down;
590                     }
591                   else
592                     p2 = p2->right;
593                 }
594               break;
595             }
596           p = p->right;
597         }
598       if (!p)
599         return ASN1_ELEMENT_NOT_FOUND;
600       break;
601     case ASN1_ETYPE_ANY:
602       _asn1_set_value_lv (node, value, len);
603       break;
604     case ASN1_ETYPE_SEQUENCE_OF:
605     case ASN1_ETYPE_SET_OF:
606       if (_asn1_strcmp (value, "NEW"))
607         return ASN1_VALUE_NOT_VALID;
608       _asn1_append_sequence_set (node);
609       break;
610     default:
611       return ASN1_ELEMENT_NOT_FOUND;
612       break;
613     }
614
615   return ASN1_SUCCESS;
616 }
617
618
619 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
620         *len = data_size; \
621         if (ptr_size < data_size) { \
622                 return ASN1_MEM_ERROR; \
623         } else { \
624                 if (ptr) \
625                   memcpy( ptr, data, data_size); \
626         }
627
628 #define PUT_STR_VALUE( ptr, ptr_size, data) \
629         *len = _asn1_strlen(data) + 1; \
630         if (ptr_size < *len) { \
631                 return ASN1_MEM_ERROR; \
632         } else { \
633                 /* this strcpy is checked */ \
634                 if (ptr) \
635                   _asn1_strcpy(ptr, data); \
636         }
637
638 #define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \
639         *len = data_size + 1; \
640         if (ptr_size < *len) { \
641                 return ASN1_MEM_ERROR; \
642         } else { \
643                 /* this strcpy is checked */ \
644                 if (ptr) { \
645                   memcpy(ptr, data, data_size); \
646                   ptr[data_size] = 0; \
647                 } \
648         }
649
650 #define ADD_STR_VALUE( ptr, ptr_size, data) \
651         *len = (int) _asn1_strlen(data) + 1; \
652         if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
653                 return ASN1_MEM_ERROR; \
654         } else { \
655                 /* this strcat is checked */ \
656                 if (ptr) _asn1_strcat(ptr, data); \
657         }
658
659 /**
660  * asn1_read_value:
661  * @root: pointer to a structure.
662  * @name: the name of the element inside a structure that you want to read.
663  * @ivalue: vector that will contain the element's content, must be a
664  *   pointer to memory cells already allocated.
665  * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
666  *   holds the sizeof value.
667  *
668  * Returns the value of one element inside a structure.
669  *
670  * If an element is OPTIONAL and the function "read_value" returns
671  * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
672  * in the der encoding that created the structure.  The first element
673  * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
674  * so on.
675  *
676  * INTEGER: VALUE will contain a two's complement form integer.
677  *
678  *            integer=-1  -> value[0]=0xFF , len=1.
679  *            integer=1   -> value[0]=0x01 , len=1.
680  *
681  * ENUMERATED: As INTEGER (but only with not negative numbers).
682  *
683  * BOOLEAN: VALUE will be the null terminated string "TRUE" or
684  *   "FALSE" and LEN=5 or LEN=6.
685  *
686  * OBJECT IDENTIFIER: VALUE will be a null terminated string with
687  *   each number separated by a dot (i.e. "1.2.3.543.1").
688  *
689  *                      LEN = strlen(VALUE)+1
690  *
691  * UTCTime: VALUE will be a null terminated string in one of these
692  *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
693  *   LEN=strlen(VALUE)+1.
694  *
695  * GeneralizedTime: VALUE will be a null terminated string in the
696  *   same format used to set the value.
697  *
698  * OCTET STRING: VALUE will contain the octet string and LEN will be
699  *   the number of octets.
700  *
701  * GeneralString: VALUE will contain the generalstring and LEN will
702  *   be the number of octets.
703  *
704  * BIT STRING: VALUE will contain the bit string organized by bytes
705  *   and LEN will be the number of bits.
706  *
707  * CHOICE: If NAME indicates a choice type, VALUE will specify the
708  *   alternative selected.
709  *
710  * ANY: If NAME indicates an any type, VALUE will indicate the DER
711  *   encoding of the structure actually used.
712  *
713  * Returns: %ASN1_SUCCESS if value is returned,
714  *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
715  *   %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
716  *   selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
717  *   to store the result, and in this case @len will contain the number of
718  *   bytes needed.
719  **/
720 int
721 asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
722 {
723   return asn1_read_value_type (root, name, ivalue, len, NULL);
724 }
725
726 /**
727  * asn1_read_value_type:
728  * @root: pointer to a structure.
729  * @name: the name of the element inside a structure that you want to read.
730  * @ivalue: vector that will contain the element's content, must be a
731  *   pointer to memory cells already allocated.
732  * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
733  *   holds the sizeof value.
734  * @etype: The type of the value read (ASN1_ETYPE)
735  *
736  * Returns the value of one element inside a structure.
737  *
738  * If an element is OPTIONAL and the function "read_value" returns
739  * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
740  * in the der encoding that created the structure.  The first element
741  * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
742  * so on.
743  *
744  * INTEGER: VALUE will contain a two's complement form integer.
745  *
746  *            integer=-1  -> value[0]=0xFF , len=1.
747  *            integer=1   -> value[0]=0x01 , len=1.
748  *
749  * ENUMERATED: As INTEGER (but only with not negative numbers).
750  *
751  * BOOLEAN: VALUE will be the null terminated string "TRUE" or
752  *   "FALSE" and LEN=5 or LEN=6.
753  *
754  * OBJECT IDENTIFIER: VALUE will be a null terminated string with
755  *   each number separated by a dot (i.e. "1.2.3.543.1").
756  *
757  *                      LEN = strlen(VALUE)+1
758  *
759  * UTCTime: VALUE will be a null terminated string in one of these
760  *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
761  *   LEN=strlen(VALUE)+1.
762  *
763  * GeneralizedTime: VALUE will be a null terminated string in the
764  *   same format used to set the value.
765  *
766  * OCTET STRING: VALUE will contain the octet string and LEN will be
767  *   the number of octets.
768  *
769  * GeneralString: VALUE will contain the generalstring and LEN will
770  *   be the number of octets.
771  *
772  * BIT STRING: VALUE will contain the bit string organized by bytes
773  *   and LEN will be the number of bits.
774  *
775  * CHOICE: If NAME indicates a choice type, VALUE will specify the
776  *   alternative selected.
777  *
778  * ANY: If NAME indicates an any type, VALUE will indicate the DER
779  *   encoding of the structure actually used.
780  *
781  * Returns: %ASN1_SUCCESS if value is returned,
782  *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
783  *   %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
784  *   selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
785  *   to store the result, and in this case @len will contain the number of
786  *   bytes needed.
787  **/
788 int
789 asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
790                       int *len, unsigned int *etype)
791 {
792   asn1_node node, p, p2;
793   int len2, len3;
794   int value_size = *len;
795   unsigned char *value = ivalue;
796   unsigned type;
797
798   node = asn1_find_node (root, name);
799   if (node == NULL)
800     return ASN1_ELEMENT_NOT_FOUND;
801
802   type = type_field (node->type);
803
804   if ((type != ASN1_ETYPE_NULL) &&
805       (type != ASN1_ETYPE_CHOICE) &&
806       !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
807       (node->value == NULL))
808     return ASN1_VALUE_NOT_FOUND;
809
810   if (etype)
811     *etype = type;
812   switch (type)
813     {
814     case ASN1_ETYPE_NULL:
815       PUT_STR_VALUE (value, value_size, "NULL");
816       break;
817     case ASN1_ETYPE_BOOLEAN:
818       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
819         {
820           p = node->down;
821           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
822             p = p->right;
823           if (p->type & CONST_TRUE)
824             {
825               PUT_STR_VALUE (value, value_size, "TRUE");
826             }
827           else
828             {
829               PUT_STR_VALUE (value, value_size, "FALSE");
830             }
831         }
832       else if (node->value[0] == 'T')
833         {
834           PUT_STR_VALUE (value, value_size, "TRUE");
835         }
836       else
837         {
838           PUT_STR_VALUE (value, value_size, "FALSE");
839         }
840       break;
841     case ASN1_ETYPE_INTEGER:
842     case ASN1_ETYPE_ENUMERATED:
843       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
844         {
845           p = node->down;
846           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
847             p = p->right;
848           if ((isdigit (p->value[0])) || (p->value[0] == '-')
849               || (p->value[0] == '+'))
850             {
851               if (_asn1_convert_integer
852                   (p->value, value, value_size, len) != ASN1_SUCCESS)
853                 return ASN1_MEM_ERROR;
854             }
855           else
856             {                   /* is an identifier like v1 */
857               p2 = node->down;
858               while (p2)
859                 {
860                   if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
861                     {
862                       if (!_asn1_strcmp (p2->name, p->value))
863                         {
864                           if (_asn1_convert_integer
865                               (p2->value, value, value_size,
866                                len) != ASN1_SUCCESS)
867                             return ASN1_MEM_ERROR;
868                           break;
869                         }
870                     }
871                   p2 = p2->right;
872                 }
873             }
874         }
875       else
876         {
877           len2 = -1;
878           if (asn1_get_octet_der
879               (node->value, node->value_len, &len2, value, value_size,
880                len) != ASN1_SUCCESS)
881             return ASN1_MEM_ERROR;
882         }
883       break;
884     case ASN1_ETYPE_OBJECT_ID:
885       if (node->type & CONST_ASSIGN)
886         {
887           value[0] = 0;
888           p = node->down;
889           while (p)
890             {
891               if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
892                 {
893                   ADD_STR_VALUE (value, value_size, p->value);
894                   if (p->right)
895                     {
896                       ADD_STR_VALUE (value, value_size, ".");
897                     }
898                 }
899               p = p->right;
900             }
901           *len = _asn1_strlen (value) + 1;
902         }
903       else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
904         {
905           p = node->down;
906           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
907             p = p->right;
908           PUT_STR_VALUE (value, value_size, p->value);
909         }
910       else
911         {
912           PUT_STR_VALUE (value, value_size, node->value);
913         }
914       break;
915     case ASN1_ETYPE_GENERALIZED_TIME:
916     case ASN1_ETYPE_UTC_TIME:
917       PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
918       break;
919     case ASN1_ETYPE_OCTET_STRING:
920     case ASN1_ETYPE_GENERALSTRING:
921     case ASN1_ETYPE_NUMERIC_STRING:
922     case ASN1_ETYPE_IA5_STRING:
923     case ASN1_ETYPE_TELETEX_STRING:
924     case ASN1_ETYPE_PRINTABLE_STRING:
925     case ASN1_ETYPE_UNIVERSAL_STRING:
926     case ASN1_ETYPE_BMP_STRING:
927     case ASN1_ETYPE_UTF8_STRING:
928     case ASN1_ETYPE_VISIBLE_STRING:
929       len2 = -1;
930       if (asn1_get_octet_der
931           (node->value, node->value_len, &len2, value, value_size,
932            len) != ASN1_SUCCESS)
933         return ASN1_MEM_ERROR;
934       break;
935     case ASN1_ETYPE_BIT_STRING:
936       len2 = -1;
937       if (asn1_get_bit_der
938           (node->value, node->value_len, &len2, value, value_size,
939            len) != ASN1_SUCCESS)
940         return ASN1_MEM_ERROR;
941       break;
942     case ASN1_ETYPE_CHOICE:
943       PUT_STR_VALUE (value, value_size, node->down->name);
944       break;
945     case ASN1_ETYPE_ANY:
946       len3 = -1;
947       len2 = asn1_get_length_der (node->value, node->value_len, &len3);
948       if (len2 < 0)
949         return ASN1_DER_ERROR;
950       PUT_VALUE (value, value_size, node->value + len3, len2);
951       break;
952     default:
953       return ASN1_ELEMENT_NOT_FOUND;
954       break;
955     }
956   return ASN1_SUCCESS;
957 }
958
959
960 /**
961  * asn1_read_tag:
962  * @root: pointer to a structure
963  * @name: the name of the element inside a structure.
964  * @tagValue:  variable that will contain the TAG value.
965  * @classValue: variable that will specify the TAG type.
966  *
967  * Returns the TAG and the CLASS of one element inside a structure.
968  * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
969  * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
970  * %ASN1_CLASS_CONTEXT_SPECIFIC.
971  *
972  * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
973  *   @name is not a valid element.
974  **/
975 int
976 asn1_read_tag (asn1_node root, const char *name, int *tagValue,
977                int *classValue)
978 {
979   asn1_node node, p, pTag;
980
981   node = asn1_find_node (root, name);
982   if (node == NULL)
983     return ASN1_ELEMENT_NOT_FOUND;
984
985   p = node->down;
986
987   /* pTag will points to the IMPLICIT TAG */
988   pTag = NULL;
989   if (node->type & CONST_TAG)
990     {
991       while (p)
992         {
993           if (type_field (p->type) == ASN1_ETYPE_TAG)
994             {
995               if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
996                 pTag = p;
997               else if (p->type & CONST_EXPLICIT)
998                 pTag = NULL;
999             }
1000           p = p->right;
1001         }
1002     }
1003
1004   if (pTag)
1005     {
1006       *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
1007
1008       if (pTag->type & CONST_APPLICATION)
1009         *classValue = ASN1_CLASS_APPLICATION;
1010       else if (pTag->type & CONST_UNIVERSAL)
1011         *classValue = ASN1_CLASS_UNIVERSAL;
1012       else if (pTag->type & CONST_PRIVATE)
1013         *classValue = ASN1_CLASS_PRIVATE;
1014       else
1015         *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
1016     }
1017   else
1018     {
1019       unsigned type = type_field (node->type);
1020       *classValue = ASN1_CLASS_UNIVERSAL;
1021
1022       switch (type)
1023         {
1024         CASE_HANDLED_ETYPES:
1025           *tagValue = _asn1_tags[type].tag;
1026           break;
1027         case ASN1_ETYPE_TAG:
1028         case ASN1_ETYPE_CHOICE:
1029         case ASN1_ETYPE_ANY:
1030           *tagValue = -1;
1031           break;
1032         default:
1033           break;
1034         }
1035     }
1036
1037   return ASN1_SUCCESS;
1038 }
1039
1040 /**
1041  * asn1_read_node_value:
1042  * @node: pointer to a node.
1043  * @data: a point to a asn1_data_node_st
1044  *
1045  * Returns the value a data node inside a asn1_node structure.
1046  * The data returned should be handled as constant values.
1047  *
1048  * Returns: %ASN1_SUCCESS if the node exists.
1049  **/
1050 int
1051 asn1_read_node_value (asn1_node node, asn1_data_node_st * data)
1052 {
1053   data->name = node->name;
1054   data->value = node->value;
1055   data->value_len = node->value_len;
1056   data->type = type_field (node->type);
1057
1058   return ASN1_SUCCESS;
1059 }