2 * Copyright (C) 2002-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
23 /*****************************************************/
24 /* File: structure.c */
25 /* Description: Functions to create and delete an */
27 /*****************************************************/
31 #include <structure.h>
32 #include "parser_aux.h"
36 extern char _asn1_identifierMissing[];
39 /******************************************************/
40 /* Function : _asn1_add_single_node */
41 /* Description: creates a new NODE_ASN element. */
43 /* type: type of the new element (see ASN1_ETYPE_ */
44 /* and CONST_ constants). */
45 /* Return: pointer to the new element. */
46 /******************************************************/
48 _asn1_add_single_node (unsigned int type)
52 punt = calloc (1, sizeof (struct asn1_node_st));
62 /******************************************************************/
63 /* Function : _asn1_find_left */
64 /* Description: returns the NODE_ASN element with RIGHT field that*/
65 /* points the element NODE. */
67 /* node: NODE_ASN element pointer. */
68 /* Return: NULL if not found. */
69 /******************************************************************/
71 _asn1_find_left (asn1_node node)
73 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
81 _asn1_create_static_structure (asn1_node pointer, char *output_file_name,
88 file = fopen (output_file_name, "w");
91 return ASN1_FILE_NOT_FOUND;
93 fprintf (file, "#if HAVE_CONFIG_H\n");
94 fprintf (file, "# include \"config.h\"\n");
95 fprintf (file, "#endif\n\n");
97 fprintf (file, "#include <libtasn1.h>\n\n");
99 fprintf (file, "const asn1_static_node %s[] = {\n", vector_name);
105 fprintf (file, " { ");
108 fprintf (file, "\"%s\", ", p->name);
110 fprintf (file, "NULL, ");
118 fprintf (file, "%lu, ", t);
121 fprintf (file, "\"%s\"},\n", p->value);
123 fprintf (file, "NULL },\n");
137 p = _asn1_find_up (p);
152 fprintf (file, " { NULL, 0, NULL }\n};\n");
162 * @array: specify the array that contains ASN.1 declarations
163 * @definitions: return the pointer to the structure created by
164 * *ARRAY ASN.1 declarations
165 * @errorDescription: return the error description.
167 * Creates the structures needed to manage the ASN.1 definitions.
168 * @array is a vector created by asn1_parser2array().
170 * Returns: %ASN1_SUCCESS if structure was created correctly,
171 * %ASN1_ELEMENT_NOT_EMPTY if *@definitions not NULL,
172 * %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier
173 * that is not defined (see @errorDescription for more information),
174 * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong.
177 asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
178 char *errorDescription)
180 asn1_node p, p_last = NULL;
186 if (errorDescription)
187 errorDescription[0] = 0;
189 if (*definitions != NULL)
190 return ASN1_ELEMENT_NOT_EMPTY;
195 while (array[k].value || array[k].type || array[k].name)
197 type = convert_old_type (array[k].type);
199 p = _asn1_add_static_node (type & (~CONST_DOWN));
201 _asn1_set_name (p, array[k].name);
203 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
205 if (*definitions == NULL)
209 _asn1_set_down (p_last, p);
210 else if (move == RIGHT)
211 _asn1_set_right (p_last, p);
215 if (type & CONST_DOWN)
217 else if (type & CONST_RIGHT)
223 if (p_last == *definitions)
226 p_last = _asn1_find_up (p_last);
231 if (p_last->type & CONST_RIGHT)
233 p_last->type &= ~CONST_RIGHT;
242 if (p_last == *definitions)
244 result = _asn1_check_identifier (*definitions);
245 if (result == ASN1_SUCCESS)
247 _asn1_change_integer_value (*definitions);
248 _asn1_expand_object_id (*definitions);
253 result = ASN1_ARRAY_ERROR;
256 if (errorDescription != NULL)
258 if (result == ASN1_IDENTIFIER_NOT_FOUND)
260 Estrcpy (errorDescription, ":: identifier '");
261 Estrcat (errorDescription, _asn1_identifierMissing);
262 Estrcat (errorDescription, "' not found");
265 errorDescription[0] = 0;
268 if (result != ASN1_SUCCESS)
270 _asn1_delete_list_and_nodes ();
274 _asn1_delete_list ();
280 * asn1_delete_structure:
281 * @structure: pointer to the structure that you want to delete.
283 * Deletes the structure *@structure. At the end, *@structure is set
286 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
287 * *@structure was NULL.
290 asn1_delete_structure (asn1_node * structure)
292 return asn1_delete_structure2(structure, 0);
296 * asn1_delete_structure2:
297 * @structure: pointer to the structure that you want to delete.
298 * @flags: additional flags (see %ASN1_DELETE_FLAG)
300 * Deletes the structure *@structure. At the end, *@structure is set
303 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
304 * *@structure was NULL.
307 asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
311 if (*structure == NULL)
312 return ASN1_ELEMENT_NOT_FOUND;
326 p3 = _asn1_find_up (p);
327 _asn1_set_down (p3, p2);
328 _asn1_remove_node (p, flags);
333 p3 = _asn1_find_left (p);
336 p3 = _asn1_find_up (p);
338 _asn1_set_down (p3, p2);
342 p->right->left = NULL;
346 _asn1_set_right (p3, p2);
347 _asn1_remove_node (p, flags);
360 * asn1_delete_element:
361 * @structure: pointer to the structure that contains the element you
363 * @element_name: element's name you want to delete.
365 * Deletes the element named *@element_name inside *@structure.
367 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
368 * the @element_name was not found.
371 asn1_delete_element (asn1_node structure, const char *element_name)
373 asn1_node p2, p3, source_node;
375 source_node = asn1_find_node (structure, element_name);
377 if (source_node == NULL)
378 return ASN1_ELEMENT_NOT_FOUND;
380 p2 = source_node->right;
381 p3 = _asn1_find_left (source_node);
384 p3 = _asn1_find_up (source_node);
386 _asn1_set_down (p3, p2);
387 else if (source_node->right)
388 source_node->right->left = NULL;
391 _asn1_set_right (p3, p2);
393 return asn1_delete_structure (&source_node);
397 _asn1_copy_structure3 (asn1_node source_node)
399 asn1_node dest_node, p_s, p_d, p_d_prev;
402 if (source_node == NULL)
405 dest_node = _asn1_add_single_node (source_node->type);
416 if (p_s->name[0] != 0)
417 _asn1_cpy_name (p_d, p_s);
419 _asn1_set_value (p_d, p_s->value, p_s->value_len);
424 p_d = _asn1_add_single_node (p_s->type);
425 _asn1_set_down (p_d_prev, p_d);
428 p_d->start = p_s->start;
432 if (p_s == source_node)
440 p_d = _asn1_add_single_node (p_s->type);
441 _asn1_set_right (p_d_prev, p_d);
446 p_s = _asn1_find_up (p_s);
447 p_d = _asn1_find_up (p_d);
450 while (p_s != source_node);
457 _asn1_copy_structure2 (asn1_node root, const char *source_name)
459 asn1_node source_node;
461 source_node = asn1_find_node (root, source_name);
463 return _asn1_copy_structure3 (source_node);
469 _asn1_type_choice_config (asn1_node node)
471 asn1_node p, p2, p3, p4;
475 return ASN1_ELEMENT_NOT_FOUND;
480 while (!((p == node) && (move == UP)))
484 if ((type_field (p->type) == ASN1_ETYPE_CHOICE)
485 && (p->type & CONST_TAG))
490 if (type_field (p2->type) != ASN1_ETYPE_TAG)
492 p2->type |= CONST_TAG;
493 p3 = _asn1_find_left (p2);
496 if (type_field (p3->type) == ASN1_ETYPE_TAG)
498 p4 = _asn1_add_single_node (p3->type);
499 tlen = _asn1_strlen (p3->value);
501 _asn1_set_value (p4, p3->value, tlen + 1);
502 _asn1_set_right (p4, p2->down);
503 _asn1_set_down (p2, p4);
505 p3 = _asn1_find_left (p3);
510 p->type &= ~(CONST_TAG);
515 if (type_field (p2->type) == ASN1_ETYPE_TAG)
516 asn1_delete_structure (&p2);
547 p = _asn1_find_up (p);
555 _asn1_expand_identifier (asn1_node * node, asn1_node root)
558 char name2[ASN1_MAX_NAME_SIZE + 2];
562 return ASN1_ELEMENT_NOT_FOUND;
567 while (!((p == *node) && (move == UP)))
571 if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
573 snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value);
574 p2 = _asn1_copy_structure2 (root, name2);
577 return ASN1_IDENTIFIER_NOT_FOUND;
579 _asn1_cpy_name (p2, p);
580 p2->right = p->right;
589 _asn1_set_right (p3, p2->down);
590 _asn1_set_down (p2, p->down);
593 p3 = _asn1_find_left (p);
595 _asn1_set_right (p3, p2);
598 p3 = _asn1_find_up (p);
600 _asn1_set_down (p3, p2);
607 if (p->type & CONST_SIZE)
608 p2->type |= CONST_SIZE;
609 if (p->type & CONST_TAG)
610 p2->type |= CONST_TAG;
611 if (p->type & CONST_OPTION)
612 p2->type |= CONST_OPTION;
613 if (p->type & CONST_DEFAULT)
614 p2->type |= CONST_DEFAULT;
615 if (p->type & CONST_SET)
616 p2->type |= CONST_SET;
617 if (p->type & CONST_NOT_USED)
618 p2->type |= CONST_NOT_USED;
622 _asn1_remove_node (p, 0);
654 p = _asn1_find_up (p);
662 * asn1_create_element:
663 * @definitions: pointer to the structure returned by "parser_asn1" function
664 * @source_name: the name of the type of the new structure (must be
665 * inside p_structure).
666 * @element: pointer to the structure created.
668 * Creates a structure of type @source_name. Example using
671 * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr);
673 * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if
674 * @source_name is not known.
677 asn1_create_element (asn1_node definitions, const char *source_name,
683 dest_node = _asn1_copy_structure2 (definitions, source_name);
685 if (dest_node == NULL)
686 return ASN1_ELEMENT_NOT_FOUND;
688 _asn1_set_name (dest_node, "");
690 res = _asn1_expand_identifier (&dest_node, definitions);
691 _asn1_type_choice_config (dest_node);
693 *element = dest_node;
700 * asn1_print_structure:
701 * @out: pointer to the output file (e.g. stdout).
702 * @structure: pointer to the structure that you want to visit.
703 * @name: an element of the structure
704 * @mode: specify how much of the structure to print, can be
705 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
706 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
708 * Prints on the @out file descriptor the structure's tree starting
709 * from the @name element inside the structure @structure.
712 asn1_print_structure (FILE * out, asn1_node structure, const char *name,
716 int k, indent = 0, len, len2, len3;
721 root = asn1_find_node (structure, name);
729 if (mode == ASN1_PRINT_ALL)
731 for (k = 0; k < indent; k++)
733 fprintf (out, "name:");
735 fprintf (out, "%s ", p->name);
737 fprintf (out, "NULL ");
741 switch (type_field (p->type))
743 case ASN1_ETYPE_CONSTANT:
745 case ASN1_ETYPE_SIZE:
748 for (k = 0; k < indent; k++)
750 fprintf (out, "name:");
752 fprintf (out, "%s ", p->name);
754 fprintf (out, "NULL ");
758 if (mode != ASN1_PRINT_NAME)
760 unsigned type = type_field (p->type);
763 case ASN1_ETYPE_CONSTANT:
764 if (mode == ASN1_PRINT_ALL)
765 fprintf (out, "type:CONST");
768 if (mode == ASN1_PRINT_ALL)
769 fprintf (out, "type:TAG");
771 case ASN1_ETYPE_SIZE:
772 if (mode == ASN1_PRINT_ALL)
773 fprintf (out, "type:SIZE");
775 case ASN1_ETYPE_DEFAULT:
776 fprintf (out, "type:DEFAULT");
778 case ASN1_ETYPE_IDENTIFIER:
779 fprintf (out, "type:IDENTIFIER");
782 fprintf (out, "type:ANY");
784 case ASN1_ETYPE_CHOICE:
785 fprintf (out, "type:CHOICE");
787 case ASN1_ETYPE_DEFINITIONS:
788 fprintf (out, "type:DEFINITIONS");
791 fprintf (out, "%s", _asn1_tags[type].desc);
798 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
800 switch (type_field (p->type))
802 case ASN1_ETYPE_CONSTANT:
803 if (mode == ASN1_PRINT_ALL)
805 fprintf (out, " value:%s", p->value);
808 if (mode == ASN1_PRINT_ALL)
810 fprintf (out, " value:%s", p->value);
812 case ASN1_ETYPE_SIZE:
813 if (mode == ASN1_PRINT_ALL)
815 fprintf (out, " value:%s", p->value);
817 case ASN1_ETYPE_DEFAULT:
819 fprintf (out, " value:%s", p->value);
820 else if (p->type & CONST_TRUE)
821 fprintf (out, " value:TRUE");
822 else if (p->type & CONST_FALSE)
823 fprintf (out, " value:FALSE");
825 case ASN1_ETYPE_IDENTIFIER:
827 fprintf (out, " value:%s", p->value);
829 case ASN1_ETYPE_INTEGER:
833 len = asn1_get_length_der (p->value, p->value_len, &len2);
834 fprintf (out, " value:0x");
836 for (k = 0; k < len; k++)
837 fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
840 case ASN1_ETYPE_ENUMERATED:
844 len = asn1_get_length_der (p->value, p->value_len, &len2);
845 fprintf (out, " value:0x");
847 for (k = 0; k < len; k++)
848 fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
851 case ASN1_ETYPE_BOOLEAN:
854 if (p->value[0] == 'T')
855 fprintf (out, " value:TRUE");
856 else if (p->value[0] == 'F')
857 fprintf (out, " value:FALSE");
860 case ASN1_ETYPE_BIT_STRING:
864 len = asn1_get_length_der (p->value, p->value_len, &len2);
867 fprintf (out, " value(%i):",
868 (len - 1) * 8 - (p->value[len2]));
869 for (k = 1; k < len; k++)
870 fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
874 case ASN1_ETYPE_GENERALIZED_TIME:
875 case ASN1_ETYPE_UTC_TIME:
878 fprintf (out, " value:");
879 for (k = 0; k < p->value_len; k++)
880 fprintf (out, "%c", (p->value)[k]);
883 case ASN1_ETYPE_GENERALSTRING:
884 case ASN1_ETYPE_NUMERIC_STRING:
885 case ASN1_ETYPE_IA5_STRING:
886 case ASN1_ETYPE_TELETEX_STRING:
887 case ASN1_ETYPE_PRINTABLE_STRING:
888 case ASN1_ETYPE_UNIVERSAL_STRING:
889 case ASN1_ETYPE_UTF8_STRING:
890 case ASN1_ETYPE_VISIBLE_STRING:
894 len = asn1_get_length_der (p->value, p->value_len, &len2);
895 fprintf (out, " value:");
897 for (k = 0; k < len; k++)
898 fprintf (out, "%c", (p->value)[k + len2]);
901 case ASN1_ETYPE_BMP_STRING:
902 case ASN1_ETYPE_OCTET_STRING:
906 len = asn1_get_length_der (p->value, p->value_len, &len2);
907 fprintf (out, " value:");
909 for (k = 0; k < len; k++)
910 fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
913 case ASN1_ETYPE_OBJECT_ID:
915 fprintf (out, " value:%s", p->value);
921 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
922 fprintf (out, " value:");
924 for (k = 0; k < len2; k++)
925 fprintf (out, "%02x", (unsigned) (p->value)[k + len3]);
929 case ASN1_ETYPE_SET_OF:
930 case ASN1_ETYPE_CHOICE:
931 case ASN1_ETYPE_DEFINITIONS:
932 case ASN1_ETYPE_SEQUENCE_OF:
933 case ASN1_ETYPE_SEQUENCE:
934 case ASN1_ETYPE_NULL:
941 if (mode == ASN1_PRINT_ALL)
943 if (p->type & 0x1FFFFF00)
945 fprintf (out, " attr:");
946 if (p->type & CONST_UNIVERSAL)
947 fprintf (out, "UNIVERSAL,");
948 if (p->type & CONST_PRIVATE)
949 fprintf (out, "PRIVATE,");
950 if (p->type & CONST_APPLICATION)
951 fprintf (out, "APPLICATION,");
952 if (p->type & CONST_EXPLICIT)
953 fprintf (out, "EXPLICIT,");
954 if (p->type & CONST_IMPLICIT)
955 fprintf (out, "IMPLICIT,");
956 if (p->type & CONST_TAG)
957 fprintf (out, "TAG,");
958 if (p->type & CONST_DEFAULT)
959 fprintf (out, "DEFAULT,");
960 if (p->type & CONST_TRUE)
961 fprintf (out, "TRUE,");
962 if (p->type & CONST_FALSE)
963 fprintf (out, "FALSE,");
964 if (p->type & CONST_LIST)
965 fprintf (out, "LIST,");
966 if (p->type & CONST_MIN_MAX)
967 fprintf (out, "MIN_MAX,");
968 if (p->type & CONST_OPTION)
969 fprintf (out, "OPTION,");
970 if (p->type & CONST_1_PARAM)
971 fprintf (out, "1_PARAM,");
972 if (p->type & CONST_SIZE)
973 fprintf (out, "SIZE,");
974 if (p->type & CONST_DEFINED_BY)
975 fprintf (out, "DEF_BY,");
976 if (p->type & CONST_GENERALIZED)
977 fprintf (out, "GENERALIZED,");
978 if (p->type & CONST_UTC)
979 fprintf (out, "UTC,");
980 if (p->type & CONST_SET)
981 fprintf (out, "SET,");
982 if (p->type & CONST_NOT_USED)
983 fprintf (out, "NOT_USED,");
984 if (p->type & CONST_ASSIGN)
985 fprintf (out, "ASSIGNMENT,");
989 if (mode == ASN1_PRINT_ALL)
995 switch (type_field (p->type))
997 case ASN1_ETYPE_CONSTANT:
999 case ASN1_ETYPE_SIZE:
1002 fprintf (out, "\n");
1022 p = _asn1_find_up (p);
1042 * asn1_number_of_elements:
1043 * @element: pointer to the root of an ASN1 structure.
1044 * @name: the name of a sub-structure of ROOT.
1045 * @num: pointer to an integer where the result will be stored
1047 * Counts the number of elements of a sub-structure called NAME with
1048 * names equal to "?1","?2", ...
1050 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
1051 * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
1054 asn1_number_of_elements (asn1_node element, const char *name, int *num)
1059 return ASN1_GENERIC_ERROR;
1063 node = asn1_find_node (element, name);
1065 return ASN1_ELEMENT_NOT_FOUND;
1071 if (p->name[0] == '?')
1076 return ASN1_SUCCESS;
1081 * asn1_find_structure_from_oid:
1082 * @definitions: ASN1 definitions
1083 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1085 * Search the structure that is defined just after an OID definition.
1087 * Returns: %NULL when @oidValue not found, otherwise the pointer to a
1088 * constant string that contains the element name defined just after
1092 asn1_find_structure_from_oid (asn1_node definitions, const char *oidValue)
1094 char name[2 * ASN1_MAX_NAME_SIZE + 1];
1095 char value[ASN1_MAX_NAME_SIZE];
1099 const char *definitionsName;
1101 if ((definitions == NULL) || (oidValue == NULL))
1102 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1104 definitionsName = definitions->name;
1106 /* search the OBJECT_ID into definitions */
1107 p = definitions->down;
1110 if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1111 (p->type & CONST_ASSIGN))
1113 snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name);
1115 len = ASN1_MAX_NAME_SIZE;
1116 result = asn1_read_value (definitions, name, value, &len);
1118 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1121 if (p == NULL) /* reach the end of ASN1 definitions */
1122 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1130 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1135 * @dst: Destination asn1 node.
1136 * @dst_name: Field name in destination node.
1137 * @src: Source asn1 node.
1138 * @src_name: Field name in source node.
1140 * Create a deep copy of a asn1_node variable. That
1141 * function requires @dst to be expanded using asn1_create_element().
1143 * Returns: Return %ASN1_SUCCESS on success.
1146 asn1_copy_node (asn1_node dst, const char *dst_name,
1147 asn1_node src, const char *src_name)
1154 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1155 if (result != ASN1_MEM_ERROR)
1158 data = malloc (size);
1160 return ASN1_MEM_ERROR;
1162 result = asn1_der_coding (src, src_name, data, &size, NULL);
1163 if (result != ASN1_SUCCESS)
1169 dst_node = asn1_find_node (dst, dst_name);
1170 if (dst_node == NULL)
1173 return ASN1_ELEMENT_NOT_FOUND;
1176 result = asn1_der_decoding (&dst_node, data, size, NULL);
1185 * @src: Source asn1 node.
1186 * @src_name: Field name in source node.
1188 * Create a deep copy of a asn1_node variable. This function
1189 * will return an exact copy of the provided structure.
1191 * Returns: Return %NULL on failure.
1194 asn1_dup_node (asn1_node src, const char *src_name)
1196 return _asn1_copy_structure2(src, src_name);