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