Update gnulib files.
[libtasn1.git] / lib / structure.c
blob743e9ba42a9af0e917007a0e1f8d5b123cc1b779
1 /*
2 * Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
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
20 * 02110-1301, USA
24 /*****************************************************/
25 /* File: structure.c */
26 /* Description: Functions to create and delete an */
27 /* ASN1 tree. */
28 /*****************************************************/
31 #include <int.h>
32 #include <errors.h>
33 #include <structure.h>
34 #include "parser_aux.h"
35 #include <gstr.h>
38 extern char _asn1_identifierMissing[];
41 /******************************************************/
42 /* Function : _asn1_add_node_only */
43 /* Description: creates a new NODE_ASN element. */
44 /* Parameters: */
45 /* type: type of the new element (see TYPE_ */
46 /* and CONST_ constants). */
47 /* Return: pointer to the new element. */
48 /******************************************************/
49 node_asn *
50 _asn1_add_node_only (unsigned int type)
52 node_asn *punt;
54 punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn));
55 if (punt == NULL)
56 return NULL;
58 punt->type = type;
60 return punt;
64 /******************************************************************/
65 /* Function : _asn1_find_left */
66 /* Description: returns the NODE_ASN element with RIGHT field that*/
67 /* points the element NODE. */
68 /* Parameters: */
69 /* node: NODE_ASN element pointer. */
70 /* Return: NULL if not found. */
71 /******************************************************************/
72 node_asn *
73 _asn1_find_left (node_asn * node)
75 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
76 return NULL;
78 return node->left;
82 asn1_retCode
83 _asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
84 char *vector_name)
86 FILE *file;
87 node_asn *p;
88 unsigned long t;
90 file = fopen (output_file_name, "w");
92 if (file == NULL)
93 return ASN1_FILE_NOT_FOUND;
95 fprintf (file, "#if HAVE_CONFIG_H\n");
96 fprintf (file, "# include \"config.h\"\n");
97 fprintf (file, "#endif\n\n");
99 fprintf (file, "#include <libtasn1.h>\n\n");
101 fprintf (file, "const ASN1_ARRAY_TYPE %s[] = {\n", vector_name);
103 p = pointer;
105 while (p)
107 fprintf (file, " { ");
109 if (p->name)
110 fprintf (file, "\"%s\", ", p->name);
111 else
112 fprintf (file, "NULL, ");
114 t = p->type;
115 if (p->down)
116 t |= CONST_DOWN;
117 if (p->right)
118 t |= CONST_RIGHT;
120 fprintf (file, "%lu, ", t);
122 if (p->value)
123 fprintf (file, "\"%s\"},\n", p->value);
124 else
125 fprintf (file, "NULL },\n");
127 if (p->down)
129 p = p->down;
131 else if (p->right)
133 p = p->right;
135 else
137 while (1)
139 p = _asn1_find_up (p);
140 if (p == pointer)
142 p = NULL;
143 break;
145 if (p->right)
147 p = p->right;
148 break;
154 fprintf (file, " { NULL, 0, NULL }\n};\n");
156 fclose (file);
158 return ASN1_SUCCESS;
163 * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions.
164 * @array: specify the array that contains ASN.1 declarations
165 * @definitions: return the pointer to the structure created by
166 * *ARRAY ASN.1 declarations
167 * @errorDescription: return the error description.
169 * Creates the structures needed to manage the ASN.1 definitions.
170 * @array is a vector created by asn1_parser2array().
172 * Returns:
174 * ASN1_SUCCESS: Structure created correctly.
176 * ASN1_ELEMENT_NOT_EMPTY: *@definitions not ASN1_TYPE_EMPTY.
178 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
179 * is not defined (see @errorDescription for more information).
181 * ASN1_ARRAY_ERROR: The array pointed by @array is wrong.
183 asn1_retCode
184 asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
185 char *errorDescription)
187 node_asn *p, *p_last = NULL;
188 unsigned long k;
189 int move;
190 asn1_retCode result;
193 if (*definitions != ASN1_TYPE_EMPTY)
194 return ASN1_ELEMENT_NOT_EMPTY;
196 move = UP;
198 k = 0;
199 while (array[k].value || array[k].type || array[k].name)
201 p = _asn1_add_node (array[k].type & (~CONST_DOWN));
202 if (array[k].name)
203 _asn1_set_name (p, array[k].name);
204 if (array[k].value)
205 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
207 if (*definitions == NULL)
208 *definitions = p;
210 if (move == DOWN)
211 _asn1_set_down (p_last, p);
212 else if (move == RIGHT)
213 _asn1_set_right (p_last, p);
215 p_last = p;
217 if (array[k].type & CONST_DOWN)
218 move = DOWN;
219 else if (array[k].type & CONST_RIGHT)
220 move = RIGHT;
221 else
223 while (1)
225 if (p_last == *definitions)
226 break;
228 p_last = _asn1_find_up (p_last);
230 if (p_last == NULL)
231 break;
233 if (p_last->type & CONST_RIGHT)
235 p_last->type &= ~CONST_RIGHT;
236 move = RIGHT;
237 break;
239 } /* while */
241 k++;
242 } /* while */
244 if (p_last == *definitions)
246 result = _asn1_check_identifier (*definitions);
247 if (result == ASN1_SUCCESS)
249 _asn1_change_integer_value (*definitions);
250 _asn1_expand_object_id (*definitions);
253 else
255 result = ASN1_ARRAY_ERROR;
258 if (errorDescription != NULL)
260 if (result == ASN1_IDENTIFIER_NOT_FOUND)
262 Estrcpy (errorDescription, ":: identifier '");
263 Estrcat (errorDescription, _asn1_identifierMissing);
264 Estrcat (errorDescription, "' not found");
266 else
267 errorDescription[0] = 0;
270 if (result != ASN1_SUCCESS)
272 _asn1_delete_list_and_nodes ();
273 *definitions = ASN1_TYPE_EMPTY;
275 else
276 _asn1_delete_list ();
278 return result;
282 * asn1_delete_structure - Deletes the structure pointed by *ROOT.
283 * @structure: pointer to the structure that you want to delete.
285 * Deletes the structure *@structure. At the end, *@structure is set
286 * to ASN1_TYPE_EMPTY.
288 * Returns:
290 * ASN1_SUCCESS: Everything OK.
292 * ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY.
295 asn1_retCode
296 asn1_delete_structure (ASN1_TYPE * structure)
298 node_asn *p, *p2, *p3;
300 if (*structure == ASN1_TYPE_EMPTY)
301 return ASN1_ELEMENT_NOT_FOUND;
303 p = *structure;
304 while (p)
306 if (p->down)
308 p = p->down;
310 else
311 { /* no down */
312 p2 = p->right;
313 if (p != *structure)
315 p3 = _asn1_find_up (p);
316 _asn1_set_down (p3, p2);
317 _asn1_remove_node (p);
318 p = p3;
320 else
321 { /* p==root */
322 p3 = _asn1_find_left (p);
323 if (!p3)
325 p3 = _asn1_find_up (p);
326 if (p3)
327 _asn1_set_down (p3, p2);
328 else
330 if (p->right)
331 p->right->left = NULL;
334 else
335 _asn1_set_right (p3, p2);
336 _asn1_remove_node (p);
337 p = NULL;
342 *structure = ASN1_TYPE_EMPTY;
343 return ASN1_SUCCESS;
349 * asn1_delete_element - Deletes the element of a structure.
350 * @structure: pointer to the structure that contains the element you
351 * want to delete.
352 * @element_name: element's name you want to delete.
354 * Deletes the element named *@element_name inside *@structure.
356 * Returns:
358 * ASN1_SUCCESS: Everything OK.
360 * ASN1_ELEMENT_NOT_FOUND: The name element was not found.
363 asn1_retCode
364 asn1_delete_element (ASN1_TYPE structure, const char *element_name)
366 node_asn *p2, *p3, *source_node;
368 source_node = asn1_find_node (structure, element_name);
370 if (source_node == ASN1_TYPE_EMPTY)
371 return ASN1_ELEMENT_NOT_FOUND;
373 p2 = source_node->right;
374 p3 = _asn1_find_left (source_node);
375 if (!p3)
377 p3 = _asn1_find_up (source_node);
378 if (p3)
379 _asn1_set_down (p3, p2);
380 else if (source_node->right)
381 source_node->right->left = NULL;
383 else
384 _asn1_set_right (p3, p2);
386 return asn1_delete_structure (&source_node);
389 node_asn *
390 _asn1_copy_structure3 (node_asn * source_node)
392 node_asn *dest_node, *p_s, *p_d, *p_d_prev;
393 int move;
395 if (source_node == NULL)
396 return NULL;
398 dest_node = _asn1_add_node_only (source_node->type);
400 p_s = source_node;
401 p_d = dest_node;
403 move = DOWN;
407 if (move != UP)
409 if (p_s->name)
410 _asn1_set_name (p_d, p_s->name);
411 if (p_s->value)
412 _asn1_set_value (p_d, p_s->value, p_s->value_len);
413 move = DOWN;
415 else
416 move = RIGHT;
418 if (move == DOWN)
420 if (p_s->down)
422 p_s = p_s->down;
423 p_d_prev = p_d;
424 p_d = _asn1_add_node_only (p_s->type);
425 _asn1_set_down (p_d_prev, p_d);
427 else
428 move = RIGHT;
431 if (p_s == source_node)
432 break;
434 if (move == RIGHT)
436 if (p_s->right)
438 p_s = p_s->right;
439 p_d_prev = p_d;
440 p_d = _asn1_add_node_only (p_s->type);
441 _asn1_set_right (p_d_prev, p_d);
443 else
444 move = UP;
446 if (move == UP)
448 p_s = _asn1_find_up (p_s);
449 p_d = _asn1_find_up (p_d);
452 while (p_s != source_node);
454 return dest_node;
458 node_asn *
459 _asn1_copy_structure2 (node_asn * root, const char *source_name)
461 node_asn *source_node;
463 source_node = asn1_find_node (root, source_name);
465 return _asn1_copy_structure3 (source_node);
470 asn1_retCode
471 _asn1_type_choice_config (node_asn * node)
473 node_asn *p, *p2, *p3, *p4;
474 int move, tlen;
476 if (node == NULL)
477 return ASN1_ELEMENT_NOT_FOUND;
479 p = node;
480 move = DOWN;
482 while (!((p == node) && (move == UP)))
484 if (move != UP)
486 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
488 p2 = p->down;
489 while (p2)
491 if (type_field (p2->type) != TYPE_TAG)
493 p2->type |= CONST_TAG;
494 p3 = _asn1_find_left (p2);
495 while (p3)
497 if (type_field (p3->type) == TYPE_TAG)
499 p4 = _asn1_add_node_only (p3->type);
500 tlen = strlen (p3->value);
501 if (tlen > 0)
502 _asn1_set_value (p4, p3->value, tlen + 1);
503 _asn1_set_right (p4, p2->down);
504 _asn1_set_down (p2, p4);
506 p3 = _asn1_find_left (p3);
509 p2 = p2->right;
511 p->type &= ~(CONST_TAG);
512 p2 = p->down;
513 while (p2)
515 p3 = p2->right;
516 if (type_field (p2->type) == TYPE_TAG)
517 asn1_delete_structure (&p2);
518 p2 = p3;
521 move = DOWN;
523 else
524 move = RIGHT;
526 if (move == DOWN)
528 if (p->down)
529 p = p->down;
530 else
531 move = RIGHT;
534 if (p == node)
536 move = UP;
537 continue;
540 if (move == RIGHT)
542 if (p->right)
543 p = p->right;
544 else
545 move = UP;
547 if (move == UP)
548 p = _asn1_find_up (p);
551 return ASN1_SUCCESS;
555 asn1_retCode
556 _asn1_expand_identifier (node_asn ** node, node_asn * root)
558 node_asn *p, *p2, *p3;
559 char name2[MAX_NAME_SIZE + 2];
560 int move;
562 if (node == NULL)
563 return ASN1_ELEMENT_NOT_FOUND;
565 p = *node;
566 move = DOWN;
568 while (!((p == *node) && (move == UP)))
570 if (move != UP)
572 if (type_field (p->type) == TYPE_IDENTIFIER)
574 _asn1_str_cpy (name2, sizeof (name2), root->name);
575 _asn1_str_cat (name2, sizeof (name2), ".");
576 _asn1_str_cat (name2, sizeof (name2), p->value);
577 p2 = _asn1_copy_structure2 (root, name2);
578 if (p2 == NULL)
580 return ASN1_IDENTIFIER_NOT_FOUND;
582 _asn1_set_name (p2, p->name);
583 p2->right = p->right;
584 p2->left = p->left;
585 if (p->right)
586 p->right->left = p2;
587 p3 = p->down;
588 if (p3)
590 while (p3->right)
591 p3 = p3->right;
592 _asn1_set_right (p3, p2->down);
593 _asn1_set_down (p2, p->down);
596 p3 = _asn1_find_left (p);
597 if (p3)
598 _asn1_set_right (p3, p2);
599 else
601 p3 = _asn1_find_up (p);
602 if (p3)
603 _asn1_set_down (p3, p2);
604 else
606 p2->left = NULL;
610 if (p->type & CONST_SIZE)
611 p2->type |= CONST_SIZE;
612 if (p->type & CONST_TAG)
613 p2->type |= CONST_TAG;
614 if (p->type & CONST_OPTION)
615 p2->type |= CONST_OPTION;
616 if (p->type & CONST_DEFAULT)
617 p2->type |= CONST_DEFAULT;
618 if (p->type & CONST_SET)
619 p2->type |= CONST_SET;
620 if (p->type & CONST_NOT_USED)
621 p2->type |= CONST_NOT_USED;
623 if (p == *node)
624 *node = p2;
625 _asn1_remove_node (p);
626 p = p2;
627 move = DOWN;
628 continue;
630 move = DOWN;
632 else
633 move = RIGHT;
635 if (move == DOWN)
637 if (p->down)
638 p = p->down;
639 else
640 move = RIGHT;
643 if (p == *node)
645 move = UP;
646 continue;
649 if (move == RIGHT)
651 if (p->right)
652 p = p->right;
653 else
654 move = UP;
656 if (move == UP)
657 p = _asn1_find_up (p);
660 return ASN1_SUCCESS;
665 * asn1_create_element - Creates a structure of type SOURCE_NAME.
666 * @definitions: pointer to the structure returned by "parser_asn1" function
667 * @source_name: the name of the type of the new structure (must be
668 * inside p_structure).
669 * @element: pointer to the structure created.
671 * Creates a structure of type @source_name. Example using
672 * "pkix.asn":
674 * rc = asn1_create_structure(cert_def, "PKIX1.Certificate",
675 * certptr);
677 * Returns:
679 * ASN1_SUCCESS: Creation OK.
681 * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
683 asn1_retCode
684 asn1_create_element (ASN1_TYPE definitions, const char *source_name,
685 ASN1_TYPE * element)
687 node_asn *dest_node;
688 int res;
690 dest_node = _asn1_copy_structure2 (definitions, source_name);
692 if (dest_node == NULL)
693 return ASN1_ELEMENT_NOT_FOUND;
695 _asn1_set_name (dest_node, "");
697 res = _asn1_expand_identifier (&dest_node, definitions);
698 _asn1_type_choice_config (dest_node);
700 *element = dest_node;
702 return res;
707 * asn1_print_structure - Prints on the standard output the structure's tree
708 * @out: pointer to the output file (e.g. stdout).
709 * @structure: pointer to the structure that you want to visit.
710 * @name: an element of the structure
711 * @mode: specify how much of the structure to print, can be
712 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
713 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
715 * Prints on the @out file descriptor the structure's tree starting
716 * from the @name element inside the structure @structure.
718 void
719 asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
720 int mode)
722 node_asn *p, *root;
723 int k, indent = 0, len, len2, len3;
725 if (out == NULL)
726 return;
728 root = asn1_find_node (structure, name);
730 if (root == NULL)
731 return;
733 p = root;
734 while (p)
736 if (mode == ASN1_PRINT_ALL)
738 for (k = 0; k < indent; k++)
739 fprintf (out, " ");
740 fprintf (out, "name:");
741 if (p->name)
742 fprintf (out, "%s ", p->name);
743 else
744 fprintf (out, "NULL ");
746 else
748 switch (type_field (p->type))
750 case TYPE_CONSTANT:
751 case TYPE_TAG:
752 case TYPE_SIZE:
753 break;
754 default:
755 for (k = 0; k < indent; k++)
756 fprintf (out, " ");
757 fprintf (out, "name:");
758 if (p->name)
759 fprintf (out, "%s ", p->name);
760 else
761 fprintf (out, "NULL ");
765 if (mode != ASN1_PRINT_NAME)
767 switch (type_field (p->type))
769 case TYPE_CONSTANT:
770 if (mode == ASN1_PRINT_ALL)
771 fprintf (out, "type:CONST");
772 break;
773 case TYPE_TAG:
774 if (mode == ASN1_PRINT_ALL)
775 fprintf (out, "type:TAG");
776 break;
777 case TYPE_SIZE:
778 if (mode == ASN1_PRINT_ALL)
779 fprintf (out, "type:SIZE");
780 break;
781 case TYPE_DEFAULT:
782 fprintf (out, "type:DEFAULT");
783 break;
784 case TYPE_NULL:
785 fprintf (out, "type:NULL");
786 break;
787 case TYPE_IDENTIFIER:
788 fprintf (out, "type:IDENTIFIER");
789 break;
790 case TYPE_INTEGER:
791 fprintf (out, "type:INTEGER");
792 break;
793 case TYPE_ENUMERATED:
794 fprintf (out, "type:ENUMERATED");
795 break;
796 case TYPE_TIME:
797 fprintf (out, "type:TIME");
798 break;
799 case TYPE_BOOLEAN:
800 fprintf (out, "type:BOOLEAN");
801 break;
802 case TYPE_SEQUENCE:
803 fprintf (out, "type:SEQUENCE");
804 break;
805 case TYPE_BIT_STRING:
806 fprintf (out, "type:BIT_STR");
807 break;
808 case TYPE_OCTET_STRING:
809 fprintf (out, "type:OCT_STR");
810 break;
811 case TYPE_GENERALSTRING:
812 fprintf (out, "type:GENERALSTRING");
813 break;
814 case TYPE_SEQUENCE_OF:
815 fprintf (out, "type:SEQ_OF");
816 break;
817 case TYPE_OBJECT_ID:
818 fprintf (out, "type:OBJ_ID");
819 break;
820 case TYPE_ANY:
821 fprintf (out, "type:ANY");
822 break;
823 case TYPE_SET:
824 fprintf (out, "type:SET");
825 break;
826 case TYPE_SET_OF:
827 fprintf (out, "type:SET_OF");
828 break;
829 case TYPE_CHOICE:
830 fprintf (out, "type:CHOICE");
831 break;
832 case TYPE_DEFINITIONS:
833 fprintf (out, "type:DEFINITIONS");
834 break;
835 default:
836 break;
840 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
842 switch (type_field (p->type))
844 case TYPE_CONSTANT:
845 if (mode == ASN1_PRINT_ALL)
846 if (p->value)
847 fprintf (out, " value:%s", p->value);
848 break;
849 case TYPE_TAG:
850 if (mode == ASN1_PRINT_ALL)
851 if (p->value)
852 fprintf (out, " value:%s", p->value);
853 break;
854 case TYPE_SIZE:
855 if (mode == ASN1_PRINT_ALL)
856 if (p->value)
857 fprintf (out, " value:%s", p->value);
858 break;
859 case TYPE_DEFAULT:
860 if (p->value)
861 fprintf (out, " value:%s", p->value);
862 else if (p->type & CONST_TRUE)
863 fprintf (out, " value:TRUE");
864 else if (p->type & CONST_FALSE)
865 fprintf (out, " value:FALSE");
866 break;
867 case TYPE_IDENTIFIER:
868 if (p->value)
869 fprintf (out, " value:%s", p->value);
870 break;
871 case TYPE_INTEGER:
872 if (p->value)
874 len2 = -1;
875 len = asn1_get_length_der (p->value, p->value_len, &len2);
876 fprintf (out, " value:0x");
877 if (len > 0)
878 for (k = 0; k < len; k++)
879 fprintf (out, "%02x", (p->value)[k + len2]);
881 break;
882 case TYPE_ENUMERATED:
883 if (p->value)
885 len2 = -1;
886 len = asn1_get_length_der (p->value, p->value_len, &len2);
887 fprintf (out, " value:0x");
888 if (len > 0)
889 for (k = 0; k < len; k++)
890 fprintf (out, "%02x", (p->value)[k + len2]);
892 break;
893 case TYPE_TIME:
894 if (p->value)
895 fprintf (out, " value:%s", p->value);
896 break;
897 case TYPE_BOOLEAN:
898 if (p->value)
900 if (p->value[0] == 'T')
901 fprintf (out, " value:TRUE");
902 else if (p->value[0] == 'F')
903 fprintf (out, " value:FALSE");
905 break;
906 case TYPE_BIT_STRING:
907 if (p->value)
909 len2 = -1;
910 len = asn1_get_length_der (p->value, p->value_len, &len2);
911 if (len > 0)
913 fprintf (out, " value(%i):",
914 (len - 1) * 8 - (p->value[len2]));
915 for (k = 1; k < len; k++)
916 fprintf (out, "%02x", (p->value)[k + len2]);
919 break;
920 case TYPE_OCTET_STRING:
921 if (p->value)
923 len2 = -1;
924 len = asn1_get_length_der (p->value, p->value_len, &len2);
925 fprintf (out, " value:");
926 if (len > 0)
927 for (k = 0; k < len; k++)
928 fprintf (out, "%02x", (p->value)[k + len2]);
930 break;
931 case TYPE_GENERALSTRING:
932 if (p->value)
934 len2 = -1;
935 len = asn1_get_length_der (p->value, p->value_len, &len2);
936 fprintf (out, " value:");
937 if (len > 0)
938 for (k = 0; k < len; k++)
939 fprintf (out, "%02x", (p->value)[k + len2]);
941 break;
942 case TYPE_OBJECT_ID:
943 if (p->value)
944 fprintf (out, " value:%s", p->value);
945 break;
946 case TYPE_ANY:
947 if (p->value)
949 len3 = -1;
950 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
951 fprintf (out, " value:");
952 if (len2 > 0)
953 for (k = 0; k < len2; k++)
954 fprintf (out, "%02x", (p->value)[k + len3]);
956 break;
957 case TYPE_SET:
958 case TYPE_SET_OF:
959 case TYPE_CHOICE:
960 case TYPE_DEFINITIONS:
961 case TYPE_SEQUENCE_OF:
962 case TYPE_SEQUENCE:
963 case TYPE_NULL:
964 break;
965 default:
966 break;
970 if (mode == ASN1_PRINT_ALL)
972 if (p->type & 0x1FFFFF00)
974 fprintf (out, " attr:");
975 if (p->type & CONST_UNIVERSAL)
976 fprintf (out, "UNIVERSAL,");
977 if (p->type & CONST_PRIVATE)
978 fprintf (out, "PRIVATE,");
979 if (p->type & CONST_APPLICATION)
980 fprintf (out, "APPLICATION,");
981 if (p->type & CONST_EXPLICIT)
982 fprintf (out, "EXPLICIT,");
983 if (p->type & CONST_IMPLICIT)
984 fprintf (out, "IMPLICIT,");
985 if (p->type & CONST_TAG)
986 fprintf (out, "TAG,");
987 if (p->type & CONST_DEFAULT)
988 fprintf (out, "DEFAULT,");
989 if (p->type & CONST_TRUE)
990 fprintf (out, "TRUE,");
991 if (p->type & CONST_FALSE)
992 fprintf (out, "FALSE,");
993 if (p->type & CONST_LIST)
994 fprintf (out, "LIST,");
995 if (p->type & CONST_MIN_MAX)
996 fprintf (out, "MIN_MAX,");
997 if (p->type & CONST_OPTION)
998 fprintf (out, "OPTION,");
999 if (p->type & CONST_1_PARAM)
1000 fprintf (out, "1_PARAM,");
1001 if (p->type & CONST_SIZE)
1002 fprintf (out, "SIZE,");
1003 if (p->type & CONST_DEFINED_BY)
1004 fprintf (out, "DEF_BY,");
1005 if (p->type & CONST_GENERALIZED)
1006 fprintf (out, "GENERALIZED,");
1007 if (p->type & CONST_UTC)
1008 fprintf (out, "UTC,");
1009 if (p->type & CONST_SET)
1010 fprintf (out, "SET,");
1011 if (p->type & CONST_NOT_USED)
1012 fprintf (out, "NOT_USED,");
1013 if (p->type & CONST_ASSIGN)
1014 fprintf (out, "ASSIGNMENT,");
1018 if (mode == ASN1_PRINT_ALL)
1020 fprintf (out, "\n");
1022 else
1024 switch (type_field (p->type))
1026 case TYPE_CONSTANT:
1027 case TYPE_TAG:
1028 case TYPE_SIZE:
1029 break;
1030 default:
1031 fprintf (out, "\n");
1035 if (p->down)
1037 p = p->down;
1038 indent += 2;
1040 else if (p == root)
1042 p = NULL;
1043 break;
1045 else if (p->right)
1046 p = p->right;
1047 else
1049 while (1)
1051 p = _asn1_find_up (p);
1052 if (p == root)
1054 p = NULL;
1055 break;
1057 indent -= 2;
1058 if (p->right)
1060 p = p->right;
1061 break;
1071 * asn1_number_of_elements - Counts the number of elements of a structure.
1072 * @element: pointer to the root of an ASN1 structure.
1073 * @name: the name of a sub-structure of ROOT.
1074 * @num: pointer to an integer where the result will be stored
1076 * Counts the number of elements of a sub-structure called NAME with
1077 * names equal to "?1","?2", ...
1079 * Returns:
1081 * ASN1_SUCCESS: Creation OK.
1083 * ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
1085 * ASN1_GENERIC_ERROR: Pointer num equal to NULL.
1088 asn1_retCode
1089 asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1091 node_asn *node, *p;
1093 if (num == NULL)
1094 return ASN1_GENERIC_ERROR;
1096 *num = 0;
1098 node = asn1_find_node (element, name);
1099 if (node == NULL)
1100 return ASN1_ELEMENT_NOT_FOUND;
1102 p = node->down;
1104 while (p)
1106 if ((p->name) && (p->name[0] == '?'))
1107 (*num)++;
1108 p = p->right;
1111 return ASN1_SUCCESS;
1116 * asn1_find_structure_from_oid - Locate structure defined by a specific OID.
1117 * @definitions: ASN1 definitions
1118 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1120 * Search the structure that is defined just after an OID definition.
1122 * Returns: NULL when OIDVALUE not found, otherwise the pointer to a
1123 * constant string that contains the element name defined just
1124 * after the OID.
1127 const char *
1128 asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1130 char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1];
1131 char value[MAX_NAME_SIZE];
1132 ASN1_TYPE p;
1133 int len;
1134 asn1_retCode result;
1136 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1137 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1140 strcpy (definitionsName, definitions->name);
1141 strcat (definitionsName, ".");
1143 /* search the OBJECT_ID into definitions */
1144 p = definitions->down;
1145 while (p)
1147 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1148 (p->type & CONST_ASSIGN))
1150 strcpy (name, definitionsName);
1151 strcat (name, p->name);
1153 len = MAX_NAME_SIZE;
1154 result = asn1_read_value (definitions, name, value, &len);
1156 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1158 p = p->right;
1159 if (p == NULL) /* reach the end of ASN1 definitions */
1160 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1162 return p->name;
1165 p = p->right;
1168 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1172 * asn1_copy_node:
1173 * @dst: Destination ASN1_TYPE node.
1174 * @dst_name: Field name in destination node.
1175 * @src: Source ASN1_TYPE node.
1176 * @src_name: Field name in source node.
1178 * Create a deep copy of a ASN1_TYPE variable.
1180 * Return value: Return ASN1_SUCCESS on success.
1182 asn1_retCode
1183 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1184 ASN1_TYPE src, const char *src_name)
1186 /* FIXME: rewrite using copy_structure().
1187 * It seems quite hard to do.
1189 int result;
1190 ASN1_TYPE dst_node;
1191 void *data = NULL;
1192 int size = 0;
1194 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1195 if (result != ASN1_MEM_ERROR)
1196 return result;
1198 data = _asn1_malloc (size);
1199 if (data == NULL)
1200 return ASN1_MEM_ERROR;
1202 result = asn1_der_coding (src, src_name, data, &size, NULL);
1203 if (result != ASN1_SUCCESS)
1205 _asn1_free (data);
1206 return result;
1209 dst_node = asn1_find_node (dst, dst_name);
1210 if (dst_node == NULL)
1212 _asn1_free (data);
1213 return ASN1_ELEMENT_NOT_FOUND;
1216 result = asn1_der_decoding (&dst_node, data, size, NULL);
1218 _asn1_free (data);
1220 return result;