Updated to minitasn1 3.0
[gnutls.git] / lib / minitasn1 / structure.c
blob7d622ce82970315220136c6a1c345b7b8ba6201a
1 /*
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
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: structure.c */
25 /* Description: Functions to create and delete an */
26 /* ASN1 tree. */
27 /*****************************************************/
30 #include <int.h>
31 #include <structure.h>
32 #include "parser_aux.h"
33 #include <gstr.h>
36 extern char _asn1_identifierMissing[];
39 /******************************************************/
40 /* Function : _asn1_add_single_node */
41 /* Description: creates a new NODE_ASN element. */
42 /* Parameters: */
43 /* type: type of the new element (see TYPE_ */
44 /* and CONST_ constants). */
45 /* Return: pointer to the new element. */
46 /******************************************************/
47 ASN1_TYPE
48 _asn1_add_single_node (unsigned int type)
50 ASN1_TYPE punt;
52 punt = calloc (1, sizeof (struct node_asn_struct));
53 if (punt == NULL)
54 return NULL;
56 punt->type = type;
58 return punt;
62 /******************************************************************/
63 /* Function : _asn1_find_left */
64 /* Description: returns the NODE_ASN element with RIGHT field that*/
65 /* points the element NODE. */
66 /* Parameters: */
67 /* node: NODE_ASN element pointer. */
68 /* Return: NULL if not found. */
69 /******************************************************************/
70 ASN1_TYPE
71 _asn1_find_left (ASN1_TYPE node)
73 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
74 return NULL;
76 return node->left;
80 asn1_retCode
81 _asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
82 char *vector_name)
84 FILE *file;
85 ASN1_TYPE p;
86 unsigned long t;
88 file = fopen (output_file_name, "w");
90 if (file == NULL)
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);
101 p = pointer;
103 while (p)
105 fprintf (file, " { ");
107 if (p->name[0] != 0)
108 fprintf (file, "\"%s\", ", p->name);
109 else
110 fprintf (file, "NULL, ");
112 t = p->type;
113 if (p->down)
114 t |= CONST_DOWN;
115 if (p->right)
116 t |= CONST_RIGHT;
118 fprintf (file, "%lu, ", t);
120 if (p->value)
121 fprintf (file, "\"%s\"},\n", p->value);
122 else
123 fprintf (file, "NULL },\n");
125 if (p->down)
127 p = p->down;
129 else if (p->right)
131 p = p->right;
133 else
135 while (1)
137 p = _asn1_find_up (p);
138 if (p == pointer)
140 p = NULL;
141 break;
143 if (p->right)
145 p = p->right;
146 break;
152 fprintf (file, " { NULL, 0, NULL }\n};\n");
154 fclose (file);
156 return ASN1_SUCCESS;
161 * asn1_array2tree:
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.
176 asn1_retCode
177 asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
178 char *errorDescription)
180 ASN1_TYPE p, p_last = NULL;
181 unsigned long k;
182 int move;
183 asn1_retCode result;
186 if (*definitions != ASN1_TYPE_EMPTY)
187 return ASN1_ELEMENT_NOT_EMPTY;
189 move = UP;
191 k = 0;
192 while (array[k].value || array[k].type || array[k].name)
194 p = _asn1_add_static_node (array[k].type & (~CONST_DOWN));
195 if (array[k].name)
196 _asn1_set_name (p, array[k].name);
197 if (array[k].value)
198 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
200 if (*definitions == NULL)
201 *definitions = p;
203 if (move == DOWN)
204 _asn1_set_down (p_last, p);
205 else if (move == RIGHT)
206 _asn1_set_right (p_last, p);
208 p_last = p;
210 if (array[k].type & CONST_DOWN)
211 move = DOWN;
212 else if (array[k].type & CONST_RIGHT)
213 move = RIGHT;
214 else
216 while (1)
218 if (p_last == *definitions)
219 break;
221 p_last = _asn1_find_up (p_last);
223 if (p_last == NULL)
224 break;
226 if (p_last->type & CONST_RIGHT)
228 p_last->type &= ~CONST_RIGHT;
229 move = RIGHT;
230 break;
232 } /* while */
234 k++;
235 } /* while */
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);
246 else
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");
259 else
260 errorDescription[0] = 0;
263 if (result != ASN1_SUCCESS)
265 _asn1_delete_list_and_nodes ();
266 *definitions = ASN1_TYPE_EMPTY;
268 else
269 _asn1_delete_list ();
271 return result;
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.
284 asn1_retCode
285 asn1_delete_structure (ASN1_TYPE * structure)
287 ASN1_TYPE p, p2, p3;
289 if (*structure == ASN1_TYPE_EMPTY)
290 return ASN1_ELEMENT_NOT_FOUND;
292 p = *structure;
293 while (p)
295 if (p->down)
297 p = p->down;
299 else
300 { /* no down */
301 p2 = p->right;
302 if (p != *structure)
304 p3 = _asn1_find_up (p);
305 _asn1_set_down (p3, p2);
306 _asn1_remove_node (p);
307 p = p3;
309 else
310 { /* p==root */
311 p3 = _asn1_find_left (p);
312 if (!p3)
314 p3 = _asn1_find_up (p);
315 if (p3)
316 _asn1_set_down (p3, p2);
317 else
319 if (p->right)
320 p->right->left = NULL;
323 else
324 _asn1_set_right (p3, p2);
325 _asn1_remove_node (p);
326 p = NULL;
331 *structure = ASN1_TYPE_EMPTY;
332 return ASN1_SUCCESS;
338 * asn1_delete_element:
339 * @structure: pointer to the structure that contains the element you
340 * want to delete.
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.
348 asn1_retCode
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);
360 if (!p3)
362 p3 = _asn1_find_up (source_node);
363 if (p3)
364 _asn1_set_down (p3, p2);
365 else if (source_node->right)
366 source_node->right->left = NULL;
368 else
369 _asn1_set_right (p3, p2);
371 return asn1_delete_structure (&source_node);
374 ASN1_TYPE
375 _asn1_copy_structure3 (ASN1_TYPE source_node)
377 ASN1_TYPE dest_node, p_s, p_d, p_d_prev;
378 int move;
380 if (source_node == NULL)
381 return NULL;
383 dest_node = _asn1_add_single_node (source_node->type);
385 p_s = source_node;
386 p_d = dest_node;
388 move = DOWN;
392 if (move != UP)
394 if (p_s->name[0] != 0)
395 _asn1_cpy_name (p_d, p_s);
396 if (p_s->value)
397 _asn1_set_value (p_d, p_s->value, p_s->value_len);
398 if (p_s->down)
400 p_s = p_s->down;
401 p_d_prev = p_d;
402 p_d = _asn1_add_single_node (p_s->type);
403 _asn1_set_down (p_d_prev, p_d);
404 continue;
408 if (p_s == source_node)
409 break;
411 if (p_s->right)
413 move = RIGHT;
414 p_s = p_s->right;
415 p_d_prev = p_d;
416 p_d = _asn1_add_single_node (p_s->type);
417 _asn1_set_right (p_d_prev, p_d);
419 else
421 move = UP;
422 p_s = _asn1_find_up (p_s);
423 p_d = _asn1_find_up (p_d);
426 while (p_s != source_node);
428 return dest_node;
432 static ASN1_TYPE
433 _asn1_copy_structure2 (ASN1_TYPE root, const char *source_name)
435 ASN1_TYPE source_node;
437 source_node = asn1_find_node (root, source_name);
439 return _asn1_copy_structure3 (source_node);
444 static asn1_retCode
445 _asn1_type_choice_config (ASN1_TYPE node)
447 ASN1_TYPE p, p2, p3, p4;
448 int move, tlen;
450 if (node == NULL)
451 return ASN1_ELEMENT_NOT_FOUND;
453 p = node;
454 move = DOWN;
456 while (!((p == node) && (move == UP)))
458 if (move != UP)
460 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
462 p2 = p->down;
463 while (p2)
465 if (type_field (p2->type) != TYPE_TAG)
467 p2->type |= CONST_TAG;
468 p3 = _asn1_find_left (p2);
469 while (p3)
471 if (type_field (p3->type) == TYPE_TAG)
473 p4 = _asn1_add_single_node (p3->type);
474 tlen = _asn1_strlen (p3->value);
475 if (tlen > 0)
476 _asn1_set_value (p4, p3->value, tlen + 1);
477 _asn1_set_right (p4, p2->down);
478 _asn1_set_down (p2, p4);
480 p3 = _asn1_find_left (p3);
483 p2 = p2->right;
485 p->type &= ~(CONST_TAG);
486 p2 = p->down;
487 while (p2)
489 p3 = p2->right;
490 if (type_field (p2->type) == TYPE_TAG)
491 asn1_delete_structure (&p2);
492 p2 = p3;
495 move = DOWN;
497 else
498 move = RIGHT;
500 if (move == DOWN)
502 if (p->down)
503 p = p->down;
504 else
505 move = RIGHT;
508 if (p == node)
510 move = UP;
511 continue;
514 if (move == RIGHT)
516 if (p->right)
517 p = p->right;
518 else
519 move = UP;
521 if (move == UP)
522 p = _asn1_find_up (p);
525 return ASN1_SUCCESS;
529 static asn1_retCode
530 _asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root)
532 ASN1_TYPE p, p2, p3;
533 char name2[ASN1_MAX_NAME_SIZE + 2];
534 int move;
536 if (node == NULL)
537 return ASN1_ELEMENT_NOT_FOUND;
539 p = *node;
540 move = DOWN;
542 while (!((p == *node) && (move == UP)))
544 if (move != UP)
546 if (type_field (p->type) == TYPE_IDENTIFIER)
548 snprintf(name2, sizeof (name2), "%s.%s", root->name, p->value);
549 p2 = _asn1_copy_structure2 (root, name2);
550 if (p2 == NULL)
552 return ASN1_IDENTIFIER_NOT_FOUND;
554 _asn1_cpy_name (p2, p);
555 p2->right = p->right;
556 p2->left = p->left;
557 if (p->right)
558 p->right->left = p2;
559 p3 = p->down;
560 if (p3)
562 while (p3->right)
563 p3 = p3->right;
564 _asn1_set_right (p3, p2->down);
565 _asn1_set_down (p2, p->down);
568 p3 = _asn1_find_left (p);
569 if (p3)
570 _asn1_set_right (p3, p2);
571 else
573 p3 = _asn1_find_up (p);
574 if (p3)
575 _asn1_set_down (p3, p2);
576 else
578 p2->left = NULL;
582 if (p->type & CONST_SIZE)
583 p2->type |= CONST_SIZE;
584 if (p->type & CONST_TAG)
585 p2->type |= CONST_TAG;
586 if (p->type & CONST_OPTION)
587 p2->type |= CONST_OPTION;
588 if (p->type & CONST_DEFAULT)
589 p2->type |= CONST_DEFAULT;
590 if (p->type & CONST_SET)
591 p2->type |= CONST_SET;
592 if (p->type & CONST_NOT_USED)
593 p2->type |= CONST_NOT_USED;
595 if (p == *node)
596 *node = p2;
597 _asn1_remove_node (p);
598 p = p2;
599 move = DOWN;
600 continue;
602 move = DOWN;
604 else
605 move = RIGHT;
607 if (move == DOWN)
609 if (p->down)
610 p = p->down;
611 else
612 move = RIGHT;
615 if (p == *node)
617 move = UP;
618 continue;
621 if (move == RIGHT)
623 if (p->right)
624 p = p->right;
625 else
626 move = UP;
628 if (move == UP)
629 p = _asn1_find_up (p);
632 return ASN1_SUCCESS;
637 * asn1_create_element:
638 * @definitions: pointer to the structure returned by "parser_asn1" function
639 * @source_name: the name of the type of the new structure (must be
640 * inside p_structure).
641 * @element: pointer to the structure created.
643 * Creates a structure of type @source_name. Example using
644 * "pkix.asn":
646 * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr);
648 * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if
649 * @source_name is not known.
651 asn1_retCode
652 asn1_create_element (ASN1_TYPE definitions, const char *source_name,
653 ASN1_TYPE * element)
655 ASN1_TYPE dest_node;
656 int res;
658 dest_node = _asn1_copy_structure2 (definitions, source_name);
660 if (dest_node == NULL)
661 return ASN1_ELEMENT_NOT_FOUND;
663 _asn1_set_name (dest_node, "");
665 res = _asn1_expand_identifier (&dest_node, definitions);
666 _asn1_type_choice_config (dest_node);
668 *element = dest_node;
670 return res;
675 * asn1_print_structure:
676 * @out: pointer to the output file (e.g. stdout).
677 * @structure: pointer to the structure that you want to visit.
678 * @name: an element of the structure
679 * @mode: specify how much of the structure to print, can be
680 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
681 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
683 * Prints on the @out file descriptor the structure's tree starting
684 * from the @name element inside the structure @structure.
686 void
687 asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
688 int mode)
690 ASN1_TYPE p, root;
691 int k, indent = 0, len, len2, len3;
693 if (out == NULL)
694 return;
696 root = asn1_find_node (structure, name);
698 if (root == NULL)
699 return;
701 p = root;
702 while (p)
704 if (mode == ASN1_PRINT_ALL)
706 for (k = 0; k < indent; k++)
707 fprintf (out, " ");
708 fprintf (out, "name:");
709 if (p->name[0] != 0)
710 fprintf (out, "%s ", p->name);
711 else
712 fprintf (out, "NULL ");
714 else
716 switch (type_field (p->type))
718 case TYPE_CONSTANT:
719 case TYPE_TAG:
720 case TYPE_SIZE:
721 break;
722 default:
723 for (k = 0; k < indent; k++)
724 fprintf (out, " ");
725 fprintf (out, "name:");
726 if (p->name[0] != 0)
727 fprintf (out, "%s ", p->name);
728 else
729 fprintf (out, "NULL ");
733 if (mode != ASN1_PRINT_NAME)
735 switch (type_field (p->type))
737 case TYPE_CONSTANT:
738 if (mode == ASN1_PRINT_ALL)
739 fprintf (out, "type:CONST");
740 break;
741 case TYPE_TAG:
742 if (mode == ASN1_PRINT_ALL)
743 fprintf (out, "type:TAG");
744 break;
745 case TYPE_SIZE:
746 if (mode == ASN1_PRINT_ALL)
747 fprintf (out, "type:SIZE");
748 break;
749 case TYPE_DEFAULT:
750 fprintf (out, "type:DEFAULT");
751 break;
752 case TYPE_NULL:
753 fprintf (out, "type:NULL");
754 break;
755 case TYPE_IDENTIFIER:
756 fprintf (out, "type:IDENTIFIER");
757 break;
758 case TYPE_INTEGER:
759 fprintf (out, "type:INTEGER");
760 break;
761 case TYPE_ENUMERATED:
762 fprintf (out, "type:ENUMERATED");
763 break;
764 case TYPE_TIME:
765 fprintf (out, "type:TIME");
766 break;
767 case TYPE_BOOLEAN:
768 fprintf (out, "type:BOOLEAN");
769 break;
770 case TYPE_SEQUENCE:
771 fprintf (out, "type:SEQUENCE");
772 break;
773 case TYPE_BIT_STRING:
774 fprintf (out, "type:BIT_STR");
775 break;
776 case TYPE_OCTET_STRING:
777 fprintf (out, "type:OCT_STR");
778 break;
779 case TYPE_GENERALSTRING:
780 fprintf (out, "type:GENERALSTRING");
781 break;
782 case TYPE_SEQUENCE_OF:
783 fprintf (out, "type:SEQ_OF");
784 break;
785 case TYPE_OBJECT_ID:
786 fprintf (out, "type:OBJ_ID");
787 break;
788 case TYPE_ANY:
789 fprintf (out, "type:ANY");
790 break;
791 case TYPE_SET:
792 fprintf (out, "type:SET");
793 break;
794 case TYPE_SET_OF:
795 fprintf (out, "type:SET_OF");
796 break;
797 case TYPE_CHOICE:
798 fprintf (out, "type:CHOICE");
799 break;
800 case TYPE_DEFINITIONS:
801 fprintf (out, "type:DEFINITIONS");
802 break;
803 default:
804 break;
808 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
810 switch (type_field (p->type))
812 case TYPE_CONSTANT:
813 if (mode == ASN1_PRINT_ALL)
814 if (p->value)
815 fprintf (out, " value:%s", p->value);
816 break;
817 case TYPE_TAG:
818 if (mode == ASN1_PRINT_ALL)
819 if (p->value)
820 fprintf (out, " value:%s", p->value);
821 break;
822 case TYPE_SIZE:
823 if (mode == ASN1_PRINT_ALL)
824 if (p->value)
825 fprintf (out, " value:%s", p->value);
826 break;
827 case TYPE_DEFAULT:
828 if (p->value)
829 fprintf (out, " value:%s", p->value);
830 else if (p->type & CONST_TRUE)
831 fprintf (out, " value:TRUE");
832 else if (p->type & CONST_FALSE)
833 fprintf (out, " value:FALSE");
834 break;
835 case TYPE_IDENTIFIER:
836 if (p->value)
837 fprintf (out, " value:%s", p->value);
838 break;
839 case TYPE_INTEGER:
840 if (p->value)
842 len2 = -1;
843 len = asn1_get_length_der (p->value, p->value_len, &len2);
844 fprintf (out, " value:0x");
845 if (len > 0)
846 for (k = 0; k < len; k++)
847 fprintf (out, "%02x", (p->value)[k + len2]);
849 break;
850 case TYPE_ENUMERATED:
851 if (p->value)
853 len2 = -1;
854 len = asn1_get_length_der (p->value, p->value_len, &len2);
855 fprintf (out, " value:0x");
856 if (len > 0)
857 for (k = 0; k < len; k++)
858 fprintf (out, "%02x", (p->value)[k + len2]);
860 break;
861 case TYPE_TIME:
862 if (p->value)
863 fprintf (out, " value:%s", p->value);
864 break;
865 case TYPE_BOOLEAN:
866 if (p->value)
868 if (p->value[0] == 'T')
869 fprintf (out, " value:TRUE");
870 else if (p->value[0] == 'F')
871 fprintf (out, " value:FALSE");
873 break;
874 case TYPE_BIT_STRING:
875 if (p->value)
877 len2 = -1;
878 len = asn1_get_length_der (p->value, p->value_len, &len2);
879 if (len > 0)
881 fprintf (out, " value(%i):",
882 (len - 1) * 8 - (p->value[len2]));
883 for (k = 1; k < len; k++)
884 fprintf (out, "%02x", (p->value)[k + len2]);
887 break;
888 case TYPE_OCTET_STRING:
889 if (p->value)
891 len2 = -1;
892 len = asn1_get_length_der (p->value, p->value_len, &len2);
893 fprintf (out, " value:");
894 if (len > 0)
895 for (k = 0; k < len; k++)
896 fprintf (out, "%02x", (p->value)[k + len2]);
898 break;
899 case TYPE_GENERALSTRING:
900 if (p->value)
902 len2 = -1;
903 len = asn1_get_length_der (p->value, p->value_len, &len2);
904 fprintf (out, " value:");
905 if (len > 0)
906 for (k = 0; k < len; k++)
907 fprintf (out, "%02x", (p->value)[k + len2]);
909 break;
910 case TYPE_OBJECT_ID:
911 if (p->value)
912 fprintf (out, " value:%s", p->value);
913 break;
914 case TYPE_ANY:
915 if (p->value)
917 len3 = -1;
918 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
919 fprintf (out, " value:");
920 if (len2 > 0)
921 for (k = 0; k < len2; k++)
922 fprintf (out, "%02x", (p->value)[k + len3]);
924 break;
925 case TYPE_SET:
926 case TYPE_SET_OF:
927 case TYPE_CHOICE:
928 case TYPE_DEFINITIONS:
929 case TYPE_SEQUENCE_OF:
930 case TYPE_SEQUENCE:
931 case TYPE_NULL:
932 break;
933 default:
934 break;
938 if (mode == ASN1_PRINT_ALL)
940 if (p->type & 0x1FFFFF00)
942 fprintf (out, " attr:");
943 if (p->type & CONST_UNIVERSAL)
944 fprintf (out, "UNIVERSAL,");
945 if (p->type & CONST_PRIVATE)
946 fprintf (out, "PRIVATE,");
947 if (p->type & CONST_APPLICATION)
948 fprintf (out, "APPLICATION,");
949 if (p->type & CONST_EXPLICIT)
950 fprintf (out, "EXPLICIT,");
951 if (p->type & CONST_IMPLICIT)
952 fprintf (out, "IMPLICIT,");
953 if (p->type & CONST_TAG)
954 fprintf (out, "TAG,");
955 if (p->type & CONST_DEFAULT)
956 fprintf (out, "DEFAULT,");
957 if (p->type & CONST_TRUE)
958 fprintf (out, "TRUE,");
959 if (p->type & CONST_FALSE)
960 fprintf (out, "FALSE,");
961 if (p->type & CONST_LIST)
962 fprintf (out, "LIST,");
963 if (p->type & CONST_MIN_MAX)
964 fprintf (out, "MIN_MAX,");
965 if (p->type & CONST_OPTION)
966 fprintf (out, "OPTION,");
967 if (p->type & CONST_1_PARAM)
968 fprintf (out, "1_PARAM,");
969 if (p->type & CONST_SIZE)
970 fprintf (out, "SIZE,");
971 if (p->type & CONST_DEFINED_BY)
972 fprintf (out, "DEF_BY,");
973 if (p->type & CONST_GENERALIZED)
974 fprintf (out, "GENERALIZED,");
975 if (p->type & CONST_UTC)
976 fprintf (out, "UTC,");
977 if (p->type & CONST_SET)
978 fprintf (out, "SET,");
979 if (p->type & CONST_NOT_USED)
980 fprintf (out, "NOT_USED,");
981 if (p->type & CONST_ASSIGN)
982 fprintf (out, "ASSIGNMENT,");
986 if (mode == ASN1_PRINT_ALL)
988 fprintf (out, "\n");
990 else
992 switch (type_field (p->type))
994 case TYPE_CONSTANT:
995 case TYPE_TAG:
996 case TYPE_SIZE:
997 break;
998 default:
999 fprintf (out, "\n");
1003 if (p->down)
1005 p = p->down;
1006 indent += 2;
1008 else if (p == root)
1010 p = NULL;
1011 break;
1013 else if (p->right)
1014 p = p->right;
1015 else
1017 while (1)
1019 p = _asn1_find_up (p);
1020 if (p == root)
1022 p = NULL;
1023 break;
1025 indent -= 2;
1026 if (p->right)
1028 p = p->right;
1029 break;
1039 * asn1_number_of_elements:
1040 * @element: pointer to the root of an ASN1 structure.
1041 * @name: the name of a sub-structure of ROOT.
1042 * @num: pointer to an integer where the result will be stored
1044 * Counts the number of elements of a sub-structure called NAME with
1045 * names equal to "?1","?2", ...
1047 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
1048 * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
1050 asn1_retCode
1051 asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1053 ASN1_TYPE node, p;
1055 if (num == NULL)
1056 return ASN1_GENERIC_ERROR;
1058 *num = 0;
1060 node = asn1_find_node (element, name);
1061 if (node == NULL)
1062 return ASN1_ELEMENT_NOT_FOUND;
1064 p = node->down;
1066 while (p)
1068 if (p->name[0] == '?')
1069 (*num)++;
1070 p = p->right;
1073 return ASN1_SUCCESS;
1078 * asn1_find_structure_from_oid:
1079 * @definitions: ASN1 definitions
1080 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1082 * Search the structure that is defined just after an OID definition.
1084 * Returns: %NULL when @oidValue not found, otherwise the pointer to a
1085 * constant string that contains the element name defined just after
1086 * the OID.
1088 const char *
1089 asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1091 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1];
1092 char value[ASN1_MAX_NAME_SIZE];
1093 ASN1_TYPE p;
1094 int len;
1095 asn1_retCode result;
1097 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1098 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1101 strcpy (definitionsName, definitions->name);
1102 strcat (definitionsName, ".");
1104 /* search the OBJECT_ID into definitions */
1105 p = definitions->down;
1106 while (p)
1108 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1109 (p->type & CONST_ASSIGN))
1111 strcpy (name, definitionsName);
1112 strcat (name, p->name);
1114 len = ASN1_MAX_NAME_SIZE;
1115 result = asn1_read_value (definitions, name, value, &len);
1117 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1119 p = p->right;
1120 if (p == NULL) /* reach the end of ASN1 definitions */
1121 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1123 return p->name;
1126 p = p->right;
1129 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1133 * asn1_copy_node:
1134 * @dst: Destination ASN1_TYPE node.
1135 * @dst_name: Field name in destination node.
1136 * @src: Source ASN1_TYPE node.
1137 * @src_name: Field name in source node.
1139 * Create a deep copy of a ASN1_TYPE variable.
1141 * Returns: Return %ASN1_SUCCESS on success.
1143 asn1_retCode
1144 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1145 ASN1_TYPE src, const char *src_name)
1147 /* FIXME: rewrite using copy_structure().
1148 * It seems quite hard to do.
1150 int result;
1151 ASN1_TYPE dst_node;
1152 void *data = NULL;
1153 int size = 0;
1155 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1156 if (result != ASN1_MEM_ERROR)
1157 return result;
1159 data = malloc (size);
1160 if (data == NULL)
1161 return ASN1_MEM_ERROR;
1163 result = asn1_der_coding (src, src_name, data, &size, NULL);
1164 if (result != ASN1_SUCCESS)
1166 free (data);
1167 return result;
1170 dst_node = asn1_find_node (dst, dst_name);
1171 if (dst_node == NULL)
1173 free (data);
1174 return ASN1_ELEMENT_NOT_FOUND;
1177 result = asn1_der_decoding (&dst_node, data, size, NULL);
1179 free (data);
1181 return result;