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