2 * Copyright (C) 2002-2012 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_node_only */
41 /* Description: creates a new NODE_ASN element. */
43 /* type: type of the new element (see TYPE_ */
44 /* and CONST_ constants). */
45 /* Return: pointer to the new element. */
46 /******************************************************/
48 _asn1_add_node_only (unsigned int type)
52 punt = (ASN1_TYPE) _asn1_calloc (1, sizeof (struct node_asn_struct));
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_TYPE node)
73 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
81 _asn1_create_static_structure (ASN1_TYPE 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_ARRAY_TYPE %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 ASN1_TYPE_EMPTY,
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_ARRAY_TYPE * array, ASN1_TYPE * definitions,
178 char *errorDescription)
180 ASN1_TYPE p, p_last = NULL;
186 if (*definitions != ASN1_TYPE_EMPTY)
187 return ASN1_ELEMENT_NOT_EMPTY;
192 while (array[k].value || array[k].type || array[k].name)
194 p = _asn1_add_node (array[k].type & (~CONST_DOWN));
196 _asn1_set_name (p, array[k].name);
198 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
200 if (*definitions == NULL)
204 _asn1_set_down (p_last, p);
205 else if (move == RIGHT)
206 _asn1_set_right (p_last, p);
210 if (array[k].type & CONST_DOWN)
212 else if (array[k].type & CONST_RIGHT)
218 if (p_last == *definitions)
221 p_last = _asn1_find_up (p_last);
226 if (p_last->type & CONST_RIGHT)
228 p_last->type &= ~CONST_RIGHT;
237 if (p_last == *definitions)
239 result = _asn1_check_identifier (*definitions);
240 if (result == ASN1_SUCCESS)
242 _asn1_change_integer_value (*definitions);
243 _asn1_expand_object_id (*definitions);
248 result = ASN1_ARRAY_ERROR;
251 if (errorDescription != NULL)
253 if (result == ASN1_IDENTIFIER_NOT_FOUND)
255 Estrcpy (errorDescription, ":: identifier '");
256 Estrcat (errorDescription, _asn1_identifierMissing);
257 Estrcat (errorDescription, "' not found");
260 errorDescription[0] = 0;
263 if (result != ASN1_SUCCESS)
265 _asn1_delete_list_and_nodes ();
266 *definitions = ASN1_TYPE_EMPTY;
269 _asn1_delete_list ();
275 * asn1_delete_structure:
276 * @structure: pointer to the structure that you want to delete.
278 * Deletes the structure *@structure. At the end, *@structure is set
279 * to ASN1_TYPE_EMPTY.
281 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
282 * *@structure was ASN1_TYPE_EMPTY.
285 asn1_delete_structure (ASN1_TYPE * structure)
289 if (*structure == ASN1_TYPE_EMPTY)
290 return ASN1_ELEMENT_NOT_FOUND;
304 p3 = _asn1_find_up (p);
305 _asn1_set_down (p3, p2);
306 _asn1_remove_node (p);
311 p3 = _asn1_find_left (p);
314 p3 = _asn1_find_up (p);
316 _asn1_set_down (p3, p2);
320 p->right->left = NULL;
324 _asn1_set_right (p3, p2);
325 _asn1_remove_node (p);
331 *structure = ASN1_TYPE_EMPTY;
338 * asn1_delete_element:
339 * @structure: pointer to the structure that contains the element you
341 * @element_name: element's name you want to delete.
343 * Deletes the element named *@element_name inside *@structure.
345 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
346 * the @element_name was not found.
349 asn1_delete_element (ASN1_TYPE structure, const char *element_name)
351 ASN1_TYPE p2, p3, source_node;
353 source_node = asn1_find_node (structure, element_name);
355 if (source_node == ASN1_TYPE_EMPTY)
356 return ASN1_ELEMENT_NOT_FOUND;
358 p2 = source_node->right;
359 p3 = _asn1_find_left (source_node);
362 p3 = _asn1_find_up (source_node);
364 _asn1_set_down (p3, p2);
365 else if (source_node->right)
366 source_node->right->left = NULL;
369 _asn1_set_right (p3, p2);
371 return asn1_delete_structure (&source_node);
375 _asn1_copy_structure3 (ASN1_TYPE source_node)
377 ASN1_TYPE dest_node, p_s, p_d, p_d_prev;
380 if (source_node == NULL)
383 dest_node = _asn1_add_node_only (source_node->type);
395 _asn1_set_name (p_d, p_s->name);
397 _asn1_set_value (p_d, p_s->value, p_s->value_len);
409 p_d = _asn1_add_node_only (p_s->type);
410 _asn1_set_down (p_d_prev, p_d);
416 if (p_s == source_node)
425 p_d = _asn1_add_node_only (p_s->type);
426 _asn1_set_right (p_d_prev, p_d);
433 p_s = _asn1_find_up (p_s);
434 p_d = _asn1_find_up (p_d);
437 while (p_s != source_node);
444 _asn1_copy_structure2 (ASN1_TYPE root, const char *source_name)
446 ASN1_TYPE source_node;
448 source_node = asn1_find_node (root, source_name);
450 return _asn1_copy_structure3 (source_node);
456 _asn1_type_choice_config (ASN1_TYPE node)
458 ASN1_TYPE p, p2, p3, p4;
462 return ASN1_ELEMENT_NOT_FOUND;
467 while (!((p == node) && (move == UP)))
471 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
476 if (type_field (p2->type) != TYPE_TAG)
478 p2->type |= CONST_TAG;
479 p3 = _asn1_find_left (p2);
482 if (type_field (p3->type) == TYPE_TAG)
484 p4 = _asn1_add_node_only (p3->type);
485 tlen = _asn1_strlen (p3->value);
487 _asn1_set_value (p4, p3->value, tlen + 1);
488 _asn1_set_right (p4, p2->down);
489 _asn1_set_down (p2, p4);
491 p3 = _asn1_find_left (p3);
496 p->type &= ~(CONST_TAG);
501 if (type_field (p2->type) == TYPE_TAG)
502 asn1_delete_structure (&p2);
533 p = _asn1_find_up (p);
541 _asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root)
544 char name2[ASN1_MAX_NAME_SIZE + 2];
548 return ASN1_ELEMENT_NOT_FOUND;
553 while (!((p == *node) && (move == UP)))
557 if (type_field (p->type) == TYPE_IDENTIFIER)
559 _asn1_str_cpy (name2, sizeof (name2), root->name);
560 _asn1_str_cat (name2, sizeof (name2), ".");
561 _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
562 p2 = _asn1_copy_structure2 (root, name2);
565 return ASN1_IDENTIFIER_NOT_FOUND;
567 _asn1_set_name (p2, p->name);
568 p2->right = p->right;
577 _asn1_set_right (p3, p2->down);
578 _asn1_set_down (p2, p->down);
581 p3 = _asn1_find_left (p);
583 _asn1_set_right (p3, p2);
586 p3 = _asn1_find_up (p);
588 _asn1_set_down (p3, p2);
595 if (p->type & CONST_SIZE)
596 p2->type |= CONST_SIZE;
597 if (p->type & CONST_TAG)
598 p2->type |= CONST_TAG;
599 if (p->type & CONST_OPTION)
600 p2->type |= CONST_OPTION;
601 if (p->type & CONST_DEFAULT)
602 p2->type |= CONST_DEFAULT;
603 if (p->type & CONST_SET)
604 p2->type |= CONST_SET;
605 if (p->type & CONST_NOT_USED)
606 p2->type |= CONST_NOT_USED;
610 _asn1_remove_node (p);
642 p = _asn1_find_up (p);
650 * asn1_create_element:
651 * @definitions: pointer to the structure returned by "parser_asn1" function
652 * @source_name: the name of the type of the new structure (must be
653 * inside p_structure).
654 * @element: pointer to the structure created.
656 * Creates a structure of type @source_name. Example using
659 * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr);
661 * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if
662 * @source_name is not known.
665 asn1_create_element (ASN1_TYPE definitions, const char *source_name,
671 dest_node = _asn1_copy_structure2 (definitions, source_name);
673 if (dest_node == NULL)
674 return ASN1_ELEMENT_NOT_FOUND;
676 _asn1_set_name (dest_node, "");
678 res = _asn1_expand_identifier (&dest_node, definitions);
679 _asn1_type_choice_config (dest_node);
681 *element = dest_node;
688 * asn1_print_structure:
689 * @out: pointer to the output file (e.g. stdout).
690 * @structure: pointer to the structure that you want to visit.
691 * @name: an element of the structure
692 * @mode: specify how much of the structure to print, can be
693 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
694 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
696 * Prints on the @out file descriptor the structure's tree starting
697 * from the @name element inside the structure @structure.
700 asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
704 int k, indent = 0, len, len2, len3;
709 root = asn1_find_node (structure, name);
717 if (mode == ASN1_PRINT_ALL)
719 for (k = 0; k < indent; k++)
721 fprintf (out, "name:");
723 fprintf (out, "%s ", p->name);
725 fprintf (out, "NULL ");
729 switch (type_field (p->type))
736 for (k = 0; k < indent; k++)
738 fprintf (out, "name:");
740 fprintf (out, "%s ", p->name);
742 fprintf (out, "NULL ");
746 if (mode != ASN1_PRINT_NAME)
748 switch (type_field (p->type))
751 if (mode == ASN1_PRINT_ALL)
752 fprintf (out, "type:CONST");
755 if (mode == ASN1_PRINT_ALL)
756 fprintf (out, "type:TAG");
759 if (mode == ASN1_PRINT_ALL)
760 fprintf (out, "type:SIZE");
763 fprintf (out, "type:DEFAULT");
766 fprintf (out, "type:NULL");
768 case TYPE_IDENTIFIER:
769 fprintf (out, "type:IDENTIFIER");
772 fprintf (out, "type:INTEGER");
774 case TYPE_ENUMERATED:
775 fprintf (out, "type:ENUMERATED");
778 fprintf (out, "type:TIME");
781 fprintf (out, "type:BOOLEAN");
784 fprintf (out, "type:SEQUENCE");
786 case TYPE_BIT_STRING:
787 fprintf (out, "type:BIT_STR");
789 case TYPE_OCTET_STRING:
790 fprintf (out, "type:OCT_STR");
792 case TYPE_GENERALSTRING:
793 fprintf (out, "type:GENERALSTRING");
795 case TYPE_SEQUENCE_OF:
796 fprintf (out, "type:SEQ_OF");
799 fprintf (out, "type:OBJ_ID");
802 fprintf (out, "type:ANY");
805 fprintf (out, "type:SET");
808 fprintf (out, "type:SET_OF");
811 fprintf (out, "type:CHOICE");
813 case TYPE_DEFINITIONS:
814 fprintf (out, "type:DEFINITIONS");
821 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
823 switch (type_field (p->type))
826 if (mode == ASN1_PRINT_ALL)
828 fprintf (out, " value:%s", p->value);
831 if (mode == ASN1_PRINT_ALL)
833 fprintf (out, " value:%s", p->value);
836 if (mode == ASN1_PRINT_ALL)
838 fprintf (out, " value:%s", p->value);
842 fprintf (out, " value:%s", p->value);
843 else if (p->type & CONST_TRUE)
844 fprintf (out, " value:TRUE");
845 else if (p->type & CONST_FALSE)
846 fprintf (out, " value:FALSE");
848 case TYPE_IDENTIFIER:
850 fprintf (out, " value:%s", p->value);
856 len = asn1_get_length_der (p->value, p->value_len, &len2);
857 fprintf (out, " value:0x");
859 for (k = 0; k < len; k++)
860 fprintf (out, "%02x", (p->value)[k + len2]);
863 case TYPE_ENUMERATED:
867 len = asn1_get_length_der (p->value, p->value_len, &len2);
868 fprintf (out, " value:0x");
870 for (k = 0; k < len; k++)
871 fprintf (out, "%02x", (p->value)[k + len2]);
876 fprintf (out, " value:%s", p->value);
881 if (p->value[0] == 'T')
882 fprintf (out, " value:TRUE");
883 else if (p->value[0] == 'F')
884 fprintf (out, " value:FALSE");
887 case TYPE_BIT_STRING:
891 len = asn1_get_length_der (p->value, p->value_len, &len2);
894 fprintf (out, " value(%i):",
895 (len - 1) * 8 - (p->value[len2]));
896 for (k = 1; k < len; k++)
897 fprintf (out, "%02x", (p->value)[k + len2]);
901 case TYPE_OCTET_STRING:
905 len = asn1_get_length_der (p->value, p->value_len, &len2);
906 fprintf (out, " value:");
908 for (k = 0; k < len; k++)
909 fprintf (out, "%02x", (p->value)[k + len2]);
912 case TYPE_GENERALSTRING:
916 len = asn1_get_length_der (p->value, p->value_len, &len2);
917 fprintf (out, " value:");
919 for (k = 0; k < len; k++)
920 fprintf (out, "%02x", (p->value)[k + len2]);
925 fprintf (out, " value:%s", p->value);
931 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
932 fprintf (out, " value:");
934 for (k = 0; k < len2; k++)
935 fprintf (out, "%02x", (p->value)[k + len3]);
941 case TYPE_DEFINITIONS:
942 case TYPE_SEQUENCE_OF:
951 if (mode == ASN1_PRINT_ALL)
953 if (p->type & 0x1FFFFF00)
955 fprintf (out, " attr:");
956 if (p->type & CONST_UNIVERSAL)
957 fprintf (out, "UNIVERSAL,");
958 if (p->type & CONST_PRIVATE)
959 fprintf (out, "PRIVATE,");
960 if (p->type & CONST_APPLICATION)
961 fprintf (out, "APPLICATION,");
962 if (p->type & CONST_EXPLICIT)
963 fprintf (out, "EXPLICIT,");
964 if (p->type & CONST_IMPLICIT)
965 fprintf (out, "IMPLICIT,");
966 if (p->type & CONST_TAG)
967 fprintf (out, "TAG,");
968 if (p->type & CONST_DEFAULT)
969 fprintf (out, "DEFAULT,");
970 if (p->type & CONST_TRUE)
971 fprintf (out, "TRUE,");
972 if (p->type & CONST_FALSE)
973 fprintf (out, "FALSE,");
974 if (p->type & CONST_LIST)
975 fprintf (out, "LIST,");
976 if (p->type & CONST_MIN_MAX)
977 fprintf (out, "MIN_MAX,");
978 if (p->type & CONST_OPTION)
979 fprintf (out, "OPTION,");
980 if (p->type & CONST_1_PARAM)
981 fprintf (out, "1_PARAM,");
982 if (p->type & CONST_SIZE)
983 fprintf (out, "SIZE,");
984 if (p->type & CONST_DEFINED_BY)
985 fprintf (out, "DEF_BY,");
986 if (p->type & CONST_GENERALIZED)
987 fprintf (out, "GENERALIZED,");
988 if (p->type & CONST_UTC)
989 fprintf (out, "UTC,");
990 if (p->type & CONST_SET)
991 fprintf (out, "SET,");
992 if (p->type & CONST_NOT_USED)
993 fprintf (out, "NOT_USED,");
994 if (p->type & CONST_ASSIGN)
995 fprintf (out, "ASSIGNMENT,");
999 if (mode == ASN1_PRINT_ALL)
1001 fprintf (out, "\n");
1005 switch (type_field (p->type))
1012 fprintf (out, "\n");
1032 p = _asn1_find_up (p);
1052 * asn1_number_of_elements:
1053 * @element: pointer to the root of an ASN1 structure.
1054 * @name: the name of a sub-structure of ROOT.
1055 * @num: pointer to an integer where the result will be stored
1057 * Counts the number of elements of a sub-structure called NAME with
1058 * names equal to "?1","?2", ...
1060 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
1061 * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
1064 asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1069 return ASN1_GENERIC_ERROR;
1073 node = asn1_find_node (element, name);
1075 return ASN1_ELEMENT_NOT_FOUND;
1081 if ((p->name) && (p->name[0] == '?'))
1086 return ASN1_SUCCESS;
1091 * asn1_find_structure_from_oid:
1092 * @definitions: ASN1 definitions
1093 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1095 * Search the structure that is defined just after an OID definition.
1097 * Returns: %NULL when @oidValue not found, otherwise the pointer to a
1098 * constant string that contains the element name defined just after
1102 asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1104 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1];
1105 char value[ASN1_MAX_NAME_SIZE];
1108 asn1_retCode result;
1110 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1111 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1114 strcpy (definitionsName, definitions->name);
1115 strcat (definitionsName, ".");
1117 /* search the OBJECT_ID into definitions */
1118 p = definitions->down;
1121 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1122 (p->type & CONST_ASSIGN))
1124 strcpy (name, definitionsName);
1125 strcat (name, p->name);
1127 len = ASN1_MAX_NAME_SIZE;
1128 result = asn1_read_value (definitions, name, value, &len);
1130 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1133 if (p == NULL) /* reach the end of ASN1 definitions */
1134 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1142 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1147 * @dst: Destination ASN1_TYPE node.
1148 * @dst_name: Field name in destination node.
1149 * @src: Source ASN1_TYPE node.
1150 * @src_name: Field name in source node.
1152 * Create a deep copy of a ASN1_TYPE variable.
1154 * Returns: Return %ASN1_SUCCESS on success.
1157 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1158 ASN1_TYPE src, const char *src_name)
1160 /* FIXME: rewrite using copy_structure().
1161 * It seems quite hard to do.
1168 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1169 if (result != ASN1_MEM_ERROR)
1172 data = _asn1_malloc (size);
1174 return ASN1_MEM_ERROR;
1176 result = asn1_der_coding (src, src_name, data, &size, NULL);
1177 if (result != ASN1_SUCCESS)
1183 dst_node = asn1_find_node (dst, dst_name);
1184 if (dst_node == NULL)
1187 return ASN1_ELEMENT_NOT_FOUND;
1190 result = asn1_der_decoding (&dst_node, data, size, NULL);