2 * Copyright (C) 2000-2014 Free Software Foundation, Inc.
4 * This file is part of LIBTASN1.
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.
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.
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
22 /*****************************************************/
24 /* Description: Functions with the read and write */
26 /*****************************************************/
30 #include "parser_aux.h"
32 #include "structure.h"
37 _asn1_hierarchical_name (asn1_node node, char *name, int name_size)
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);
55 p = _asn1_find_up (p);
59 _asn1_str_cpy (name, name_size, "ROOT");
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. */
70 /* value: null terminated string to convert. */
71 /* value_out: convertion result (memory must be already */
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 /******************************************************************/
78 _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
79 int value_out_size, int *len)
82 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
86 valtmp = _asn1_strtol (value, NULL, 10);
88 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
90 val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
98 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
100 if (negative && (val[k] != 0xFF))
102 else if (!negative && val[k])
106 if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
109 *len = SIZEOF_UNSIGNED_LONG_INT - k;
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;
115 if (value_out != NULL)
117 for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
118 value_out[k2 - k] = val[k2];
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]);
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.
135 * The last element in the list may be provided in @pcache, to avoid
136 * traversing the list, an expensive operation in long lists.
138 * On success it returns in @pcache the added element (which is the
139 * tail in the list of added elements).
142 _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
145 char temp[LTOSTR_MAX_SIZE];
148 if (!node || !(node->down))
149 return ASN1_GENERIC_ERROR;
152 while ((type_field (p->type) == ASN1_ETYPE_TAG)
153 || (type_field (p->type) == ASN1_ETYPE_SIZE))
156 p2 = _asn1_copy_structure3 (p);
158 return ASN1_GENERIC_ERROR;
160 if (pcache == NULL || pcache->tail == NULL || pcache->head != node)
172 _asn1_set_right (p, p2);
180 _asn1_str_cpy (temp, sizeof (temp), "?1");
183 n = strtol (p->name + 1, NULL, 0);
186 _asn1_ltostr (n, temp + 1);
188 _asn1_set_name (p2, temp);
189 /* p2->type |= CONST_OPTION; */
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
205 * Set the value of one element inside a structure.
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":
210 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
213 * Description for each type:
215 * INTEGER: VALUE must contain a two's complement form integer.
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.
223 * ENUMERATED: As INTEGER (but only with not negative numbers).
225 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
226 * "FALSE" and LEN != 0.
228 * value="TRUE" , len=1 -> boolean=TRUE.
229 * value="FALSE" , len=1 -> boolean=FALSE.
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.
234 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
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.
241 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
242 * at 12h 00m Greenwich Mean Time
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".
251 * value="2001010112001.12-0700" , len=1 -> time=Jannuary
252 * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
254 * OCTET STRING: VALUE contains the octet string and LEN is the
257 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
258 * len=3 -> three bytes octet string
260 * GeneralString: VALUE contains the generalstring and LEN is the
263 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
264 * len=3 -> three bytes generalstring
266 * BIT STRING: VALUE contains the bit string organized by bytes and
267 * LEN is the number of bits.
269 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
272 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
273 * the alternatives with a null terminated string. LEN != 0. Using
276 * result=asn1_write_value(cert,
277 * "certificate1.tbsCertificate.subject", "rdnSequence",
280 * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
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.
289 * result=asn1_write_value(cert,
290 * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
292 * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
294 * result=asn1_write_value(cert,
295 * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
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.
302 asn1_write_value (asn1_node node_root, const char *name,
303 const void *ivalue, int len)
305 asn1_node node, p, p2;
306 unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
307 int len2, k, k2, negative;
309 const unsigned char *value = ivalue;
312 node = asn1_find_node (node_root, name);
314 return ASN1_ELEMENT_NOT_FOUND;
316 if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
318 asn1_delete_structure (&node);
322 type = type_field (node->type);
324 if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0))
327 while ((type_field (p->type) == ASN1_ETYPE_TAG)
328 || (type_field (p->type) == ASN1_ETYPE_SIZE))
332 asn1_delete_structure (&p->right);
337 /* Don't allow element deletion for other types */
340 return ASN1_VALUE_NOT_VALID;
345 case ASN1_ETYPE_BOOLEAN:
346 if (!_asn1_strcmp (value, "TRUE"))
348 if (node->type & CONST_DEFAULT)
351 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
353 if (p->type & CONST_TRUE)
354 _asn1_set_value (node, NULL, 0);
356 _asn1_set_value (node, "T", 1);
359 _asn1_set_value (node, "T", 1);
361 else if (!_asn1_strcmp (value, "FALSE"))
363 if (node->type & CONST_DEFAULT)
366 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
368 if (p->type & CONST_FALSE)
369 _asn1_set_value (node, NULL, 0);
371 _asn1_set_value (node, "F", 1);
374 _asn1_set_value (node, "F", 1);
377 return ASN1_VALUE_NOT_VALID;
379 case ASN1_ETYPE_INTEGER:
380 case ASN1_ETYPE_ENUMERATED:
383 if ((isdigit (value[0])) || (value[0] == '-'))
385 value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
386 if (value_temp == NULL)
387 return ASN1_MEM_ALLOC_ERROR;
389 _asn1_convert_integer (value, value_temp,
390 SIZEOF_UNSIGNED_LONG_INT, &len);
393 { /* is an identifier like v1 */
394 if (!(node->type & CONST_LIST))
395 return ASN1_VALUE_NOT_VALID;
399 if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
401 if (!_asn1_strcmp (p->name, value))
403 value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
404 if (value_temp == NULL)
405 return ASN1_MEM_ALLOC_ERROR;
407 _asn1_convert_integer (p->value,
409 SIZEOF_UNSIGNED_LONG_INT,
417 return ASN1_VALUE_NOT_VALID;
422 value_temp = malloc (len);
423 if (value_temp == NULL)
424 return ASN1_MEM_ALLOC_ERROR;
425 memcpy (value_temp, value, len);
428 if (value_temp[0] & 0x80)
433 if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
436 return ASN1_VALUE_NOT_VALID;
439 for (k = 0; k < len - 1; k++)
440 if (negative && (value_temp[k] != 0xFF))
442 else if (!negative && value_temp[k])
445 if ((negative && !(value_temp[k] & 0x80)) ||
446 (!negative && (value_temp[k] & 0x80)))
449 _asn1_set_value_lv (node, value_temp + k, len - k);
451 if (node->type & CONST_DEFAULT)
454 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
456 if ((isdigit (p->value[0])) || (p->value[0] == '-'))
458 default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
459 if (default_temp == NULL)
462 return ASN1_MEM_ALLOC_ERROR;
465 _asn1_convert_integer (p->value, default_temp,
466 SIZEOF_UNSIGNED_LONG_INT, &len2);
469 { /* is an identifier like v1 */
470 if (!(node->type & CONST_LIST))
473 return ASN1_VALUE_NOT_VALID;
478 if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
480 if (!_asn1_strcmp (p2->name, p->value))
482 default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
483 if (default_temp == NULL)
486 return ASN1_MEM_ALLOC_ERROR;
489 _asn1_convert_integer (p2->value,
491 SIZEOF_UNSIGNED_LONG_INT,
501 return ASN1_VALUE_NOT_VALID;
506 if ((len - k) == len2)
508 for (k2 = 0; k2 < len2; k2++)
509 if (value_temp[k + k2] != default_temp[k2])
514 _asn1_set_value (node, NULL, 0);
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)
527 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
529 if (!_asn1_strcmp (value, p->value))
531 _asn1_set_value (node, NULL, 0);
535 _asn1_set_value (node, value, _asn1_strlen (value) + 1);
537 case ASN1_ETYPE_UTC_TIME:
539 len = _asn1_strlen (value);
541 return ASN1_VALUE_NOT_VALID;
542 for (k = 0; k < 10; k++)
543 if (!isdigit (value[k]))
544 return ASN1_VALUE_NOT_VALID;
548 if (value[10] != 'Z')
549 return ASN1_VALUE_NOT_VALID;
552 if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
554 return ASN1_VALUE_NOT_VALID;
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;
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;
573 return ASN1_VALUE_NOT_FOUND;
575 _asn1_set_value (node, value, len);
578 case ASN1_ETYPE_GENERALIZED_TIME:
579 len = _asn1_strlen (value);
580 _asn1_set_value (node, value, len);
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:
593 len = _asn1_strlen (value);
594 _asn1_set_value_lv (node, value, len);
596 case ASN1_ETYPE_BIT_STRING:
598 len = _asn1_strlen (value);
599 asn1_length_der ((len >> 3) + 2, NULL, &len2);
600 temp = malloc ((len >> 3) + 2 + len2);
602 return ASN1_MEM_ALLOC_ERROR;
604 asn1_bit_der (value, len, temp, &len2);
605 _asn1_set_value_m (node, temp, len2);
608 case ASN1_ETYPE_CHOICE:
612 if (!_asn1_strcmp (p->name, value))
619 asn1_delete_structure (&p2);
630 return ASN1_ELEMENT_NOT_FOUND;
633 _asn1_set_value_lv (node, value, len);
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);
642 return ASN1_ELEMENT_NOT_FOUND;
650 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
652 if (ptr_size < data_size) { \
653 return ASN1_MEM_ERROR; \
655 if (ptr && data_size > 0) \
656 memcpy (ptr, data, data_size); \
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; \
664 /* this strcpy is checked */ \
666 _asn1_strcpy (ptr, data); \
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; \
675 /* this strcpy is checked */ \
678 memcpy (ptr, data, data_size); \
679 ptr[data_size] = 0; \
683 #define ADD_STR_VALUE( ptr, ptr_size, data) \
684 *len += _asn1_strlen(data); \
685 if (ptr_size < (int) *len) { \
687 return ASN1_MEM_ERROR; \
689 /* this strcat is checked */ \
690 if (ptr) _asn1_strcat (ptr, data); \
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.
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.
711 * Note that there can be valid values with length zero. In these case
712 * this function will succeed and @len will be zero.
714 * INTEGER: VALUE will contain a two's complement form integer.
716 * integer=-1 -> value[0]=0xFF , len=1.
717 * integer=1 -> value[0]=0x01 , len=1.
719 * ENUMERATED: As INTEGER (but only with not negative numbers).
721 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
722 * "FALSE" and LEN=5 or LEN=6.
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").
727 * LEN = strlen(VALUE)+1
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.
733 * GeneralizedTime: VALUE will be a null terminated string in the
734 * same format used to set the value.
736 * OCTET STRING: VALUE will contain the octet string and LEN will be
737 * the number of octets.
739 * GeneralString: VALUE will contain the generalstring and LEN will
740 * be the number of octets.
742 * BIT STRING: VALUE will contain the bit string organized by bytes
743 * and LEN will be the number of bits.
745 * CHOICE: If NAME indicates a choice type, VALUE will specify the
746 * alternative selected.
748 * ANY: If NAME indicates an any type, VALUE will indicate the DER
749 * encoding of the structure actually used.
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
759 asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
761 return asn1_read_value_type (root, name, ivalue, len, NULL);
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)
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.
783 * Note that there can be valid values with length zero. In these case
784 * this function will succeed and @len will be zero.
787 * INTEGER: VALUE will contain a two's complement form integer.
789 * integer=-1 -> value[0]=0xFF , len=1.
790 * integer=1 -> value[0]=0x01 , len=1.
792 * ENUMERATED: As INTEGER (but only with not negative numbers).
794 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
795 * "FALSE" and LEN=5 or LEN=6.
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").
800 * LEN = strlen(VALUE)+1
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.
806 * GeneralizedTime: VALUE will be a null terminated string in the
807 * same format used to set the value.
809 * OCTET STRING: VALUE will contain the octet string and LEN will be
810 * the number of octets.
812 * GeneralString: VALUE will contain the generalstring and LEN will
813 * be the number of octets.
815 * BIT STRING: VALUE will contain the bit string organized by bytes
816 * and LEN will be the number of bits.
818 * CHOICE: If NAME indicates a choice type, VALUE will specify the
819 * alternative selected.
821 * ANY: If NAME indicates an any type, VALUE will indicate the DER
822 * encoding of the structure actually used.
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
832 asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
833 int *len, unsigned int *etype)
835 asn1_node node, p, p2;
836 int len2, len3, result;
837 int value_size = *len;
838 unsigned char *value = ivalue;
841 node = asn1_find_node (root, name);
843 return ASN1_ELEMENT_NOT_FOUND;
845 type = type_field (node->type);
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;
857 case ASN1_ETYPE_NULL:
858 PUT_STR_VALUE (value, value_size, "NULL");
860 case ASN1_ETYPE_BOOLEAN:
861 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
864 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
866 if (p->type & CONST_TRUE)
868 PUT_STR_VALUE (value, value_size, "TRUE");
872 PUT_STR_VALUE (value, value_size, "FALSE");
875 else if (node->value[0] == 'T')
877 PUT_STR_VALUE (value, value_size, "TRUE");
881 PUT_STR_VALUE (value, value_size, "FALSE");
884 case ASN1_ETYPE_INTEGER:
885 case ASN1_ETYPE_ENUMERATED:
886 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
889 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
891 if ((isdigit (p->value[0])) || (p->value[0] == '-')
892 || (p->value[0] == '+'))
894 result = _asn1_convert_integer
895 (p->value, value, value_size, len);
896 if (result != ASN1_SUCCESS)
900 { /* is an identifier like v1 */
904 if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
906 if (!_asn1_strcmp (p2->name, p->value))
908 result = _asn1_convert_integer
909 (p2->value, value, value_size,
911 if (result != ASN1_SUCCESS)
923 result = asn1_get_octet_der
924 (node->value, node->value_len, &len2, value, value_size,
926 if (result != ASN1_SUCCESS)
930 case ASN1_ETYPE_OBJECT_ID:
931 if (node->type & CONST_ASSIGN)
939 if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
941 ADD_STR_VALUE (value, value_size, p->value);
944 ADD_STR_VALUE (value, value_size, ".");
951 else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
954 while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
956 PUT_STR_VALUE (value, value_size, p->value);
960 PUT_STR_VALUE (value, value_size, node->value);
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);
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:
978 result = asn1_get_octet_der
979 (node->value, node->value_len, &len2, value, value_size,
981 if (result != ASN1_SUCCESS)
984 case ASN1_ETYPE_BIT_STRING:
986 result = asn1_get_bit_der
987 (node->value, node->value_len, &len2, value, value_size,
989 if (result != ASN1_SUCCESS)
992 case ASN1_ETYPE_CHOICE:
993 PUT_STR_VALUE (value, value_size, node->down->name);
997 len2 = asn1_get_length_der (node->value, node->value_len, &len3);
999 return ASN1_DER_ERROR;
1000 PUT_VALUE (value, value_size, node->value + len3, len2);
1003 return ASN1_ELEMENT_NOT_FOUND;
1006 return ASN1_SUCCESS;
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.
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.
1022 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
1023 * @name is not a valid element.
1026 asn1_read_tag (asn1_node root, const char *name, int *tagValue,
1029 asn1_node node, p, pTag;
1031 node = asn1_find_node (root, name);
1033 return ASN1_ELEMENT_NOT_FOUND;
1037 /* pTag will points to the IMPLICIT TAG */
1039 if (node->type & CONST_TAG)
1043 if (type_field (p->type) == ASN1_ETYPE_TAG)
1045 if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
1047 else if (p->type & CONST_EXPLICIT)
1056 *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
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;
1065 *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
1069 unsigned type = type_field (node->type);
1070 *classValue = ASN1_CLASS_UNIVERSAL;
1074 CASE_HANDLED_ETYPES:
1075 *tagValue = _asn1_tags[type].tag;
1077 case ASN1_ETYPE_TAG:
1078 case ASN1_ETYPE_CHOICE:
1079 case ASN1_ETYPE_ANY:
1087 return ASN1_SUCCESS;
1091 * asn1_read_node_value:
1092 * @node: pointer to a node.
1093 * @data: a point to a asn1_data_node_st
1095 * Returns the value a data node inside a asn1_node structure.
1096 * The data returned should be handled as constant values.
1098 * Returns: %ASN1_SUCCESS if the node exists.
1101 asn1_read_node_value (asn1_node node, asn1_data_node_st * data)
1103 data->name = node->name;
1104 data->value = node->value;
1105 data->value_len = node->value_len;
1106 data->type = type_field (node->type);
1108 return ASN1_SUCCESS;