2 * Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009, 2010 Free
3 * 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
24 /*****************************************************/
25 /* File: structure.c */
26 /* Description: Functions to create and delete an */
28 /*****************************************************/
32 #include <structure.h>
33 #include "parser_aux.h"
37 extern char _asn1_identifierMissing[];
40 /******************************************************/
41 /* Function : _asn1_add_node_only */
42 /* Description: creates a new NODE_ASN element. */
44 /* type: type of the new element (see TYPE_ */
45 /* and CONST_ constants). */
46 /* Return: pointer to the new element. */
47 /******************************************************/
49 _asn1_add_node_only (unsigned int type)
53 punt = (ASN1_TYPE) _asn1_calloc (1, sizeof (struct node_asn_struct));
63 /******************************************************************/
64 /* Function : _asn1_find_left */
65 /* Description: returns the NODE_ASN element with RIGHT field that*/
66 /* points the element NODE. */
68 /* node: NODE_ASN element pointer. */
69 /* Return: NULL if not found. */
70 /******************************************************************/
72 _asn1_find_left (ASN1_TYPE node)
74 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
82 _asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
89 file = fopen (output_file_name, "w");
92 return ASN1_FILE_NOT_FOUND;
94 fprintf (file, "#if HAVE_CONFIG_H\n");
95 fprintf (file, "# include \"config.h\"\n");
96 fprintf (file, "#endif\n\n");
98 fprintf (file, "#include <libtasn1.h>\n\n");
100 fprintf (file, "const ASN1_ARRAY_TYPE %s[] = {\n", vector_name);
106 fprintf (file, " { ");
109 fprintf (file, "\"%s\", ", p->name);
111 fprintf (file, "NULL, ");
119 fprintf (file, "%lu, ", t);
122 fprintf (file, "\"%s\"},\n", p->value);
124 fprintf (file, "NULL },\n");
138 p = _asn1_find_up (p);
153 fprintf (file, " { NULL, 0, NULL }\n};\n");
163 * @array: specify the array that contains ASN.1 declarations
164 * @definitions: return the pointer to the structure created by
165 * *ARRAY ASN.1 declarations
166 * @errorDescription: return the error description.
168 * Creates the structures needed to manage the ASN.1 definitions.
169 * @array is a vector created by asn1_parser2array().
173 * %ASN1_SUCCESS: Structure created correctly.
175 * %ASN1_ELEMENT_NOT_EMPTY: *@definitions not ASN1_TYPE_EMPTY.
177 * %ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
178 * is not defined (see @errorDescription for more information).
180 * %ASN1_ARRAY_ERROR: The array pointed by @array is wrong.
183 asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
184 char *errorDescription)
186 ASN1_TYPE p, p_last = NULL;
192 if (*definitions != ASN1_TYPE_EMPTY)
193 return ASN1_ELEMENT_NOT_EMPTY;
198 while (array[k].value || array[k].type || array[k].name)
200 p = _asn1_add_node (array[k].type & (~CONST_DOWN));
202 _asn1_set_name (p, array[k].name);
204 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
206 if (*definitions == NULL)
210 _asn1_set_down (p_last, p);
211 else if (move == RIGHT)
212 _asn1_set_right (p_last, p);
216 if (array[k].type & CONST_DOWN)
218 else if (array[k].type & CONST_RIGHT)
224 if (p_last == *definitions)
227 p_last = _asn1_find_up (p_last);
232 if (p_last->type & CONST_RIGHT)
234 p_last->type &= ~CONST_RIGHT;
243 if (p_last == *definitions)
245 result = _asn1_check_identifier (*definitions);
246 if (result == ASN1_SUCCESS)
248 _asn1_change_integer_value (*definitions);
249 _asn1_expand_object_id (*definitions);
254 result = ASN1_ARRAY_ERROR;
257 if (errorDescription != NULL)
259 if (result == ASN1_IDENTIFIER_NOT_FOUND)
261 Estrcpy (errorDescription, ":: identifier '");
262 Estrcat (errorDescription, _asn1_identifierMissing);
263 Estrcat (errorDescription, "' not found");
266 errorDescription[0] = 0;
269 if (result != ASN1_SUCCESS)
271 _asn1_delete_list_and_nodes ();
272 *definitions = ASN1_TYPE_EMPTY;
275 _asn1_delete_list ();
281 * asn1_delete_structure:
282 * @structure: pointer to the structure that you want to delete.
284 * Deletes the structure *@structure. At the end, *@structure is set
285 * to ASN1_TYPE_EMPTY.
289 * %ASN1_SUCCESS: Everything OK.
291 * %ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY.
294 asn1_delete_structure (ASN1_TYPE * structure)
298 if (*structure == ASN1_TYPE_EMPTY)
299 return ASN1_ELEMENT_NOT_FOUND;
313 p3 = _asn1_find_up (p);
314 _asn1_set_down (p3, p2);
315 _asn1_remove_node (p);
320 p3 = _asn1_find_left (p);
323 p3 = _asn1_find_up (p);
325 _asn1_set_down (p3, p2);
329 p->right->left = NULL;
333 _asn1_set_right (p3, p2);
334 _asn1_remove_node (p);
340 *structure = ASN1_TYPE_EMPTY;
347 * asn1_delete_element:
348 * @structure: pointer to the structure that contains the element you
350 * @element_name: element's name you want to delete.
352 * Deletes the element named *@element_name inside *@structure.
356 * %ASN1_SUCCESS: Everything OK.
358 * %ASN1_ELEMENT_NOT_FOUND: The name element was not found.
361 asn1_delete_element (ASN1_TYPE structure, const char *element_name)
363 ASN1_TYPE p2, p3, source_node;
365 source_node = asn1_find_node (structure, element_name);
367 if (source_node == ASN1_TYPE_EMPTY)
368 return ASN1_ELEMENT_NOT_FOUND;
370 p2 = source_node->right;
371 p3 = _asn1_find_left (source_node);
374 p3 = _asn1_find_up (source_node);
376 _asn1_set_down (p3, p2);
377 else if (source_node->right)
378 source_node->right->left = NULL;
381 _asn1_set_right (p3, p2);
383 return asn1_delete_structure (&source_node);
387 _asn1_copy_structure3 (ASN1_TYPE source_node)
389 ASN1_TYPE dest_node, p_s, p_d, p_d_prev;
392 if (source_node == NULL)
395 dest_node = _asn1_add_node_only (source_node->type);
407 _asn1_set_name (p_d, p_s->name);
409 _asn1_set_value (p_d, p_s->value, p_s->value_len);
421 p_d = _asn1_add_node_only (p_s->type);
422 _asn1_set_down (p_d_prev, p_d);
428 if (p_s == source_node)
437 p_d = _asn1_add_node_only (p_s->type);
438 _asn1_set_right (p_d_prev, p_d);
445 p_s = _asn1_find_up (p_s);
446 p_d = _asn1_find_up (p_d);
449 while (p_s != source_node);
456 _asn1_copy_structure2 (ASN1_TYPE root, const char *source_name)
458 ASN1_TYPE source_node;
460 source_node = asn1_find_node (root, source_name);
462 return _asn1_copy_structure3 (source_node);
468 _asn1_type_choice_config (ASN1_TYPE node)
470 ASN1_TYPE p, p2, p3, p4;
474 return ASN1_ELEMENT_NOT_FOUND;
479 while (!((p == node) && (move == UP)))
483 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
488 if (type_field (p2->type) != TYPE_TAG)
490 p2->type |= CONST_TAG;
491 p3 = _asn1_find_left (p2);
494 if (type_field (p3->type) == TYPE_TAG)
496 p4 = _asn1_add_node_only (p3->type);
497 tlen = strlen (p3->value);
499 _asn1_set_value (p4, p3->value, tlen + 1);
500 _asn1_set_right (p4, p2->down);
501 _asn1_set_down (p2, p4);
503 p3 = _asn1_find_left (p3);
508 p->type &= ~(CONST_TAG);
513 if (type_field (p2->type) == TYPE_TAG)
514 asn1_delete_structure (&p2);
545 p = _asn1_find_up (p);
553 _asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root)
556 char name2[ASN1_MAX_NAME_SIZE + 2];
560 return ASN1_ELEMENT_NOT_FOUND;
565 while (!((p == *node) && (move == UP)))
569 if (type_field (p->type) == TYPE_IDENTIFIER)
571 _asn1_str_cpy (name2, sizeof (name2), root->name);
572 _asn1_str_cat (name2, sizeof (name2), ".");
573 _asn1_str_cat (name2, sizeof (name2), p->value);
574 p2 = _asn1_copy_structure2 (root, name2);
577 return ASN1_IDENTIFIER_NOT_FOUND;
579 _asn1_set_name (p2, p->name);
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);
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);
675 * %ASN1_SUCCESS: Creation OK.
677 * %ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
680 asn1_create_element (ASN1_TYPE definitions, const char *source_name,
686 dest_node = _asn1_copy_structure2 (definitions, source_name);
688 if (dest_node == NULL)
689 return ASN1_ELEMENT_NOT_FOUND;
691 _asn1_set_name (dest_node, "");
693 res = _asn1_expand_identifier (&dest_node, definitions);
694 _asn1_type_choice_config (dest_node);
696 *element = dest_node;
703 * asn1_print_structure:
704 * @out: pointer to the output file (e.g. stdout).
705 * @structure: pointer to the structure that you want to visit.
706 * @name: an element of the structure
707 * @mode: specify how much of the structure to print, can be
708 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
709 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
711 * Prints on the @out file descriptor the structure's tree starting
712 * from the @name element inside the structure @structure.
715 asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
719 int k, indent = 0, len, len2, len3;
724 root = asn1_find_node (structure, name);
732 if (mode == ASN1_PRINT_ALL)
734 for (k = 0; k < indent; k++)
736 fprintf (out, "name:");
738 fprintf (out, "%s ", p->name);
740 fprintf (out, "NULL ");
744 switch (type_field (p->type))
751 for (k = 0; k < indent; k++)
753 fprintf (out, "name:");
755 fprintf (out, "%s ", p->name);
757 fprintf (out, "NULL ");
761 if (mode != ASN1_PRINT_NAME)
763 switch (type_field (p->type))
766 if (mode == ASN1_PRINT_ALL)
767 fprintf (out, "type:CONST");
770 if (mode == ASN1_PRINT_ALL)
771 fprintf (out, "type:TAG");
774 if (mode == ASN1_PRINT_ALL)
775 fprintf (out, "type:SIZE");
778 fprintf (out, "type:DEFAULT");
781 fprintf (out, "type:NULL");
783 case TYPE_IDENTIFIER:
784 fprintf (out, "type:IDENTIFIER");
787 fprintf (out, "type:INTEGER");
789 case TYPE_ENUMERATED:
790 fprintf (out, "type:ENUMERATED");
793 fprintf (out, "type:TIME");
796 fprintf (out, "type:BOOLEAN");
799 fprintf (out, "type:SEQUENCE");
801 case TYPE_BIT_STRING:
802 fprintf (out, "type:BIT_STR");
804 case TYPE_OCTET_STRING:
805 fprintf (out, "type:OCT_STR");
807 case TYPE_GENERALSTRING:
808 fprintf (out, "type:GENERALSTRING");
810 case TYPE_SEQUENCE_OF:
811 fprintf (out, "type:SEQ_OF");
814 fprintf (out, "type:OBJ_ID");
817 fprintf (out, "type:ANY");
820 fprintf (out, "type:SET");
823 fprintf (out, "type:SET_OF");
826 fprintf (out, "type:CHOICE");
828 case TYPE_DEFINITIONS:
829 fprintf (out, "type:DEFINITIONS");
836 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
838 switch (type_field (p->type))
841 if (mode == ASN1_PRINT_ALL)
843 fprintf (out, " value:%s", p->value);
846 if (mode == ASN1_PRINT_ALL)
848 fprintf (out, " value:%s", p->value);
851 if (mode == ASN1_PRINT_ALL)
853 fprintf (out, " value:%s", p->value);
857 fprintf (out, " value:%s", p->value);
858 else if (p->type & CONST_TRUE)
859 fprintf (out, " value:TRUE");
860 else if (p->type & CONST_FALSE)
861 fprintf (out, " value:FALSE");
863 case TYPE_IDENTIFIER:
865 fprintf (out, " value:%s", p->value);
871 len = asn1_get_length_der (p->value, p->value_len, &len2);
872 fprintf (out, " value:0x");
874 for (k = 0; k < len; k++)
875 fprintf (out, "%02x", (p->value)[k + len2]);
878 case TYPE_ENUMERATED:
882 len = asn1_get_length_der (p->value, p->value_len, &len2);
883 fprintf (out, " value:0x");
885 for (k = 0; k < len; k++)
886 fprintf (out, "%02x", (p->value)[k + len2]);
891 fprintf (out, " value:%s", p->value);
896 if (p->value[0] == 'T')
897 fprintf (out, " value:TRUE");
898 else if (p->value[0] == 'F')
899 fprintf (out, " value:FALSE");
902 case TYPE_BIT_STRING:
906 len = asn1_get_length_der (p->value, p->value_len, &len2);
909 fprintf (out, " value(%i):",
910 (len - 1) * 8 - (p->value[len2]));
911 for (k = 1; k < len; k++)
912 fprintf (out, "%02x", (p->value)[k + len2]);
916 case TYPE_OCTET_STRING:
920 len = asn1_get_length_der (p->value, p->value_len, &len2);
921 fprintf (out, " value:");
923 for (k = 0; k < len; k++)
924 fprintf (out, "%02x", (p->value)[k + len2]);
927 case TYPE_GENERALSTRING:
931 len = asn1_get_length_der (p->value, p->value_len, &len2);
932 fprintf (out, " value:");
934 for (k = 0; k < len; k++)
935 fprintf (out, "%02x", (p->value)[k + len2]);
940 fprintf (out, " value:%s", p->value);
946 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
947 fprintf (out, " value:");
949 for (k = 0; k < len2; k++)
950 fprintf (out, "%02x", (p->value)[k + len3]);
956 case TYPE_DEFINITIONS:
957 case TYPE_SEQUENCE_OF:
966 if (mode == ASN1_PRINT_ALL)
968 if (p->type & 0x1FFFFF00)
970 fprintf (out, " attr:");
971 if (p->type & CONST_UNIVERSAL)
972 fprintf (out, "UNIVERSAL,");
973 if (p->type & CONST_PRIVATE)
974 fprintf (out, "PRIVATE,");
975 if (p->type & CONST_APPLICATION)
976 fprintf (out, "APPLICATION,");
977 if (p->type & CONST_EXPLICIT)
978 fprintf (out, "EXPLICIT,");
979 if (p->type & CONST_IMPLICIT)
980 fprintf (out, "IMPLICIT,");
981 if (p->type & CONST_TAG)
982 fprintf (out, "TAG,");
983 if (p->type & CONST_DEFAULT)
984 fprintf (out, "DEFAULT,");
985 if (p->type & CONST_TRUE)
986 fprintf (out, "TRUE,");
987 if (p->type & CONST_FALSE)
988 fprintf (out, "FALSE,");
989 if (p->type & CONST_LIST)
990 fprintf (out, "LIST,");
991 if (p->type & CONST_MIN_MAX)
992 fprintf (out, "MIN_MAX,");
993 if (p->type & CONST_OPTION)
994 fprintf (out, "OPTION,");
995 if (p->type & CONST_1_PARAM)
996 fprintf (out, "1_PARAM,");
997 if (p->type & CONST_SIZE)
998 fprintf (out, "SIZE,");
999 if (p->type & CONST_DEFINED_BY)
1000 fprintf (out, "DEF_BY,");
1001 if (p->type & CONST_GENERALIZED)
1002 fprintf (out, "GENERALIZED,");
1003 if (p->type & CONST_UTC)
1004 fprintf (out, "UTC,");
1005 if (p->type & CONST_SET)
1006 fprintf (out, "SET,");
1007 if (p->type & CONST_NOT_USED)
1008 fprintf (out, "NOT_USED,");
1009 if (p->type & CONST_ASSIGN)
1010 fprintf (out, "ASSIGNMENT,");
1014 if (mode == ASN1_PRINT_ALL)
1016 fprintf (out, "\n");
1020 switch (type_field (p->type))
1027 fprintf (out, "\n");
1047 p = _asn1_find_up (p);
1067 * asn1_number_of_elements:
1068 * @element: pointer to the root of an ASN1 structure.
1069 * @name: the name of a sub-structure of ROOT.
1070 * @num: pointer to an integer where the result will be stored
1072 * Counts the number of elements of a sub-structure called NAME with
1073 * names equal to "?1","?2", ...
1077 * %ASN1_SUCCESS: Creation OK.
1079 * %ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
1081 * %ASN1_GENERIC_ERROR: Pointer num equal to NULL.
1084 asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1089 return ASN1_GENERIC_ERROR;
1093 node = asn1_find_node (element, name);
1095 return ASN1_ELEMENT_NOT_FOUND;
1101 if ((p->name) && (p->name[0] == '?'))
1106 return ASN1_SUCCESS;
1111 * asn1_find_structure_from_oid:
1112 * @definitions: ASN1 definitions
1113 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1115 * Search the structure that is defined just after an OID definition.
1117 * Returns: %NULL when @oidValue not found, otherwise the pointer to a
1118 * constant string that contains the element name defined just after
1122 asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1124 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1];
1125 char value[ASN1_MAX_NAME_SIZE];
1128 asn1_retCode result;
1130 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1131 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1134 strcpy (definitionsName, definitions->name);
1135 strcat (definitionsName, ".");
1137 /* search the OBJECT_ID into definitions */
1138 p = definitions->down;
1141 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1142 (p->type & CONST_ASSIGN))
1144 strcpy (name, definitionsName);
1145 strcat (name, p->name);
1147 len = ASN1_MAX_NAME_SIZE;
1148 result = asn1_read_value (definitions, name, value, &len);
1150 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1153 if (p == NULL) /* reach the end of ASN1 definitions */
1154 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1162 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1167 * @dst: Destination ASN1_TYPE node.
1168 * @dst_name: Field name in destination node.
1169 * @src: Source ASN1_TYPE node.
1170 * @src_name: Field name in source node.
1172 * Create a deep copy of a ASN1_TYPE variable.
1174 * Return value: Return %ASN1_SUCCESS on success.
1177 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1178 ASN1_TYPE src, const char *src_name)
1180 /* FIXME: rewrite using copy_structure().
1181 * It seems quite hard to do.
1188 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1189 if (result != ASN1_MEM_ERROR)
1192 data = _asn1_malloc (size);
1194 return ASN1_MEM_ERROR;
1196 result = asn1_der_coding (src, src_name, data, &size, NULL);
1197 if (result != ASN1_SUCCESS)
1203 dst_node = asn1_find_node (dst, dst_name);
1204 if (dst_node == NULL)
1207 return ASN1_ELEMENT_NOT_FOUND;
1210 result = asn1_der_decoding (&dst_node, data, size, NULL);