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