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