remove -Werror from automake
[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_get_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   if (value_out != NULL)
116     {
117       for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
118         value_out[k2 - k] = val[k2];
119     }
120
121 #if 0
122   printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
123   for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
124     printf (", vOut[%d]=%d", k, value_out[k]);
125   printf ("\n");
126 #endif
127
128   return ASN1_SUCCESS;
129 }
130
131
132 int
133 _asn1_append_sequence_set (asn1_node node, asn1_node *ptail)
134 {
135   asn1_node p, p2;
136   char temp[LTOSTR_MAX_SIZE];
137   long n;
138
139   if (!node || !(node->down))
140     return ASN1_GENERIC_ERROR;
141
142   p = node->down;
143   while ((type_field (p->type) == ASN1_ETYPE_TAG)
144          || (type_field (p->type) == ASN1_ETYPE_SIZE))
145     p = p->right;
146   p2 = _asn1_copy_structure3 (p);
147
148   if (ptail == NULL || *ptail == NULL || (*ptail)->up != p->up)
149     while (p->right) {
150       p = p->right;
151     }
152   else
153     {
154       p = *ptail;
155     }
156
157   _asn1_set_right (p, p2);
158   if (ptail)
159     *ptail = p2;
160
161   if (p->name[0] == 0)
162     _asn1_str_cpy (temp, sizeof (temp), "?1");
163   else
164     {
165       n = strtol (p->name + 1, NULL, 0);
166       n++;
167       temp[0] = '?';
168       _asn1_ltostr (n, temp + 1);
169     }
170   _asn1_set_name (p2, temp);
171   /*  p2->type |= CONST_OPTION; */
172
173   return ASN1_SUCCESS;
174 }
175
176
177 /**
178  * asn1_write_value:
179  * @node_root: pointer to a structure
180  * @name: the name of the element inside the structure that you want to set.
181  * @ivalue: vector used to specify the value to set. If len is >0,
182  *   VALUE must be a two's complement form integer.  if len=0 *VALUE
183  *   must be a null terminated string with an integer value.
184  * @len: number of bytes of *value to use to set the value:
185  *   value[0]..value[len-1] or 0 if value is a null terminated string
186  *
187  * Set the value of one element inside a structure.
188  *
189  * If an element is OPTIONAL and you want to delete it, you must use
190  * the value=NULL and len=0.  Using "pkix.asn":
191  *
192  * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
193  * NULL, 0);
194  *
195  * Description for each type:
196  *
197  * INTEGER: VALUE must contain a two's complement form integer.
198  *
199  *            value[0]=0xFF ,               len=1 -> integer=-1.
200  *            value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
201  *            value[0]=0x01 ,               len=1 -> integer= 1.
202  *            value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
203  *            value="123"                 , len=0 -> integer= 123.
204  *
205  * ENUMERATED: As INTEGER (but only with not negative numbers).
206  *
207  * BOOLEAN: VALUE must be the null terminated string "TRUE" or
208  *   "FALSE" and LEN != 0.
209  *
210  *            value="TRUE" , len=1 -> boolean=TRUE.
211  *            value="FALSE" , len=1 -> boolean=FALSE.
212  *
213  * OBJECT IDENTIFIER: VALUE must be a null terminated string with
214  *   each number separated by a dot (e.g. "1.2.3.543.1").  LEN != 0.
215  *
216  *            value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
217  *
218  * UTCTime: VALUE must be a null terminated string in one of these
219  *   formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
220  *   "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
221  *   "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'".  LEN != 0.
222  *
223  *            value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
224  *            at 12h 00m Greenwich Mean Time
225  *
226  * GeneralizedTime: VALUE must be in one of this format:
227  *   "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
228  *   "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
229  *   "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
230  *   indicates the seconds with any precision like "10.1" or "01.02".
231  *   LEN != 0
232  *
233  *            value="2001010112001.12-0700" , len=1 -> time=Jannuary
234  *            1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
235  *
236  * OCTET STRING: VALUE contains the octet string and LEN is the
237  *   number of octets.
238  *
239  *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
240  *            len=3 -> three bytes octet string
241  *
242  * GeneralString: VALUE contains the generalstring and LEN is the
243  *   number of octets.
244  *
245  *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
246  *            len=3 -> three bytes generalstring
247  *
248  * BIT STRING: VALUE contains the bit string organized by bytes and
249  *   LEN is the number of bits.
250  *
251  *   value="$\backslash$xCF" , len=6 -> bit string="110011" (six
252  *   bits)
253  *
254  * CHOICE: if NAME indicates a choice type, VALUE must specify one of
255  *   the alternatives with a null terminated string. LEN != 0. Using
256  *   "pkix.asn"\:
257  *
258  *           result=asn1_write_value(cert,
259  *           "certificate1.tbsCertificate.subject", "rdnSequence",
260  *           1);
261  *
262  * ANY: VALUE indicates the der encoding of a structure.  LEN != 0.
263  *
264  * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
265  *   LEN != 0. With this instruction another element is appended in
266  *   the sequence. The name of this element will be "?1" if it's the
267  *   first one, "?2" for the second and so on.
268  *
269  *   Using "pkix.asn"\:
270  *
271  *   result=asn1_write_value(cert,
272  *   "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
273  *
274  * SET OF: the same as SEQUENCE OF.  Using "pkix.asn":
275  *
276  *           result=asn1_write_value(cert,
277  *           "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
278  *
279  * Returns: %ASN1_SUCCESS if the value was set,
280  *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
281  *   %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
282  **/
283 int
284 asn1_write_value (asn1_node node_root, const char *name,
285                   const void *ivalue, int len)
286 {
287   asn1_node node, p, p2;
288   unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
289   int len2, k, k2, negative;
290   size_t i;
291   const unsigned char *value = ivalue;
292   unsigned int type;
293
294   node = asn1_find_node (node_root, name);
295   if (node == NULL)
296     return ASN1_ELEMENT_NOT_FOUND;
297
298   if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
299     {
300       asn1_delete_structure (&node);
301       return ASN1_SUCCESS;
302     }
303
304   type = type_field (node->type);
305
306   if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0))
307     {
308       p = node->down;
309       while ((type_field (p->type) == ASN1_ETYPE_TAG)
310              || (type_field (p->type) == ASN1_ETYPE_SIZE))
311         p = p->right;
312
313       while (p->right)
314         asn1_delete_structure (&p->right);
315
316       return ASN1_SUCCESS;
317     }
318
319   /* Don't allow element deletion for other types */
320   if (value == NULL)
321     {
322       return ASN1_VALUE_NOT_VALID;
323     }
324
325   switch (type)
326     {
327     case ASN1_ETYPE_BOOLEAN:
328       if (!_asn1_strcmp (value, "TRUE"))
329         {
330           if (node->type & CONST_DEFAULT)
331             {
332               p = node->down;
333               while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
334                 p = p->right;
335               if (p->type & CONST_TRUE)
336                 _asn1_set_value (node, NULL, 0);
337               else
338                 _asn1_set_value (node, "T", 1);
339             }
340           else
341             _asn1_set_value (node, "T", 1);
342         }
343       else if (!_asn1_strcmp (value, "FALSE"))
344         {
345           if (node->type & CONST_DEFAULT)
346             {
347               p = node->down;
348               while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
349                 p = p->right;
350               if (p->type & CONST_FALSE)
351                 _asn1_set_value (node, NULL, 0);
352               else
353                 _asn1_set_value (node, "F", 1);
354             }
355           else
356             _asn1_set_value (node, "F", 1);
357         }
358       else
359         return ASN1_VALUE_NOT_VALID;
360       break;
361     case ASN1_ETYPE_INTEGER:
362     case ASN1_ETYPE_ENUMERATED:
363       if (len == 0)
364         {
365           if ((isdigit (value[0])) || (value[0] == '-'))
366             {
367               value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
368               if (value_temp == NULL)
369                 return ASN1_MEM_ALLOC_ERROR;
370
371               _asn1_convert_integer (value, value_temp,
372                                      SIZEOF_UNSIGNED_LONG_INT, &len);
373             }
374           else
375             {                   /* is an identifier like v1 */
376               if (!(node->type & CONST_LIST))
377                 return ASN1_VALUE_NOT_VALID;
378               p = node->down;
379               while (p)
380                 {
381                   if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
382                     {
383                       if (!_asn1_strcmp (p->name, value))
384                         {
385                           value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
386                           if (value_temp == NULL)
387                             return ASN1_MEM_ALLOC_ERROR;
388
389                           _asn1_convert_integer (p->value,
390                                                  value_temp,
391                                                  SIZEOF_UNSIGNED_LONG_INT,
392                                                  &len);
393                           break;
394                         }
395                     }
396                   p = p->right;
397                 }
398               if (p == NULL)
399                 return ASN1_VALUE_NOT_VALID;
400             }
401         }
402       else
403         {                       /* len != 0 */
404           value_temp = malloc (len);
405           if (value_temp == NULL)
406             return ASN1_MEM_ALLOC_ERROR;
407           memcpy (value_temp, value, len);
408         }
409
410       if (value_temp[0] & 0x80)
411         negative = 1;
412       else
413         negative = 0;
414
415       if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
416         {
417           free (value_temp);
418           return ASN1_VALUE_NOT_VALID;
419         }
420
421       for (k = 0; k < len - 1; k++)
422         if (negative && (value_temp[k] != 0xFF))
423           break;
424         else if (!negative && value_temp[k])
425           break;
426
427       if ((negative && !(value_temp[k] & 0x80)) ||
428           (!negative && (value_temp[k] & 0x80)))
429         k--;
430
431       _asn1_set_value_lv (node, value_temp + k, len - k);
432
433       if (node->type & CONST_DEFAULT)
434         {
435           p = node->down;
436           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
437             p = p->right;
438           if ((isdigit (p->value[0])) || (p->value[0] == '-'))
439             {
440               default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
441               if (default_temp == NULL)
442                 {
443                   free (value_temp);
444                   return ASN1_MEM_ALLOC_ERROR;
445                 }
446
447               _asn1_convert_integer (p->value, default_temp,
448                                      SIZEOF_UNSIGNED_LONG_INT, &len2);
449             }
450           else
451             {                   /* is an identifier like v1 */
452               if (!(node->type & CONST_LIST))
453                 {
454                   free (value_temp);
455                   return ASN1_VALUE_NOT_VALID;
456                 }
457               p2 = node->down;
458               while (p2)
459                 {
460                   if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
461                     {
462                       if (!_asn1_strcmp (p2->name, p->value))
463                         {
464                           default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
465                           if (default_temp == NULL)
466                             {
467                               free (value_temp);
468                               return ASN1_MEM_ALLOC_ERROR;
469                             }
470
471                           _asn1_convert_integer (p2->value,
472                                                  default_temp,
473                                                  SIZEOF_UNSIGNED_LONG_INT,
474                                                  &len2);
475                           break;
476                         }
477                     }
478                   p2 = p2->right;
479                 }
480               if (p2 == NULL)
481                 {
482                   free (value_temp);
483                   return ASN1_VALUE_NOT_VALID;
484                 }
485             }
486
487
488           if ((len - k) == len2)
489             {
490               for (k2 = 0; k2 < len2; k2++)
491                 if (value_temp[k + k2] != default_temp[k2])
492                   {
493                     break;
494                   }
495               if (k2 == len2)
496                 _asn1_set_value (node, NULL, 0);
497             }
498           free (default_temp);
499         }
500       free (value_temp);
501       break;
502     case ASN1_ETYPE_OBJECT_ID:
503       for (i = 0; i < _asn1_strlen (value); i++)
504         if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
505           return ASN1_VALUE_NOT_VALID;
506       if (node->type & CONST_DEFAULT)
507         {
508           p = node->down;
509           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
510             p = p->right;
511           if (!_asn1_strcmp (value, p->value))
512             {
513               _asn1_set_value (node, NULL, 0);
514               break;
515             }
516         }
517       _asn1_set_value (node, value, _asn1_strlen (value) + 1);
518       break;
519     case ASN1_ETYPE_UTC_TIME:
520       {
521         len = _asn1_strlen (value);
522         if (len < 11)
523           return ASN1_VALUE_NOT_VALID;
524         for (k = 0; k < 10; k++)
525           if (!isdigit (value[k]))
526             return ASN1_VALUE_NOT_VALID;
527         switch (len)
528           {
529           case 11:
530             if (value[10] != 'Z')
531               return ASN1_VALUE_NOT_VALID;
532             break;
533           case 13:
534             if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
535                 (value[12] != 'Z'))
536               return ASN1_VALUE_NOT_VALID;
537             break;
538           case 15:
539             if ((value[10] != '+') && (value[10] != '-'))
540               return ASN1_VALUE_NOT_VALID;
541             for (k = 11; k < 15; k++)
542               if (!isdigit (value[k]))
543                 return ASN1_VALUE_NOT_VALID;
544             break;
545           case 17:
546             if ((!isdigit (value[10])) || (!isdigit (value[11])))
547               return ASN1_VALUE_NOT_VALID;
548             if ((value[12] != '+') && (value[12] != '-'))
549               return ASN1_VALUE_NOT_VALID;
550             for (k = 13; k < 17; k++)
551               if (!isdigit (value[k]))
552                 return ASN1_VALUE_NOT_VALID;
553             break;
554           default:
555             return ASN1_VALUE_NOT_FOUND;
556           }
557         _asn1_set_value (node, value, len);
558       }
559       break;
560     case ASN1_ETYPE_GENERALIZED_TIME:
561       len = _asn1_strlen (value);
562       _asn1_set_value (node, value, len);
563       break;
564     case ASN1_ETYPE_OCTET_STRING:
565     case ASN1_ETYPE_GENERALSTRING:
566     case ASN1_ETYPE_NUMERIC_STRING:
567     case ASN1_ETYPE_IA5_STRING:
568     case ASN1_ETYPE_TELETEX_STRING:
569     case ASN1_ETYPE_PRINTABLE_STRING:
570     case ASN1_ETYPE_UNIVERSAL_STRING:
571     case ASN1_ETYPE_BMP_STRING:
572     case ASN1_ETYPE_UTF8_STRING:
573     case ASN1_ETYPE_VISIBLE_STRING:
574       if (len == 0)
575         len = _asn1_strlen (value);
576       _asn1_set_value_lv (node, value, len);
577       break;
578     case ASN1_ETYPE_BIT_STRING:
579       if (len == 0)
580         len = _asn1_strlen (value);
581       asn1_length_der ((len >> 3) + 2, NULL, &len2);
582       temp = malloc ((len >> 3) + 2 + len2);
583       if (temp == NULL)
584         return ASN1_MEM_ALLOC_ERROR;
585
586       asn1_bit_der (value, len, temp, &len2);
587       _asn1_set_value_m (node, temp, len2);
588       temp = NULL;
589       break;
590     case ASN1_ETYPE_CHOICE:
591       p = node->down;
592       while (p)
593         {
594           if (!_asn1_strcmp (p->name, value))
595             {
596               p2 = node->down;
597               while (p2)
598                 {
599                   if (p2 != p)
600                     {
601                       asn1_delete_structure (&p2);
602                       p2 = node->down;
603                     }
604                   else
605                     p2 = p2->right;
606                 }
607               break;
608             }
609           p = p->right;
610         }
611       if (!p)
612         return ASN1_ELEMENT_NOT_FOUND;
613       break;
614     case ASN1_ETYPE_ANY:
615       _asn1_set_value_lv (node, value, len);
616       break;
617     case ASN1_ETYPE_SEQUENCE_OF:
618     case ASN1_ETYPE_SET_OF:
619       if (_asn1_strcmp (value, "NEW"))
620         return ASN1_VALUE_NOT_VALID;
621       _asn1_append_sequence_set (node, NULL);
622       break;
623     default:
624       return ASN1_ELEMENT_NOT_FOUND;
625       break;
626     }
627
628   return ASN1_SUCCESS;
629 }
630
631
632 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
633         *len = data_size; \
634         if (ptr_size < data_size) { \
635                 return ASN1_MEM_ERROR; \
636         } else { \
637                 if (ptr && data_size > 0) \
638                   memcpy (ptr, data, data_size); \
639         }
640
641 #define PUT_STR_VALUE( ptr, ptr_size, data) \
642         *len = _asn1_strlen (data) + 1; \
643         if (ptr_size < *len) { \
644                 return ASN1_MEM_ERROR; \
645         } else { \
646                 /* this strcpy is checked */ \
647                 if (ptr) { \
648                   _asn1_strcpy (ptr, data); \
649                 } \
650         }
651
652 #define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \
653         *len = data_size + 1; \
654         if (ptr_size < *len) { \
655                 return ASN1_MEM_ERROR; \
656         } else { \
657                 /* this strcpy is checked */ \
658                 if (ptr) { \
659                   if (data_size > 0) \
660                     memcpy (ptr, data, data_size); \
661                   ptr[data_size] = 0; \
662                 } \
663         }
664
665 #define ADD_STR_VALUE( ptr, ptr_size, data) \
666         *len += _asn1_strlen(data); \
667         if (ptr_size < (int) *len) { \
668                 (*len)++; \
669                 return ASN1_MEM_ERROR; \
670         } else { \
671                 /* this strcat is checked */ \
672                 if (ptr) _asn1_strcat (ptr, data); \
673         }
674
675 /**
676  * asn1_read_value:
677  * @root: pointer to a structure.
678  * @name: the name of the element inside a structure that you want to read.
679  * @ivalue: vector that will contain the element's content, must be a
680  *   pointer to memory cells already allocated (may be %NULL).
681  * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
682  *   holds the sizeof value.
683  *
684  * Returns the value of one element inside a structure. 
685  * If an element is OPTIONAL and this returns
686  * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
687  * in the der encoding that created the structure.  The first element
688  * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
689  * so on. If the @root provided is a node to specific sequence element,
690  * then the keyword "?CURRENT" is also acceptable and indicates the
691  * current sequence element of this node.
692  *
693  * Note that there can be valid values with length zero. In these case
694  * this function will succeed and @len will be zero.
695  *
696  * INTEGER: VALUE will contain a two's complement form integer.
697  *
698  *            integer=-1  -> value[0]=0xFF , len=1.
699  *            integer=1   -> value[0]=0x01 , len=1.
700  *
701  * ENUMERATED: As INTEGER (but only with not negative numbers).
702  *
703  * BOOLEAN: VALUE will be the null terminated string "TRUE" or
704  *   "FALSE" and LEN=5 or LEN=6.
705  *
706  * OBJECT IDENTIFIER: VALUE will be a null terminated string with
707  *   each number separated by a dot (i.e. "1.2.3.543.1").
708  *
709  *                      LEN = strlen(VALUE)+1
710  *
711  * UTCTime: VALUE will be a null terminated string in one of these
712  *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
713  *   LEN=strlen(VALUE)+1.
714  *
715  * GeneralizedTime: VALUE will be a null terminated string in the
716  *   same format used to set the value.
717  *
718  * OCTET STRING: VALUE will contain the octet string and LEN will be
719  *   the number of octets.
720  *
721  * GeneralString: VALUE will contain the generalstring and LEN will
722  *   be the number of octets.
723  *
724  * BIT STRING: VALUE will contain the bit string organized by bytes
725  *   and LEN will be the number of bits.
726  *
727  * CHOICE: If NAME indicates a choice type, VALUE will specify the
728  *   alternative selected.
729  *
730  * ANY: If NAME indicates an any type, VALUE will indicate the DER
731  *   encoding of the structure actually used.
732  *
733  * Returns: %ASN1_SUCCESS if value is returned,
734  *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
735  *   %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
736  *   selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
737  *   to store the result, and in this case @len will contain the number of
738  *   bytes needed.
739  **/
740 int
741 asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
742 {
743   return asn1_read_value_type (root, name, ivalue, len, NULL);
744 }
745
746 /**
747  * asn1_read_value_type:
748  * @root: pointer to a structure.
749  * @name: the name of the element inside a structure that you want to read.
750  * @ivalue: vector that will contain the element's content, must be a
751  *   pointer to memory cells already allocated (may be %NULL).
752  * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
753  *   holds the sizeof value.
754  * @etype: The type of the value read (ASN1_ETYPE)
755  *
756  * Returns the type and value of one element inside a structure. 
757  * If an element is OPTIONAL and this returns
758  * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
759  * in the der encoding that created the structure.  The first element
760  * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
761  * so on. If the @root provided is a node to specific sequence element,
762  * then the keyword "?CURRENT" is also acceptable and indicates the
763  * current sequence element of this node.
764  *
765  * Note that there can be valid values with length zero. In these case
766  * this function will succeed and @len will be zero.
767  *
768  *
769  * INTEGER: VALUE will contain a two's complement form integer.
770  *
771  *            integer=-1  -> value[0]=0xFF , len=1.
772  *            integer=1   -> value[0]=0x01 , len=1.
773  *
774  * ENUMERATED: As INTEGER (but only with not negative numbers).
775  *
776  * BOOLEAN: VALUE will be the null terminated string "TRUE" or
777  *   "FALSE" and LEN=5 or LEN=6.
778  *
779  * OBJECT IDENTIFIER: VALUE will be a null terminated string with
780  *   each number separated by a dot (i.e. "1.2.3.543.1").
781  *
782  *                      LEN = strlen(VALUE)+1
783  *
784  * UTCTime: VALUE will be a null terminated string in one of these
785  *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
786  *   LEN=strlen(VALUE)+1.
787  *
788  * GeneralizedTime: VALUE will be a null terminated string in the
789  *   same format used to set the value.
790  *
791  * OCTET STRING: VALUE will contain the octet string and LEN will be
792  *   the number of octets.
793  *
794  * GeneralString: VALUE will contain the generalstring and LEN will
795  *   be the number of octets.
796  *
797  * BIT STRING: VALUE will contain the bit string organized by bytes
798  *   and LEN will be the number of bits.
799  *
800  * CHOICE: If NAME indicates a choice type, VALUE will specify the
801  *   alternative selected.
802  *
803  * ANY: If NAME indicates an any type, VALUE will indicate the DER
804  *   encoding of the structure actually used.
805  *
806  * Returns: %ASN1_SUCCESS if value is returned,
807  *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
808  *   %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
809  *   selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
810  *   to store the result, and in this case @len will contain the number of
811  *   bytes needed.
812  **/
813 int
814 asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
815                       int *len, unsigned int *etype)
816 {
817   asn1_node node, p, p2;
818   int len2, len3, result;
819   int value_size = *len;
820   unsigned char *value = ivalue;
821   unsigned type;
822
823   node = asn1_find_node (root, name);
824   if (node == NULL)
825     return ASN1_ELEMENT_NOT_FOUND;
826
827   type = type_field (node->type);
828
829   if ((type != ASN1_ETYPE_NULL) &&
830       (type != ASN1_ETYPE_CHOICE) &&
831       !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
832       (node->value == NULL))
833     return ASN1_VALUE_NOT_FOUND;
834
835   if (etype)
836     *etype = type;
837   switch (type)
838     {
839     case ASN1_ETYPE_NULL:
840       PUT_STR_VALUE (value, value_size, "NULL");
841       break;
842     case ASN1_ETYPE_BOOLEAN:
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 (p->type & CONST_TRUE)
849             {
850               PUT_STR_VALUE (value, value_size, "TRUE");
851             }
852           else
853             {
854               PUT_STR_VALUE (value, value_size, "FALSE");
855             }
856         }
857       else if (node->value[0] == 'T')
858         {
859           PUT_STR_VALUE (value, value_size, "TRUE");
860         }
861       else
862         {
863           PUT_STR_VALUE (value, value_size, "FALSE");
864         }
865       break;
866     case ASN1_ETYPE_INTEGER:
867     case ASN1_ETYPE_ENUMERATED:
868       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
869         {
870           p = node->down;
871           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
872             p = p->right;
873           if ((isdigit (p->value[0])) || (p->value[0] == '-')
874               || (p->value[0] == '+'))
875             {
876               result = _asn1_convert_integer
877                   (p->value, value, value_size, len);
878               if (result != ASN1_SUCCESS)
879                 return result;
880             }
881           else
882             {                   /* is an identifier like v1 */
883               p2 = node->down;
884               while (p2)
885                 {
886                   if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
887                     {
888                       if (!_asn1_strcmp (p2->name, p->value))
889                         {
890                           result = _asn1_convert_integer
891                               (p2->value, value, value_size,
892                                len);
893                           if (result != ASN1_SUCCESS)
894                             return result;
895                           break;
896                         }
897                     }
898                   p2 = p2->right;
899                 }
900             }
901         }
902       else
903         {
904           len2 = -1;
905           result = asn1_get_octet_der
906               (node->value, node->value_len, &len2, value, value_size,
907                len);
908           if (result != ASN1_SUCCESS)
909             return result;
910         }
911       break;
912     case ASN1_ETYPE_OBJECT_ID:
913       if (node->type & CONST_ASSIGN)
914         {
915           *len = 0;
916           if (value)
917                 value[0] = 0;
918           p = node->down;
919           while (p)
920             {
921               if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
922                 {
923                   ADD_STR_VALUE (value, value_size, p->value);
924                   if (p->right)
925                     {
926                       ADD_STR_VALUE (value, value_size, ".");
927                     }
928                 }
929               p = p->right;
930             }
931           (*len)++;
932         }
933       else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
934         {
935           p = node->down;
936           while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
937             p = p->right;
938           PUT_STR_VALUE (value, value_size, p->value);
939         }
940       else
941         {
942           PUT_STR_VALUE (value, value_size, node->value);
943         }
944       break;
945     case ASN1_ETYPE_GENERALIZED_TIME:
946     case ASN1_ETYPE_UTC_TIME:
947       PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
948       break;
949     case ASN1_ETYPE_OCTET_STRING:
950     case ASN1_ETYPE_GENERALSTRING:
951     case ASN1_ETYPE_NUMERIC_STRING:
952     case ASN1_ETYPE_IA5_STRING:
953     case ASN1_ETYPE_TELETEX_STRING:
954     case ASN1_ETYPE_PRINTABLE_STRING:
955     case ASN1_ETYPE_UNIVERSAL_STRING:
956     case ASN1_ETYPE_BMP_STRING:
957     case ASN1_ETYPE_UTF8_STRING:
958     case ASN1_ETYPE_VISIBLE_STRING:
959       len2 = -1;
960       result = asn1_get_octet_der
961           (node->value, node->value_len, &len2, value, value_size,
962            len);
963       if (result != ASN1_SUCCESS)
964         return result;
965       break;
966     case ASN1_ETYPE_BIT_STRING:
967       len2 = -1;
968       result = asn1_get_bit_der
969           (node->value, node->value_len, &len2, value, value_size,
970            len);
971       if (result != ASN1_SUCCESS)
972         return result;
973       break;
974     case ASN1_ETYPE_CHOICE:
975       PUT_STR_VALUE (value, value_size, node->down->name);
976       break;
977     case ASN1_ETYPE_ANY:
978       len3 = -1;
979       len2 = asn1_get_length_der (node->value, node->value_len, &len3);
980       if (len2 < 0)
981         return ASN1_DER_ERROR;
982       PUT_VALUE (value, value_size, node->value + len3, len2);
983       break;
984     default:
985       return ASN1_ELEMENT_NOT_FOUND;
986       break;
987     }
988   return ASN1_SUCCESS;
989 }
990
991
992 /**
993  * asn1_read_tag:
994  * @root: pointer to a structure
995  * @name: the name of the element inside a structure.
996  * @tagValue:  variable that will contain the TAG value.
997  * @classValue: variable that will specify the TAG type.
998  *
999  * Returns the TAG and the CLASS of one element inside a structure.
1000  * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
1001  * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
1002  * %ASN1_CLASS_CONTEXT_SPECIFIC.
1003  *
1004  * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
1005  *   @name is not a valid element.
1006  **/
1007 int
1008 asn1_read_tag (asn1_node root, const char *name, int *tagValue,
1009                int *classValue)
1010 {
1011   asn1_node node, p, pTag;
1012
1013   node = asn1_find_node (root, name);
1014   if (node == NULL)
1015     return ASN1_ELEMENT_NOT_FOUND;
1016
1017   p = node->down;
1018
1019   /* pTag will points to the IMPLICIT TAG */
1020   pTag = NULL;
1021   if (node->type & CONST_TAG)
1022     {
1023       while (p)
1024         {
1025           if (type_field (p->type) == ASN1_ETYPE_TAG)
1026             {
1027               if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
1028                 pTag = p;
1029               else if (p->type & CONST_EXPLICIT)
1030                 pTag = NULL;
1031             }
1032           p = p->right;
1033         }
1034     }
1035
1036   if (pTag)
1037     {
1038       *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
1039
1040       if (pTag->type & CONST_APPLICATION)
1041         *classValue = ASN1_CLASS_APPLICATION;
1042       else if (pTag->type & CONST_UNIVERSAL)
1043         *classValue = ASN1_CLASS_UNIVERSAL;
1044       else if (pTag->type & CONST_PRIVATE)
1045         *classValue = ASN1_CLASS_PRIVATE;
1046       else
1047         *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
1048     }
1049   else
1050     {
1051       unsigned type = type_field (node->type);
1052       *classValue = ASN1_CLASS_UNIVERSAL;
1053
1054       switch (type)
1055         {
1056         CASE_HANDLED_ETYPES:
1057           *tagValue = _asn1_tags[type].tag;
1058           break;
1059         case ASN1_ETYPE_TAG:
1060         case ASN1_ETYPE_CHOICE:
1061         case ASN1_ETYPE_ANY:
1062           *tagValue = -1;
1063           break;
1064         default:
1065           break;
1066         }
1067     }
1068
1069   return ASN1_SUCCESS;
1070 }
1071
1072 /**
1073  * asn1_read_node_value:
1074  * @node: pointer to a node.
1075  * @data: a point to a asn1_data_node_st
1076  *
1077  * Returns the value a data node inside a asn1_node structure.
1078  * The data returned should be handled as constant values.
1079  *
1080  * Returns: %ASN1_SUCCESS if the node exists.
1081  **/
1082 int
1083 asn1_read_node_value (asn1_node node, asn1_data_node_st * data)
1084 {
1085   data->name = node->name;
1086   data->value = node->value;
1087   data->value_len = node->value_len;
1088   data->type = type_field (node->type);
1089
1090   return ASN1_SUCCESS;
1091 }