2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010
3 * Free Software Foundation, Inc.
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 /*****************************************************/
25 /* Description: Functions with the read and write */
27 /*****************************************************/
31 #include "parser_aux.h"
33 #include "structure.h"
38 _asn1_hierarchical_name (ASN1_TYPE node, char *name, int name_size)
51 _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
52 _asn1_str_cpy (name, name_size, p->name);
53 _asn1_str_cat (name, name_size, ".");
54 _asn1_str_cat (name, name_size, tmp_name);
56 p = _asn1_find_up (p);
60 _asn1_str_cpy (name, name_size, "ROOT");
64 /******************************************************************/
65 /* Function : _asn1_convert_integer */
66 /* Description: converts an integer from a null terminated string */
67 /* to der decoding. The convertion from a null */
68 /* terminated string to an integer is made with */
69 /* the 'strtol' function. */
71 /* value: null terminated string to convert. */
72 /* value_out: convertion result (memory must be already */
74 /* value_out_size: number of bytes of value_out. */
75 /* len: number of significant byte of value_out. */
76 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
77 /******************************************************************/
79 _asn1_convert_integer (const char *value, unsigned char *value_out,
80 int value_out_size, int *len)
83 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
87 valtmp = strtol (value, NULL, 10);
89 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
91 val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
99 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
101 if (negative && (val[k] != 0xFF))
103 else if (!negative && val[k])
107 if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
110 *len = SIZEOF_UNSIGNED_LONG_INT - k;
112 if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
113 /* VALUE_OUT is too short to contain the value conversion */
114 return ASN1_MEM_ERROR;
116 for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
117 value_out[k2 - k] = val[k2];
120 printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
121 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
122 printf (", vOut[%d]=%d", k, value_out[k]);
131 _asn1_append_sequence_set (ASN1_TYPE node)
137 if (!node || !(node->down))
138 return ASN1_GENERIC_ERROR;
141 while ((type_field (p->type) == TYPE_TAG)
142 || (type_field (p->type) == TYPE_SIZE))
144 p2 = _asn1_copy_structure3 (p);
147 _asn1_set_right (p, p2);
150 _asn1_str_cpy (temp, sizeof (temp), "?1");
153 n = strtol (p->name + 1, NULL, 0);
156 _asn1_ltostr (n, temp + 1);
158 _asn1_set_name (p2, temp);
159 /* p2->type |= CONST_OPTION; */
167 * @node_root: pointer to a structure
168 * @name: the name of the element inside the structure that you want to set.
169 * @ivalue: vector used to specify the value to set. If len is >0,
170 * VALUE must be a two's complement form integer. if len=0 *VALUE
171 * must be a null terminated string with an integer value.
172 * @len: number of bytes of *value to use to set the value:
173 * value[0]..value[len-1] or 0 if value is a null terminated string
175 * Set the value of one element inside a structure.
177 * If an element is OPTIONAL and you want to delete it, you must use
178 * the value=NULL and len=0. Using "pkix.asn":
180 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
183 * Description for each type:
185 * INTEGER: VALUE must contain a two's complement form integer.
187 * value[0]=0xFF , len=1 -> integer=-1.
188 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
189 * value[0]=0x01 , len=1 -> integer= 1.
190 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
191 * value="123" , len=0 -> integer= 123.
193 * ENUMERATED: As INTEGER (but only with not negative numbers).
195 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
196 * "FALSE" and LEN != 0.
198 * value="TRUE" , len=1 -> boolean=TRUE.
199 * value="FALSE" , len=1 -> boolean=FALSE.
201 * OBJECT IDENTIFIER: VALUE must be a null terminated string with
202 * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
204 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
206 * UTCTime: VALUE must be a null terminated string in one of these
207 * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
208 * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
209 * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
211 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
212 * at 12h 00m Greenwich Mean Time
214 * GeneralizedTime: VALUE must be in one of this format:
215 * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
216 * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
217 * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
218 * indicates the seconds with any precision like "10.1" or "01.02".
221 * value="2001010112001.12-0700" , len=1 -> time=Jannuary
222 * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
224 * OCTET STRING: VALUE contains the octet string and LEN is the
227 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
228 * len=3 -> three bytes octet string
230 * GeneralString: VALUE contains the generalstring and LEN is the
233 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
234 * len=3 -> three bytes generalstring
236 * BIT STRING: VALUE contains the bit string organized by bytes and
237 * LEN is the number of bits.
239 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
242 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
243 * the alternatives with a null terminated string. LEN != 0. Using
246 * result=asn1_write_value(cert,
247 * "certificate1.tbsCertificate.subject", "rdnSequence",
250 * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
252 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
253 * LEN != 0. With this instruction another element is appended in
254 * the sequence. The name of this element will be "?1" if it's the
255 * first one, "?2" for the second and so on.
259 * result=asn1_write_value(cert,
260 * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
262 * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
264 * result=asn1_write_value(cert,
265 * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
267 * Returns: %ASN1_SUCCESS if the value was set,
268 * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
269 * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
272 asn1_write_value (ASN1_TYPE node_root, const char *name,
273 const void *ivalue, int len)
275 ASN1_TYPE node, p, p2;
276 unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
277 int len2, k, k2, negative;
279 const unsigned char *value = ivalue;
281 node = asn1_find_node (node_root, name);
283 return ASN1_ELEMENT_NOT_FOUND;
285 if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
287 asn1_delete_structure (&node);
291 if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
295 while ((type_field (p->type) == TYPE_TAG)
296 || (type_field (p->type) == TYPE_SIZE))
300 asn1_delete_structure (&p->right);
305 switch (type_field (node->type))
308 if (!strcmp (value, "TRUE"))
310 if (node->type & CONST_DEFAULT)
313 while (type_field (p->type) != TYPE_DEFAULT)
315 if (p->type & CONST_TRUE)
316 _asn1_set_value (node, NULL, 0);
318 _asn1_set_value (node, "T", 1);
321 _asn1_set_value (node, "T", 1);
323 else if (!strcmp (value, "FALSE"))
325 if (node->type & CONST_DEFAULT)
328 while (type_field (p->type) != TYPE_DEFAULT)
330 if (p->type & CONST_FALSE)
331 _asn1_set_value (node, NULL, 0);
333 _asn1_set_value (node, "F", 1);
336 _asn1_set_value (node, "F", 1);
339 return ASN1_VALUE_NOT_VALID;
342 case TYPE_ENUMERATED:
345 if ((isdigit (value[0])) || (value[0] == '-'))
348 (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
349 if (value_temp == NULL)
350 return ASN1_MEM_ALLOC_ERROR;
352 _asn1_convert_integer (value, value_temp,
353 SIZEOF_UNSIGNED_LONG_INT, &len);
356 { /* is an identifier like v1 */
357 if (!(node->type & CONST_LIST))
358 return ASN1_VALUE_NOT_VALID;
362 if (type_field (p->type) == TYPE_CONSTANT)
364 if ((p->name) && (!strcmp (p->name, value)))
368 _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
369 if (value_temp == NULL)
370 return ASN1_MEM_ALLOC_ERROR;
372 _asn1_convert_integer (p->value,
374 SIZEOF_UNSIGNED_LONG_INT,
382 return ASN1_VALUE_NOT_VALID;
387 value_temp = (unsigned char *) _asn1_malloc (len);
388 if (value_temp == NULL)
389 return ASN1_MEM_ALLOC_ERROR;
390 memcpy (value_temp, value, len);
394 if (value_temp[0] & 0x80)
399 if (negative && (type_field (node->type) == TYPE_ENUMERATED))
401 _asn1_free (value_temp);
402 return ASN1_VALUE_NOT_VALID;
405 for (k = 0; k < len - 1; k++)
406 if (negative && (value_temp[k] != 0xFF))
408 else if (!negative && value_temp[k])
411 if ((negative && !(value_temp[k] & 0x80)) ||
412 (!negative && (value_temp[k] & 0x80)))
415 _asn1_set_value_octet (node, value_temp + k, len - k);
417 if (node->type & CONST_DEFAULT)
420 while (type_field (p->type) != TYPE_DEFAULT)
422 if ((isdigit (p->value[0])) || (p->value[0] == '-'))
425 (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
426 if (default_temp == NULL)
428 _asn1_free (value_temp);
429 return ASN1_MEM_ALLOC_ERROR;
432 _asn1_convert_integer (p->value, default_temp,
433 SIZEOF_UNSIGNED_LONG_INT, &len2);
436 { /* is an identifier like v1 */
437 if (!(node->type & CONST_LIST))
439 _asn1_free (value_temp);
440 return ASN1_VALUE_NOT_VALID;
445 if (type_field (p2->type) == TYPE_CONSTANT)
447 if ((p2->name) && (!strcmp (p2->name, p->value)))
451 _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
452 if (default_temp == NULL)
454 _asn1_free (value_temp);
455 return ASN1_MEM_ALLOC_ERROR;
458 _asn1_convert_integer (p2->value,
460 SIZEOF_UNSIGNED_LONG_INT,
469 _asn1_free (value_temp);
470 return ASN1_VALUE_NOT_VALID;
475 if ((len - k) == len2)
477 for (k2 = 0; k2 < len2; k2++)
478 if (value_temp[k + k2] != default_temp[k2])
483 _asn1_set_value (node, NULL, 0);
485 _asn1_free (default_temp);
487 _asn1_free (value_temp);
490 for (i = 0; i < strlen (value); i++)
491 if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
492 return ASN1_VALUE_NOT_VALID;
493 if (node->type & CONST_DEFAULT)
496 while (type_field (p->type) != TYPE_DEFAULT)
498 if (!strcmp (value, p->value))
500 _asn1_set_value (node, NULL, 0);
504 _asn1_set_value (node, value, strlen (value) + 1);
507 if (node->type & CONST_UTC)
509 if (strlen (value) < 11)
510 return ASN1_VALUE_NOT_VALID;
511 for (k = 0; k < 10; k++)
512 if (!isdigit (value[k]))
513 return ASN1_VALUE_NOT_VALID;
514 switch (strlen (value))
517 if (value[10] != 'Z')
518 return ASN1_VALUE_NOT_VALID;
521 if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
523 return ASN1_VALUE_NOT_VALID;
526 if ((value[10] != '+') && (value[10] != '-'))
527 return ASN1_VALUE_NOT_VALID;
528 for (k = 11; k < 15; k++)
529 if (!isdigit (value[k]))
530 return ASN1_VALUE_NOT_VALID;
533 if ((!isdigit (value[10])) || (!isdigit (value[11])))
534 return ASN1_VALUE_NOT_VALID;
535 if ((value[12] != '+') && (value[12] != '-'))
536 return ASN1_VALUE_NOT_VALID;
537 for (k = 13; k < 17; k++)
538 if (!isdigit (value[k]))
539 return ASN1_VALUE_NOT_VALID;
542 return ASN1_VALUE_NOT_FOUND;
544 _asn1_set_value (node, value, strlen (value) + 1);
547 { /* GENERALIZED TIME */
549 _asn1_set_value (node, value, strlen (value) + 1);
552 case TYPE_OCTET_STRING:
554 len = strlen (value);
555 _asn1_set_value_octet (node, value, len);
557 case TYPE_GENERALSTRING:
559 len = strlen (value);
560 _asn1_set_value_octet (node, value, len);
562 case TYPE_BIT_STRING:
564 len = strlen (value);
565 asn1_length_der ((len >> 3) + 2, NULL, &len2);
566 temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
568 return ASN1_MEM_ALLOC_ERROR;
570 asn1_bit_der (value, len, temp, &len2);
571 _asn1_set_value_m (node, temp, len2);
578 if (!strcmp (p->name, value))
585 asn1_delete_structure (&p2);
596 return ASN1_ELEMENT_NOT_FOUND;
599 _asn1_set_value_octet (node, value, len);
601 case TYPE_SEQUENCE_OF:
603 if (strcmp (value, "NEW"))
604 return ASN1_VALUE_NOT_VALID;
605 _asn1_append_sequence_set (node);
608 return ASN1_ELEMENT_NOT_FOUND;
616 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
618 if (ptr_size < data_size) { \
619 return ASN1_MEM_ERROR; \
621 memcpy( ptr, data, data_size); \
624 #define PUT_STR_VALUE( ptr, ptr_size, data) \
625 *len = strlen(data) + 1; \
626 if (ptr_size < *len) { \
627 return ASN1_MEM_ERROR; \
629 /* this strcpy is checked */ \
633 #define ADD_STR_VALUE( ptr, ptr_size, data) \
634 *len = (int) strlen(data) + 1; \
635 if (ptr_size < (int) strlen(ptr)+(*len)) { \
636 return ASN1_MEM_ERROR; \
638 /* this strcat is checked */ \
644 * @root: pointer to a structure.
645 * @name: the name of the element inside a structure that you want to read.
646 * @ivalue: vector that will contain the element's content, must be a
647 * pointer to memory cells already allocated.
648 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
649 * holds the sizeof value.
651 * Returns the value of one element inside a structure.
653 * If an element is OPTIONAL and the function "read_value" returns
654 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
655 * in the der encoding that created the structure. The first element
656 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
659 * INTEGER: VALUE will contain a two's complement form integer.
661 * integer=-1 -> value[0]=0xFF , len=1.
662 * integer=1 -> value[0]=0x01 , len=1.
664 * ENUMERATED: As INTEGER (but only with not negative numbers).
666 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
667 * "FALSE" and LEN=5 or LEN=6.
669 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
670 * each number separated by a dot (i.e. "1.2.3.543.1").
672 * LEN = strlen(VALUE)+1
674 * UTCTime: VALUE will be a null terminated string in one of these
675 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
676 * LEN=strlen(VALUE)+1.
678 * GeneralizedTime: VALUE will be a null terminated string in the
679 * same format used to set the value.
681 * OCTET STRING: VALUE will contain the octet string and LEN will be
682 * the number of octets.
684 * GeneralString: VALUE will contain the generalstring and LEN will
685 * be the number of octets.
687 * BIT STRING: VALUE will contain the bit string organized by bytes
688 * and LEN will be the number of bits.
690 * CHOICE: If NAME indicates a choice type, VALUE will specify the
691 * alternative selected.
693 * ANY: If NAME indicates an any type, VALUE will indicate the DER
694 * encoding of the structure actually used.
696 * Returns: %ASN1_SUCCESS if value is returned,
697 * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
698 * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
699 * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
700 * to store the result, and in this case @len will contain the number of
704 asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
706 ASN1_TYPE node, p, p2;
708 int value_size = *len;
709 unsigned char *value = ivalue;
711 node = asn1_find_node (root, name);
713 return ASN1_ELEMENT_NOT_FOUND;
715 if ((type_field (node->type) != TYPE_NULL) &&
716 (type_field (node->type) != TYPE_CHOICE) &&
717 !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
718 (node->value == NULL))
719 return ASN1_VALUE_NOT_FOUND;
721 switch (type_field (node->type))
724 PUT_STR_VALUE (value, value_size, "NULL");
727 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
730 while (type_field (p->type) != TYPE_DEFAULT)
732 if (p->type & CONST_TRUE)
734 PUT_STR_VALUE (value, value_size, "TRUE");
738 PUT_STR_VALUE (value, value_size, "FALSE");
741 else if (node->value[0] == 'T')
743 PUT_STR_VALUE (value, value_size, "TRUE");
747 PUT_STR_VALUE (value, value_size, "FALSE");
751 case TYPE_ENUMERATED:
752 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
755 while (type_field (p->type) != TYPE_DEFAULT)
757 if ((isdigit (p->value[0])) || (p->value[0] == '-')
758 || (p->value[0] == '+'))
760 if (_asn1_convert_integer
761 (p->value, value, value_size, len) != ASN1_SUCCESS)
762 return ASN1_MEM_ERROR;
765 { /* is an identifier like v1 */
769 if (type_field (p2->type) == TYPE_CONSTANT)
771 if ((p2->name) && (!strcmp (p2->name, p->value)))
773 if (_asn1_convert_integer
774 (p2->value, value, value_size,
775 len) != ASN1_SUCCESS)
776 return ASN1_MEM_ERROR;
787 if (asn1_get_octet_der
788 (node->value, node->value_len, &len2, value, value_size,
789 len) != ASN1_SUCCESS)
790 return ASN1_MEM_ERROR;
794 if (node->type & CONST_ASSIGN)
800 if (type_field (p->type) == TYPE_CONSTANT)
802 ADD_STR_VALUE (value, value_size, p->value);
805 ADD_STR_VALUE (value, value_size, ".");
810 *len = strlen (value) + 1;
812 else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
815 while (type_field (p->type) != TYPE_DEFAULT)
817 PUT_STR_VALUE (value, value_size, p->value);
821 PUT_STR_VALUE (value, value_size, node->value);
825 PUT_STR_VALUE (value, value_size, node->value);
827 case TYPE_OCTET_STRING:
829 if (asn1_get_octet_der
830 (node->value, node->value_len, &len2, value, value_size,
831 len) != ASN1_SUCCESS)
832 return ASN1_MEM_ERROR;
834 case TYPE_GENERALSTRING:
836 if (asn1_get_octet_der
837 (node->value, node->value_len, &len2, value, value_size,
838 len) != ASN1_SUCCESS)
839 return ASN1_MEM_ERROR;
841 case TYPE_BIT_STRING:
844 (node->value, node->value_len, &len2, value, value_size,
845 len) != ASN1_SUCCESS)
846 return ASN1_MEM_ERROR;
849 PUT_STR_VALUE (value, value_size, node->down->name);
853 len2 = asn1_get_length_der (node->value, node->value_len, &len3);
855 return ASN1_DER_ERROR;
856 PUT_VALUE (value, value_size, node->value + len3, len2);
859 return ASN1_ELEMENT_NOT_FOUND;
868 * @root: pointer to a structure
869 * @name: the name of the element inside a structure.
870 * @tagValue: variable that will contain the TAG value.
871 * @classValue: variable that will specify the TAG type.
873 * Returns the TAG and the CLASS of one element inside a structure.
874 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
875 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
876 * %ASN1_CLASS_CONTEXT_SPECIFIC.
878 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
879 * @name is not a valid element.
882 asn1_read_tag (ASN1_TYPE root, const char *name, int *tagValue,
885 ASN1_TYPE node, p, pTag;
887 node = asn1_find_node (root, name);
889 return ASN1_ELEMENT_NOT_FOUND;
893 /* pTag will points to the IMPLICIT TAG */
895 if (node->type & CONST_TAG)
899 if (type_field (p->type) == TYPE_TAG)
901 if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
903 else if (p->type & CONST_EXPLICIT)
912 *tagValue = strtoul (pTag->value, NULL, 10);
914 if (pTag->type & CONST_APPLICATION)
915 *classValue = ASN1_CLASS_APPLICATION;
916 else if (pTag->type & CONST_UNIVERSAL)
917 *classValue = ASN1_CLASS_UNIVERSAL;
918 else if (pTag->type & CONST_PRIVATE)
919 *classValue = ASN1_CLASS_PRIVATE;
921 *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
925 *classValue = ASN1_CLASS_UNIVERSAL;
927 switch (type_field (node->type))
930 *tagValue = ASN1_TAG_NULL;
933 *tagValue = ASN1_TAG_BOOLEAN;
936 *tagValue = ASN1_TAG_INTEGER;
938 case TYPE_ENUMERATED:
939 *tagValue = ASN1_TAG_ENUMERATED;
942 *tagValue = ASN1_TAG_OBJECT_ID;
945 if (node->type & CONST_UTC)
947 *tagValue = ASN1_TAG_UTCTime;
950 *tagValue = ASN1_TAG_GENERALIZEDTime;
952 case TYPE_OCTET_STRING:
953 *tagValue = ASN1_TAG_OCTET_STRING;
955 case TYPE_GENERALSTRING:
956 *tagValue = ASN1_TAG_GENERALSTRING;
958 case TYPE_BIT_STRING:
959 *tagValue = ASN1_TAG_BIT_STRING;
962 case TYPE_SEQUENCE_OF:
963 *tagValue = ASN1_TAG_SEQUENCE;
967 *tagValue = ASN1_TAG_SET;