Update.
[libtasn1.git] / lib / structure.c
blob4b2ee5099e3bcb7f917c423f2d13a7bdc7d9a3dd
1 /*
2 * Copyright (C) 2004, 2006 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, "\n#include <libtasn1.h>\n\n");
96 fprintf (file, "extern const ASN1_ARRAY_TYPE %s[]={\n", vector_name);
98 p = pointer;
100 while (p)
102 fprintf (file, " {");
104 if (p->name)
105 fprintf (file, "\"%s\",", p->name);
106 else
107 fprintf (file, "0,");
109 t = p->type;
110 if (p->down)
111 t |= CONST_DOWN;
112 if (p->right)
113 t |= CONST_RIGHT;
115 fprintf (file, "%lu,", t);
117 if (p->value)
118 fprintf (file, "\"%s\"},\n", p->value);
119 else
120 fprintf (file, "0},\n");
122 if (p->down)
124 p = p->down;
126 else if (p->right)
128 p = p->right;
130 else
132 while (1)
134 p = _asn1_find_up (p);
135 if (p == pointer)
137 p = NULL;
138 break;
140 if (p->right)
142 p = p->right;
143 break;
149 fprintf (file, " {0,0,0}\n};\n");
151 fclose (file);
153 return ASN1_SUCCESS;
158 * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions.
159 * @array: specify the array that contains ASN.1 declarations
160 * @definitions: return the pointer to the structure created by
161 * *ARRAY ASN.1 declarations
162 * @errorDescription: return the error description.
164 * Creates the structures needed to manage the ASN.1 definitions.
165 * @array is a vector created by asn1_parser2array().
167 * Returns:
169 * ASN1_SUCCESS: Structure created correctly.
171 * ASN1_ELEMENT_NOT_EMPTY: *@definitions not ASN1_TYPE_EMPTY.
173 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
174 * is not defined (see @errorDescription for more information).
176 * ASN1_ARRAY_ERROR: The array pointed by @array is wrong.
178 asn1_retCode
179 asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
180 char *errorDescription)
182 node_asn *p, *p_last = NULL;
183 unsigned long k;
184 int move;
185 asn1_retCode result;
188 if (*definitions != ASN1_TYPE_EMPTY)
189 return ASN1_ELEMENT_NOT_EMPTY;
191 move = UP;
193 k = 0;
194 while (array[k].value || array[k].type || array[k].name)
196 p = _asn1_add_node (array[k].type & (~CONST_DOWN));
197 if (array[k].name)
198 _asn1_set_name (p, array[k].name);
199 if (array[k].value)
200 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
202 if (*definitions == NULL)
203 *definitions = p;
205 if (move == DOWN)
206 _asn1_set_down (p_last, p);
207 else if (move == RIGHT)
208 _asn1_set_right (p_last, p);
210 p_last = p;
212 if (array[k].type & CONST_DOWN)
213 move = DOWN;
214 else if (array[k].type & CONST_RIGHT)
215 move = RIGHT;
216 else
218 while (1)
220 if (p_last == *definitions)
221 break;
223 p_last = _asn1_find_up (p_last);
225 if (p_last == NULL)
226 break;
228 if (p_last->type & CONST_RIGHT)
230 p_last->type &= ~CONST_RIGHT;
231 move = RIGHT;
232 break;
234 } /* while */
236 k++;
237 } /* while */
239 if (p_last == *definitions)
241 result = _asn1_check_identifier (*definitions);
242 if (result == ASN1_SUCCESS)
244 _asn1_change_integer_value (*definitions);
245 _asn1_expand_object_id (*definitions);
248 else
250 result = ASN1_ARRAY_ERROR;
253 if (errorDescription != NULL)
255 if (result == ASN1_IDENTIFIER_NOT_FOUND)
257 Estrcpy (errorDescription, ":: identifier '");
258 Estrcat (errorDescription, _asn1_identifierMissing);
259 Estrcat (errorDescription, "' not found");
261 else
262 errorDescription[0] = 0;
265 if (result != ASN1_SUCCESS)
267 _asn1_delete_list_and_nodes ();
268 *definitions = ASN1_TYPE_EMPTY;
270 else
271 _asn1_delete_list ();
273 return result;
277 * asn1_delete_structure - Deletes the structure pointed by *ROOT.
278 * @structure: pointer to the structure that you want to delete.
280 * Deletes the structure *@structure. At the end, *@structure is set
281 * to ASN1_TYPE_EMPTY.
283 * Returns:
285 * ASN1_SUCCESS: Everything OK.
287 * ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY.
290 asn1_retCode
291 asn1_delete_structure (ASN1_TYPE * structure)
293 node_asn *p, *p2, *p3;
295 if (*structure == ASN1_TYPE_EMPTY)
296 return ASN1_ELEMENT_NOT_FOUND;
298 p = *structure;
299 while (p)
301 if (p->down)
303 p = p->down;
305 else
306 { /* no down */
307 p2 = p->right;
308 if (p != *structure)
310 p3 = _asn1_find_up (p);
311 _asn1_set_down (p3, p2);
312 _asn1_remove_node (p);
313 p = p3;
315 else
316 { /* p==root */
317 p3 = _asn1_find_left (p);
318 if (!p3)
320 p3 = _asn1_find_up (p);
321 if (p3)
322 _asn1_set_down (p3, p2);
323 else
325 if (p->right)
326 p->right->left = NULL;
329 else
330 _asn1_set_right (p3, p2);
331 _asn1_remove_node (p);
332 p = NULL;
337 *structure = ASN1_TYPE_EMPTY;
338 return ASN1_SUCCESS;
344 * asn1_delete_element - Deletes the element of a structure.
345 * @structure: pointer to the structure that contains the element you
346 * want to delete.
347 * @element_name: element's name you want to delete.
349 * Deletes the element named *@element_name inside *@structure.
351 * Returns:
353 * ASN1_SUCCESS: Everything OK.
355 * ASN1_ELEMENT_NOT_FOUND: The name element was not found.
358 asn1_retCode
359 asn1_delete_element (ASN1_TYPE structure, const char *element_name)
361 node_asn *p2, *p3, *source_node;
363 source_node = asn1_find_node (structure, element_name);
365 if (source_node == ASN1_TYPE_EMPTY)
366 return ASN1_ELEMENT_NOT_FOUND;
368 p2 = source_node->right;
369 p3 = _asn1_find_left (source_node);
370 if (!p3)
372 p3 = _asn1_find_up (source_node);
373 if (p3)
374 _asn1_set_down (p3, p2);
375 else if (source_node->right)
376 source_node->right->left = NULL;
378 else
379 _asn1_set_right (p3, p2);
381 return asn1_delete_structure (&source_node);
384 node_asn *
385 _asn1_copy_structure3 (node_asn * source_node)
387 node_asn *dest_node, *p_s, *p_d, *p_d_prev;
388 int move;
390 if (source_node == NULL)
391 return NULL;
393 dest_node = _asn1_add_node_only (source_node->type);
395 p_s = source_node;
396 p_d = dest_node;
398 move = DOWN;
402 if (move != UP)
404 if (p_s->name)
405 _asn1_set_name (p_d, p_s->name);
406 if (p_s->value)
407 _asn1_set_value (p_d, p_s->value, p_s->value_len);
408 move = DOWN;
410 else
411 move = RIGHT;
413 if (move == DOWN)
415 if (p_s->down)
417 p_s = p_s->down;
418 p_d_prev = p_d;
419 p_d = _asn1_add_node_only (p_s->type);
420 _asn1_set_down (p_d_prev, p_d);
422 else
423 move = RIGHT;
426 if (p_s == source_node)
427 break;
429 if (move == RIGHT)
431 if (p_s->right)
433 p_s = p_s->right;
434 p_d_prev = p_d;
435 p_d = _asn1_add_node_only (p_s->type);
436 _asn1_set_right (p_d_prev, p_d);
438 else
439 move = UP;
441 if (move == UP)
443 p_s = _asn1_find_up (p_s);
444 p_d = _asn1_find_up (p_d);
447 while (p_s != source_node);
449 return dest_node;
453 node_asn *
454 _asn1_copy_structure2 (node_asn * root, const char *source_name)
456 node_asn *source_node;
458 source_node = asn1_find_node (root, source_name);
460 return _asn1_copy_structure3 (source_node);
465 asn1_retCode
466 _asn1_type_choice_config (node_asn * node)
468 node_asn *p, *p2, *p3, *p4;
469 int move, tlen;
471 if (node == NULL)
472 return ASN1_ELEMENT_NOT_FOUND;
474 p = node;
475 move = DOWN;
477 while (!((p == node) && (move == UP)))
479 if (move != UP)
481 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
483 p2 = p->down;
484 while (p2)
486 if (type_field (p2->type) != TYPE_TAG)
488 p2->type |= CONST_TAG;
489 p3 = _asn1_find_left (p2);
490 while (p3)
492 if (type_field (p3->type) == TYPE_TAG)
494 p4 = _asn1_add_node_only (p3->type);
495 tlen = strlen (p3->value);
496 if (tlen > 0)
497 _asn1_set_value (p4, p3->value, tlen + 1);
498 _asn1_set_right (p4, p2->down);
499 _asn1_set_down (p2, p4);
501 p3 = _asn1_find_left (p3);
504 p2 = p2->right;
506 p->type &= ~(CONST_TAG);
507 p2 = p->down;
508 while (p2)
510 p3 = p2->right;
511 if (type_field (p2->type) == TYPE_TAG)
512 asn1_delete_structure (&p2);
513 p2 = p3;
516 move = DOWN;
518 else
519 move = RIGHT;
521 if (move == DOWN)
523 if (p->down)
524 p = p->down;
525 else
526 move = RIGHT;
529 if (p == node)
531 move = UP;
532 continue;
535 if (move == RIGHT)
537 if (p->right)
538 p = p->right;
539 else
540 move = UP;
542 if (move == UP)
543 p = _asn1_find_up (p);
546 return ASN1_SUCCESS;
550 asn1_retCode
551 _asn1_expand_identifier (node_asn ** node, node_asn * root)
553 node_asn *p, *p2, *p3;
554 char name2[MAX_NAME_SIZE + 2];
555 int move;
557 if (node == NULL)
558 return ASN1_ELEMENT_NOT_FOUND;
560 p = *node;
561 move = DOWN;
563 while (!((p == *node) && (move == UP)))
565 if (move != UP)
567 if (type_field (p->type) == TYPE_IDENTIFIER)
569 _asn1_str_cpy (name2, sizeof (name2), root->name);
570 _asn1_str_cat (name2, sizeof (name2), ".");
571 _asn1_str_cat (name2, sizeof (name2), p->value);
572 p2 = _asn1_copy_structure2 (root, name2);
573 if (p2 == NULL)
575 return ASN1_IDENTIFIER_NOT_FOUND;
577 _asn1_set_name (p2, p->name);
578 p2->right = p->right;
579 p2->left = p->left;
580 if (p->right)
581 p->right->left = p2;
582 p3 = p->down;
583 if (p3)
585 while (p3->right)
586 p3 = p3->right;
587 _asn1_set_right (p3, p2->down);
588 _asn1_set_down (p2, p->down);
591 p3 = _asn1_find_left (p);
592 if (p3)
593 _asn1_set_right (p3, p2);
594 else
596 p3 = _asn1_find_up (p);
597 if (p3)
598 _asn1_set_down (p3, p2);
599 else
601 p2->left = NULL;
605 if (p->type & CONST_SIZE)
606 p2->type |= CONST_SIZE;
607 if (p->type & CONST_TAG)
608 p2->type |= CONST_TAG;
609 if (p->type & CONST_OPTION)
610 p2->type |= CONST_OPTION;
611 if (p->type & CONST_DEFAULT)
612 p2->type |= CONST_DEFAULT;
613 if (p->type & CONST_SET)
614 p2->type |= CONST_SET;
615 if (p->type & CONST_NOT_USED)
616 p2->type |= CONST_NOT_USED;
618 if (p == *node)
619 *node = p2;
620 _asn1_remove_node (p);
621 p = p2;
622 move = DOWN;
623 continue;
625 move = DOWN;
627 else
628 move = RIGHT;
630 if (move == DOWN)
632 if (p->down)
633 p = p->down;
634 else
635 move = RIGHT;
638 if (p == *node)
640 move = UP;
641 continue;
644 if (move == RIGHT)
646 if (p->right)
647 p = p->right;
648 else
649 move = UP;
651 if (move == UP)
652 p = _asn1_find_up (p);
655 return ASN1_SUCCESS;
660 * asn1_create_element - Creates a structure of type SOURCE_NAME.
661 * @definitions: pointer to the structure returned by "parser_asn1" function
662 * @source_name: the name of the type of the new structure (must be
663 * inside p_structure).
664 * @element: pointer to the structure created.
666 * Creates a structure of type @source_name. Example using
667 * "pkix.asn":
669 * rc = asn1_create_structure(cert_def, "PKIX1.Certificate",
670 * certptr);
672 * Returns:
674 * ASN1_SUCCESS: Creation OK.
676 * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
678 asn1_retCode
679 asn1_create_element (ASN1_TYPE definitions, const char *source_name,
680 ASN1_TYPE * element)
682 node_asn *dest_node;
683 int res;
685 dest_node = _asn1_copy_structure2 (definitions, source_name);
687 if (dest_node == NULL)
688 return ASN1_ELEMENT_NOT_FOUND;
690 _asn1_set_name (dest_node, "");
692 res = _asn1_expand_identifier (&dest_node, definitions);
693 _asn1_type_choice_config (dest_node);
695 *element = dest_node;
697 return res;
702 * asn1_print_structure - Prints on the standard output the structure's tree
703 * @out: pointer to the output file (e.g. stdout).
704 * @structure: pointer to the structure that you want to visit.
705 * @name: an element of the structure
706 * @mode: specify how much of the structure to print, can be
707 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
708 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
710 * Prints on the @out file descriptor the structure's tree starting
711 * from the @name element inside the structure @structure.
713 void
714 asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
715 int mode)
717 node_asn *p, *root;
718 int k, indent = 0, len, len2, len3;
720 if (out == NULL)
721 return;
723 root = asn1_find_node (structure, name);
725 if (root == NULL)
726 return;
728 p = root;
729 while (p)
731 if (mode == ASN1_PRINT_ALL)
733 for (k = 0; k < indent; k++)
734 fprintf (out, " ");
735 fprintf (out, "name:");
736 if (p->name)
737 fprintf (out, "%s ", p->name);
738 else
739 fprintf (out, "NULL ");
741 else
743 switch (type_field (p->type))
745 case TYPE_CONSTANT:
746 case TYPE_TAG:
747 case TYPE_SIZE:
748 break;
749 default:
750 for (k = 0; k < indent; k++)
751 fprintf (out, " ");
752 fprintf (out, "name:");
753 if (p->name)
754 fprintf (out, "%s ", p->name);
755 else
756 fprintf (out, "NULL ");
760 if (mode != ASN1_PRINT_NAME)
762 switch (type_field (p->type))
764 case TYPE_CONSTANT:
765 if (mode == ASN1_PRINT_ALL)
766 fprintf (out, "type:CONST");
767 break;
768 case TYPE_TAG:
769 if (mode == ASN1_PRINT_ALL)
770 fprintf (out, "type:TAG");
771 break;
772 case TYPE_SIZE:
773 if (mode == ASN1_PRINT_ALL)
774 fprintf (out, "type:SIZE");
775 break;
776 case TYPE_DEFAULT:
777 fprintf (out, "type:DEFAULT");
778 break;
779 case TYPE_NULL:
780 fprintf (out, "type:NULL");
781 break;
782 case TYPE_IDENTIFIER:
783 fprintf (out, "type:IDENTIFIER");
784 break;
785 case TYPE_INTEGER:
786 fprintf (out, "type:INTEGER");
787 break;
788 case TYPE_ENUMERATED:
789 fprintf (out, "type:ENUMERATED");
790 break;
791 case TYPE_TIME:
792 fprintf (out, "type:TIME");
793 break;
794 case TYPE_BOOLEAN:
795 fprintf (out, "type:BOOLEAN");
796 break;
797 case TYPE_SEQUENCE:
798 fprintf (out, "type:SEQUENCE");
799 break;
800 case TYPE_BIT_STRING:
801 fprintf (out, "type:BIT_STR");
802 break;
803 case TYPE_OCTET_STRING:
804 fprintf (out, "type:OCT_STR");
805 break;
806 case TYPE_GENERALSTRING:
807 fprintf (out, "type:GENERALSTRING");
808 break;
809 case TYPE_SEQUENCE_OF:
810 fprintf (out, "type:SEQ_OF");
811 break;
812 case TYPE_OBJECT_ID:
813 fprintf (out, "type:OBJ_ID");
814 break;
815 case TYPE_ANY:
816 fprintf (out, "type:ANY");
817 break;
818 case TYPE_SET:
819 fprintf (out, "type:SET");
820 break;
821 case TYPE_SET_OF:
822 fprintf (out, "type:SET_OF");
823 break;
824 case TYPE_CHOICE:
825 fprintf (out, "type:CHOICE");
826 break;
827 case TYPE_DEFINITIONS:
828 fprintf (out, "type:DEFINITIONS");
829 break;
830 default:
831 break;
835 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
837 switch (type_field (p->type))
839 case TYPE_CONSTANT:
840 if (mode == ASN1_PRINT_ALL)
841 if (p->value)
842 fprintf (out, " value:%s", p->value);
843 break;
844 case TYPE_TAG:
845 if (mode == ASN1_PRINT_ALL)
846 if (p->value)
847 fprintf (out, " value:%s", p->value);
848 break;
849 case TYPE_SIZE:
850 if (mode == ASN1_PRINT_ALL)
851 if (p->value)
852 fprintf (out, " value:%s", p->value);
853 break;
854 case TYPE_DEFAULT:
855 if (p->value)
856 fprintf (out, " value:%s", p->value);
857 else if (p->type & CONST_TRUE)
858 fprintf (out, " value:TRUE");
859 else if (p->type & CONST_FALSE)
860 fprintf (out, " value:FALSE");
861 break;
862 case TYPE_IDENTIFIER:
863 if (p->value)
864 fprintf (out, " value:%s", p->value);
865 break;
866 case TYPE_INTEGER:
867 if (p->value)
869 len2 = -1;
870 len = asn1_get_length_der (p->value, p->value_len, &len2);
871 fprintf (out, " value:0x");
872 if (len > 0)
873 for (k = 0; k < len; k++)
874 fprintf (out, "%02x", (p->value)[k + len2]);
876 break;
877 case TYPE_ENUMERATED:
878 if (p->value)
880 len2 = -1;
881 len = asn1_get_length_der (p->value, p->value_len, &len2);
882 fprintf (out, " value:0x");
883 if (len > 0)
884 for (k = 0; k < len; k++)
885 fprintf (out, "%02x", (p->value)[k + len2]);
887 break;
888 case TYPE_TIME:
889 if (p->value)
890 fprintf (out, " value:%s", p->value);
891 break;
892 case TYPE_BOOLEAN:
893 if (p->value)
895 if (p->value[0] == 'T')
896 fprintf (out, " value:TRUE");
897 else if (p->value[0] == 'F')
898 fprintf (out, " value:FALSE");
900 break;
901 case TYPE_BIT_STRING:
902 if (p->value)
904 len2 = -1;
905 len = asn1_get_length_der (p->value, p->value_len, &len2);
906 if (len > 0)
908 fprintf (out, " value(%i):",
909 (len - 1) * 8 - (p->value[len2]));
910 for (k = 1; k < len; k++)
911 fprintf (out, "%02x", (p->value)[k + len2]);
914 break;
915 case TYPE_OCTET_STRING:
916 if (p->value)
918 len2 = -1;
919 len = asn1_get_length_der (p->value, p->value_len, &len2);
920 fprintf (out, " value:");
921 if (len > 0)
922 for (k = 0; k < len; k++)
923 fprintf (out, "%02x", (p->value)[k + len2]);
925 break;
926 case TYPE_GENERALSTRING:
927 if (p->value)
929 len2 = -1;
930 len = asn1_get_length_der (p->value, p->value_len, &len2);
931 fprintf (out, " value:");
932 if (len > 0)
933 for (k = 0; k < len; k++)
934 fprintf (out, "%02x", (p->value)[k + len2]);
936 break;
937 case TYPE_OBJECT_ID:
938 if (p->value)
939 fprintf (out, " value:%s", p->value);
940 break;
941 case TYPE_ANY:
942 if (p->value)
944 len3 = -1;
945 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
946 fprintf (out, " value:");
947 if (len2 > 0)
948 for (k = 0; k < len2; k++)
949 fprintf (out, "%02x", (p->value)[k + len3]);
951 break;
952 case TYPE_SET:
953 case TYPE_SET_OF:
954 case TYPE_CHOICE:
955 case TYPE_DEFINITIONS:
956 case TYPE_SEQUENCE_OF:
957 case TYPE_SEQUENCE:
958 case TYPE_NULL:
959 break;
960 default:
961 break;
965 if (mode == ASN1_PRINT_ALL)
967 if (p->type & 0x1FFFFF00)
969 fprintf (out, " attr:");
970 if (p->type & CONST_UNIVERSAL)
971 fprintf (out, "UNIVERSAL,");
972 if (p->type & CONST_PRIVATE)
973 fprintf (out, "PRIVATE,");
974 if (p->type & CONST_APPLICATION)
975 fprintf (out, "APPLICATION,");
976 if (p->type & CONST_EXPLICIT)
977 fprintf (out, "EXPLICIT,");
978 if (p->type & CONST_IMPLICIT)
979 fprintf (out, "IMPLICIT,");
980 if (p->type & CONST_TAG)
981 fprintf (out, "TAG,");
982 if (p->type & CONST_DEFAULT)
983 fprintf (out, "DEFAULT,");
984 if (p->type & CONST_TRUE)
985 fprintf (out, "TRUE,");
986 if (p->type & CONST_FALSE)
987 fprintf (out, "FALSE,");
988 if (p->type & CONST_LIST)
989 fprintf (out, "LIST,");
990 if (p->type & CONST_MIN_MAX)
991 fprintf (out, "MIN_MAX,");
992 if (p->type & CONST_OPTION)
993 fprintf (out, "OPTION,");
994 if (p->type & CONST_1_PARAM)
995 fprintf (out, "1_PARAM,");
996 if (p->type & CONST_SIZE)
997 fprintf (out, "SIZE,");
998 if (p->type & CONST_DEFINED_BY)
999 fprintf (out, "DEF_BY,");
1000 if (p->type & CONST_GENERALIZED)
1001 fprintf (out, "GENERALIZED,");
1002 if (p->type & CONST_UTC)
1003 fprintf (out, "UTC,");
1004 if (p->type & CONST_SET)
1005 fprintf (out, "SET,");
1006 if (p->type & CONST_NOT_USED)
1007 fprintf (out, "NOT_USED,");
1008 if (p->type & CONST_ASSIGN)
1009 fprintf (out, "ASSIGNMENT,");
1013 if (mode == ASN1_PRINT_ALL)
1015 fprintf (out, "\n");
1017 else
1019 switch (type_field (p->type))
1021 case TYPE_CONSTANT:
1022 case TYPE_TAG:
1023 case TYPE_SIZE:
1024 break;
1025 default:
1026 fprintf (out, "\n");
1030 if (p->down)
1032 p = p->down;
1033 indent += 2;
1035 else if (p == root)
1037 p = NULL;
1038 break;
1040 else if (p->right)
1041 p = p->right;
1042 else
1044 while (1)
1046 p = _asn1_find_up (p);
1047 if (p == root)
1049 p = NULL;
1050 break;
1052 indent -= 2;
1053 if (p->right)
1055 p = p->right;
1056 break;
1066 * asn1_number_of_elements - Counts the number of elements of a structure.
1067 * @element: pointer to the root of an ASN1 structure.
1068 * @name: the name of a sub-structure of ROOT.
1069 * @num: pointer to an integer where the result will be stored
1071 * Counts the number of elements of a sub-structure called NAME with
1072 * names equal to "?1","?2", ...
1074 * Returns:
1076 * ASN1_SUCCESS: Creation OK.
1078 * ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
1080 * ASN1_GENERIC_ERROR: Pointer num equal to NULL.
1083 asn1_retCode
1084 asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1086 node_asn *node, *p;
1088 if (num == NULL)
1089 return ASN1_GENERIC_ERROR;
1091 *num = 0;
1093 node = asn1_find_node (element, name);
1094 if (node == NULL)
1095 return ASN1_ELEMENT_NOT_FOUND;
1097 p = node->down;
1099 while (p)
1101 if ((p->name) && (p->name[0] == '?'))
1102 (*num)++;
1103 p = p->right;
1106 return ASN1_SUCCESS;
1111 * asn1_find_structure_from_oid - Locate structure defined by a specific 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
1119 * after the OID.
1122 const char *
1123 asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1125 char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1];
1126 char value[MAX_NAME_SIZE];
1127 ASN1_TYPE p;
1128 int len;
1129 asn1_retCode result;
1131 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1132 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1135 strcpy (definitionsName, definitions->name);
1136 strcat (definitionsName, ".");
1138 /* search the OBJECT_ID into definitions */
1139 p = definitions->down;
1140 while (p)
1142 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1143 (p->type & CONST_ASSIGN))
1145 strcpy (name, definitionsName);
1146 strcat (name, p->name);
1148 len = MAX_NAME_SIZE;
1149 result = asn1_read_value (definitions, name, value, &len);
1151 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1153 p = p->right;
1154 if (p == NULL) /* reach the end of ASN1 definitions */
1155 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1157 return p->name;
1160 p = p->right;
1163 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1167 * asn1_copy_node:
1168 * @dst: Destination ASN1_TYPE node.
1169 * @dst_name: Field name in destination node.
1170 * @src: Source ASN1_TYPE node.
1171 * @src_name: Field name in source node.
1173 * Create a deep copy of a ASN1_TYPE variable.
1175 * Return value: Return ASN1_SUCCESS on success.
1177 asn1_retCode
1178 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1179 ASN1_TYPE src, const char *src_name)
1181 /* FIXME: rewrite using copy_structure().
1182 * It seems quite hard to do.
1184 int result;
1185 ASN1_TYPE dst_node;
1186 void *data = NULL;
1187 int size = 0;
1189 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1190 if (result != ASN1_MEM_ERROR)
1191 return result;
1193 data = _asn1_malloc (size);
1194 if (data == NULL)
1195 return ASN1_MEM_ERROR;
1197 result = asn1_der_coding (src, src_name, data, &size, NULL);
1198 if (result != ASN1_SUCCESS)
1200 _asn1_free (data);
1201 return result;
1204 dst_node = asn1_find_node (dst, dst_name);
1205 if (dst_node == NULL)
1207 _asn1_free (data);
1208 return ASN1_ELEMENT_NOT_FOUND;
1211 result = asn1_der_decoding (&dst_node, data, size, NULL);
1213 _asn1_free (data);
1215 return result;