Fix use of deprecated types, for now and the future.
[gnutls.git] / lib / minitasn1 / structure.c
blob39316516dfadb4533525cebb3825b6c6b7771a2c
1 /*
2 * Copyright (C) 2004, 2006, 2007, 2008, 2009 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 <structure.h>
33 #include "parser_aux.h"
34 #include <gstr.h>
37 extern char _asn1_identifierMissing[];
40 /******************************************************/
41 /* Function : _asn1_add_node_only */
42 /* Description: creates a new NODE_ASN element. */
43 /* Parameters: */
44 /* type: type of the new element (see TYPE_ */
45 /* and CONST_ constants). */
46 /* Return: pointer to the new element. */
47 /******************************************************/
48 ASN1_TYPE
49 _asn1_add_node_only (unsigned int type)
51 ASN1_TYPE punt;
53 punt = (ASN1_TYPE) _asn1_calloc (1, sizeof (struct node_asn_struct));
54 if (punt == NULL)
55 return NULL;
57 punt->type = type;
59 return punt;
63 /******************************************************************/
64 /* Function : _asn1_find_left */
65 /* Description: returns the NODE_ASN element with RIGHT field that*/
66 /* points the element NODE. */
67 /* Parameters: */
68 /* node: NODE_ASN element pointer. */
69 /* Return: NULL if not found. */
70 /******************************************************************/
71 ASN1_TYPE
72 _asn1_find_left (ASN1_TYPE node)
74 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
75 return NULL;
77 return node->left;
81 asn1_retCode
82 _asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
83 char *vector_name)
85 FILE *file;
86 ASN1_TYPE p;
87 unsigned long t;
89 file = fopen (output_file_name, "w");
91 if (file == NULL)
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);
102 p = pointer;
104 while (p)
106 fprintf (file, " { ");
108 if (p->name)
109 fprintf (file, "\"%s\", ", p->name);
110 else
111 fprintf (file, "NULL, ");
113 t = p->type;
114 if (p->down)
115 t |= CONST_DOWN;
116 if (p->right)
117 t |= CONST_RIGHT;
119 fprintf (file, "%lu, ", t);
121 if (p->value)
122 fprintf (file, "\"%s\"},\n", p->value);
123 else
124 fprintf (file, "NULL },\n");
126 if (p->down)
128 p = p->down;
130 else if (p->right)
132 p = p->right;
134 else
136 while (1)
138 p = _asn1_find_up (p);
139 if (p == pointer)
141 p = NULL;
142 break;
144 if (p->right)
146 p = p->right;
147 break;
153 fprintf (file, " { NULL, 0, NULL }\n};\n");
155 fclose (file);
157 return ASN1_SUCCESS;
162 * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions.
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().
171 * Returns:
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.
182 asn1_retCode
183 asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
184 char *errorDescription)
186 ASN1_TYPE p, p_last = NULL;
187 unsigned long k;
188 int move;
189 asn1_retCode result;
192 if (*definitions != ASN1_TYPE_EMPTY)
193 return ASN1_ELEMENT_NOT_EMPTY;
195 move = UP;
197 k = 0;
198 while (array[k].value || array[k].type || array[k].name)
200 p = _asn1_add_node (array[k].type & (~CONST_DOWN));
201 if (array[k].name)
202 _asn1_set_name (p, array[k].name);
203 if (array[k].value)
204 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
206 if (*definitions == NULL)
207 *definitions = p;
209 if (move == DOWN)
210 _asn1_set_down (p_last, p);
211 else if (move == RIGHT)
212 _asn1_set_right (p_last, p);
214 p_last = p;
216 if (array[k].type & CONST_DOWN)
217 move = DOWN;
218 else if (array[k].type & CONST_RIGHT)
219 move = RIGHT;
220 else
222 while (1)
224 if (p_last == *definitions)
225 break;
227 p_last = _asn1_find_up (p_last);
229 if (p_last == NULL)
230 break;
232 if (p_last->type & CONST_RIGHT)
234 p_last->type &= ~CONST_RIGHT;
235 move = RIGHT;
236 break;
238 } /* while */
240 k++;
241 } /* while */
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);
252 else
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");
265 else
266 errorDescription[0] = 0;
269 if (result != ASN1_SUCCESS)
271 _asn1_delete_list_and_nodes ();
272 *definitions = ASN1_TYPE_EMPTY;
274 else
275 _asn1_delete_list ();
277 return result;
281 * asn1_delete_structure - Deletes the structure pointed by *ROOT.
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.
287 * Returns:
289 * ASN1_SUCCESS: Everything OK.
291 * ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY.
294 asn1_retCode
295 asn1_delete_structure (ASN1_TYPE * structure)
297 ASN1_TYPE p, p2, p3;
299 if (*structure == ASN1_TYPE_EMPTY)
300 return ASN1_ELEMENT_NOT_FOUND;
302 p = *structure;
303 while (p)
305 if (p->down)
307 p = p->down;
309 else
310 { /* no down */
311 p2 = p->right;
312 if (p != *structure)
314 p3 = _asn1_find_up (p);
315 _asn1_set_down (p3, p2);
316 _asn1_remove_node (p);
317 p = p3;
319 else
320 { /* p==root */
321 p3 = _asn1_find_left (p);
322 if (!p3)
324 p3 = _asn1_find_up (p);
325 if (p3)
326 _asn1_set_down (p3, p2);
327 else
329 if (p->right)
330 p->right->left = NULL;
333 else
334 _asn1_set_right (p3, p2);
335 _asn1_remove_node (p);
336 p = NULL;
341 *structure = ASN1_TYPE_EMPTY;
342 return ASN1_SUCCESS;
348 * asn1_delete_element - Deletes the element of a structure.
349 * @structure: pointer to the structure that contains the element you
350 * want to delete.
351 * @element_name: element's name you want to delete.
353 * Deletes the element named *@element_name inside *@structure.
355 * Returns:
357 * ASN1_SUCCESS: Everything OK.
359 * ASN1_ELEMENT_NOT_FOUND: The name element was not found.
362 asn1_retCode
363 asn1_delete_element (ASN1_TYPE structure, const char *element_name)
365 ASN1_TYPE p2, p3, source_node;
367 source_node = asn1_find_node (structure, element_name);
369 if (source_node == ASN1_TYPE_EMPTY)
370 return ASN1_ELEMENT_NOT_FOUND;
372 p2 = source_node->right;
373 p3 = _asn1_find_left (source_node);
374 if (!p3)
376 p3 = _asn1_find_up (source_node);
377 if (p3)
378 _asn1_set_down (p3, p2);
379 else if (source_node->right)
380 source_node->right->left = NULL;
382 else
383 _asn1_set_right (p3, p2);
385 return asn1_delete_structure (&source_node);
388 ASN1_TYPE
389 _asn1_copy_structure3 (ASN1_TYPE source_node)
391 ASN1_TYPE dest_node, p_s, p_d, p_d_prev;
392 int move;
394 if (source_node == NULL)
395 return NULL;
397 dest_node = _asn1_add_node_only (source_node->type);
399 p_s = source_node;
400 p_d = dest_node;
402 move = DOWN;
406 if (move != UP)
408 if (p_s->name)
409 _asn1_set_name (p_d, p_s->name);
410 if (p_s->value)
411 _asn1_set_value (p_d, p_s->value, p_s->value_len);
412 move = DOWN;
414 else
415 move = RIGHT;
417 if (move == DOWN)
419 if (p_s->down)
421 p_s = p_s->down;
422 p_d_prev = p_d;
423 p_d = _asn1_add_node_only (p_s->type);
424 _asn1_set_down (p_d_prev, p_d);
426 else
427 move = RIGHT;
430 if (p_s == source_node)
431 break;
433 if (move == RIGHT)
435 if (p_s->right)
437 p_s = p_s->right;
438 p_d_prev = p_d;
439 p_d = _asn1_add_node_only (p_s->type);
440 _asn1_set_right (p_d_prev, p_d);
442 else
443 move = UP;
445 if (move == UP)
447 p_s = _asn1_find_up (p_s);
448 p_d = _asn1_find_up (p_d);
451 while (p_s != source_node);
453 return dest_node;
457 static ASN1_TYPE
458 _asn1_copy_structure2 (ASN1_TYPE root, const char *source_name)
460 ASN1_TYPE source_node;
462 source_node = asn1_find_node (root, source_name);
464 return _asn1_copy_structure3 (source_node);
469 static asn1_retCode
470 _asn1_type_choice_config (ASN1_TYPE node)
472 ASN1_TYPE p, p2, p3, p4;
473 int move, tlen;
475 if (node == NULL)
476 return ASN1_ELEMENT_NOT_FOUND;
478 p = node;
479 move = DOWN;
481 while (!((p == node) && (move == UP)))
483 if (move != UP)
485 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
487 p2 = p->down;
488 while (p2)
490 if (type_field (p2->type) != TYPE_TAG)
492 p2->type |= CONST_TAG;
493 p3 = _asn1_find_left (p2);
494 while (p3)
496 if (type_field (p3->type) == TYPE_TAG)
498 p4 = _asn1_add_node_only (p3->type);
499 tlen = strlen (p3->value);
500 if (tlen > 0)
501 _asn1_set_value (p4, p3->value, tlen + 1);
502 _asn1_set_right (p4, p2->down);
503 _asn1_set_down (p2, p4);
505 p3 = _asn1_find_left (p3);
508 p2 = p2->right;
510 p->type &= ~(CONST_TAG);
511 p2 = p->down;
512 while (p2)
514 p3 = p2->right;
515 if (type_field (p2->type) == TYPE_TAG)
516 asn1_delete_structure (&p2);
517 p2 = p3;
520 move = DOWN;
522 else
523 move = RIGHT;
525 if (move == DOWN)
527 if (p->down)
528 p = p->down;
529 else
530 move = RIGHT;
533 if (p == node)
535 move = UP;
536 continue;
539 if (move == RIGHT)
541 if (p->right)
542 p = p->right;
543 else
544 move = UP;
546 if (move == UP)
547 p = _asn1_find_up (p);
550 return ASN1_SUCCESS;
554 static asn1_retCode
555 _asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root)
557 ASN1_TYPE p, p2, p3;
558 char name2[ASN1_MAX_NAME_SIZE + 2];
559 int move;
561 if (node == NULL)
562 return ASN1_ELEMENT_NOT_FOUND;
564 p = *node;
565 move = DOWN;
567 while (!((p == *node) && (move == UP)))
569 if (move != UP)
571 if (type_field (p->type) == TYPE_IDENTIFIER)
573 _asn1_str_cpy (name2, sizeof (name2), root->name);
574 _asn1_str_cat (name2, sizeof (name2), ".");
575 _asn1_str_cat (name2, sizeof (name2), p->value);
576 p2 = _asn1_copy_structure2 (root, name2);
577 if (p2 == NULL)
579 return ASN1_IDENTIFIER_NOT_FOUND;
581 _asn1_set_name (p2, p->name);
582 p2->right = p->right;
583 p2->left = p->left;
584 if (p->right)
585 p->right->left = p2;
586 p3 = p->down;
587 if (p3)
589 while (p3->right)
590 p3 = p3->right;
591 _asn1_set_right (p3, p2->down);
592 _asn1_set_down (p2, p->down);
595 p3 = _asn1_find_left (p);
596 if (p3)
597 _asn1_set_right (p3, p2);
598 else
600 p3 = _asn1_find_up (p);
601 if (p3)
602 _asn1_set_down (p3, p2);
603 else
605 p2->left = NULL;
609 if (p->type & CONST_SIZE)
610 p2->type |= CONST_SIZE;
611 if (p->type & CONST_TAG)
612 p2->type |= CONST_TAG;
613 if (p->type & CONST_OPTION)
614 p2->type |= CONST_OPTION;
615 if (p->type & CONST_DEFAULT)
616 p2->type |= CONST_DEFAULT;
617 if (p->type & CONST_SET)
618 p2->type |= CONST_SET;
619 if (p->type & CONST_NOT_USED)
620 p2->type |= CONST_NOT_USED;
622 if (p == *node)
623 *node = p2;
624 _asn1_remove_node (p);
625 p = p2;
626 move = DOWN;
627 continue;
629 move = DOWN;
631 else
632 move = RIGHT;
634 if (move == DOWN)
636 if (p->down)
637 p = p->down;
638 else
639 move = RIGHT;
642 if (p == *node)
644 move = UP;
645 continue;
648 if (move == RIGHT)
650 if (p->right)
651 p = p->right;
652 else
653 move = UP;
655 if (move == UP)
656 p = _asn1_find_up (p);
659 return ASN1_SUCCESS;
664 * asn1_create_element - Creates a structure of type SOURCE_NAME.
665 * @definitions: pointer to the structure returned by "parser_asn1" function
666 * @source_name: the name of the type of the new structure (must be
667 * inside p_structure).
668 * @element: pointer to the structure created.
670 * Creates a structure of type @source_name. Example using
671 * "pkix.asn":
673 * rc = asn1_create_structure(cert_def, "PKIX1.Certificate",
674 * certptr);
676 * Returns:
678 * ASN1_SUCCESS: Creation OK.
680 * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
682 asn1_retCode
683 asn1_create_element (ASN1_TYPE definitions, const char *source_name,
684 ASN1_TYPE * element)
686 ASN1_TYPE dest_node;
687 int res;
689 dest_node = _asn1_copy_structure2 (definitions, source_name);
691 if (dest_node == NULL)
692 return ASN1_ELEMENT_NOT_FOUND;
694 _asn1_set_name (dest_node, "");
696 res = _asn1_expand_identifier (&dest_node, definitions);
697 _asn1_type_choice_config (dest_node);
699 *element = dest_node;
701 return res;
706 * asn1_print_structure - Prints on the standard output the structure's tree
707 * @out: pointer to the output file (e.g. stdout).
708 * @structure: pointer to the structure that you want to visit.
709 * @name: an element of the structure
710 * @mode: specify how much of the structure to print, can be
711 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
712 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
714 * Prints on the @out file descriptor the structure's tree starting
715 * from the @name element inside the structure @structure.
717 void
718 asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
719 int mode)
721 ASN1_TYPE p, root;
722 int k, indent = 0, len, len2, len3;
724 if (out == NULL)
725 return;
727 root = asn1_find_node (structure, name);
729 if (root == NULL)
730 return;
732 p = root;
733 while (p)
735 if (mode == ASN1_PRINT_ALL)
737 for (k = 0; k < indent; k++)
738 fprintf (out, " ");
739 fprintf (out, "name:");
740 if (p->name)
741 fprintf (out, "%s ", p->name);
742 else
743 fprintf (out, "NULL ");
745 else
747 switch (type_field (p->type))
749 case TYPE_CONSTANT:
750 case TYPE_TAG:
751 case TYPE_SIZE:
752 break;
753 default:
754 for (k = 0; k < indent; k++)
755 fprintf (out, " ");
756 fprintf (out, "name:");
757 if (p->name)
758 fprintf (out, "%s ", p->name);
759 else
760 fprintf (out, "NULL ");
764 if (mode != ASN1_PRINT_NAME)
766 switch (type_field (p->type))
768 case TYPE_CONSTANT:
769 if (mode == ASN1_PRINT_ALL)
770 fprintf (out, "type:CONST");
771 break;
772 case TYPE_TAG:
773 if (mode == ASN1_PRINT_ALL)
774 fprintf (out, "type:TAG");
775 break;
776 case TYPE_SIZE:
777 if (mode == ASN1_PRINT_ALL)
778 fprintf (out, "type:SIZE");
779 break;
780 case TYPE_DEFAULT:
781 fprintf (out, "type:DEFAULT");
782 break;
783 case TYPE_NULL:
784 fprintf (out, "type:NULL");
785 break;
786 case TYPE_IDENTIFIER:
787 fprintf (out, "type:IDENTIFIER");
788 break;
789 case TYPE_INTEGER:
790 fprintf (out, "type:INTEGER");
791 break;
792 case TYPE_ENUMERATED:
793 fprintf (out, "type:ENUMERATED");
794 break;
795 case TYPE_TIME:
796 fprintf (out, "type:TIME");
797 break;
798 case TYPE_BOOLEAN:
799 fprintf (out, "type:BOOLEAN");
800 break;
801 case TYPE_SEQUENCE:
802 fprintf (out, "type:SEQUENCE");
803 break;
804 case TYPE_BIT_STRING:
805 fprintf (out, "type:BIT_STR");
806 break;
807 case TYPE_OCTET_STRING:
808 fprintf (out, "type:OCT_STR");
809 break;
810 case TYPE_GENERALSTRING:
811 fprintf (out, "type:GENERALSTRING");
812 break;
813 case TYPE_SEQUENCE_OF:
814 fprintf (out, "type:SEQ_OF");
815 break;
816 case TYPE_OBJECT_ID:
817 fprintf (out, "type:OBJ_ID");
818 break;
819 case TYPE_ANY:
820 fprintf (out, "type:ANY");
821 break;
822 case TYPE_SET:
823 fprintf (out, "type:SET");
824 break;
825 case TYPE_SET_OF:
826 fprintf (out, "type:SET_OF");
827 break;
828 case TYPE_CHOICE:
829 fprintf (out, "type:CHOICE");
830 break;
831 case TYPE_DEFINITIONS:
832 fprintf (out, "type:DEFINITIONS");
833 break;
834 default:
835 break;
839 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
841 switch (type_field (p->type))
843 case TYPE_CONSTANT:
844 if (mode == ASN1_PRINT_ALL)
845 if (p->value)
846 fprintf (out, " value:%s", p->value);
847 break;
848 case TYPE_TAG:
849 if (mode == ASN1_PRINT_ALL)
850 if (p->value)
851 fprintf (out, " value:%s", p->value);
852 break;
853 case TYPE_SIZE:
854 if (mode == ASN1_PRINT_ALL)
855 if (p->value)
856 fprintf (out, " value:%s", p->value);
857 break;
858 case TYPE_DEFAULT:
859 if (p->value)
860 fprintf (out, " value:%s", p->value);
861 else if (p->type & CONST_TRUE)
862 fprintf (out, " value:TRUE");
863 else if (p->type & CONST_FALSE)
864 fprintf (out, " value:FALSE");
865 break;
866 case TYPE_IDENTIFIER:
867 if (p->value)
868 fprintf (out, " value:%s", p->value);
869 break;
870 case TYPE_INTEGER:
871 if (p->value)
873 len2 = -1;
874 len = asn1_get_length_der (p->value, p->value_len, &len2);
875 fprintf (out, " value:0x");
876 if (len > 0)
877 for (k = 0; k < len; k++)
878 fprintf (out, "%02x", (p->value)[k + len2]);
880 break;
881 case TYPE_ENUMERATED:
882 if (p->value)
884 len2 = -1;
885 len = asn1_get_length_der (p->value, p->value_len, &len2);
886 fprintf (out, " value:0x");
887 if (len > 0)
888 for (k = 0; k < len; k++)
889 fprintf (out, "%02x", (p->value)[k + len2]);
891 break;
892 case TYPE_TIME:
893 if (p->value)
894 fprintf (out, " value:%s", p->value);
895 break;
896 case TYPE_BOOLEAN:
897 if (p->value)
899 if (p->value[0] == 'T')
900 fprintf (out, " value:TRUE");
901 else if (p->value[0] == 'F')
902 fprintf (out, " value:FALSE");
904 break;
905 case TYPE_BIT_STRING:
906 if (p->value)
908 len2 = -1;
909 len = asn1_get_length_der (p->value, p->value_len, &len2);
910 if (len > 0)
912 fprintf (out, " value(%i):",
913 (len - 1) * 8 - (p->value[len2]));
914 for (k = 1; k < len; k++)
915 fprintf (out, "%02x", (p->value)[k + len2]);
918 break;
919 case TYPE_OCTET_STRING:
920 if (p->value)
922 len2 = -1;
923 len = asn1_get_length_der (p->value, p->value_len, &len2);
924 fprintf (out, " value:");
925 if (len > 0)
926 for (k = 0; k < len; k++)
927 fprintf (out, "%02x", (p->value)[k + len2]);
929 break;
930 case TYPE_GENERALSTRING:
931 if (p->value)
933 len2 = -1;
934 len = asn1_get_length_der (p->value, p->value_len, &len2);
935 fprintf (out, " value:");
936 if (len > 0)
937 for (k = 0; k < len; k++)
938 fprintf (out, "%02x", (p->value)[k + len2]);
940 break;
941 case TYPE_OBJECT_ID:
942 if (p->value)
943 fprintf (out, " value:%s", p->value);
944 break;
945 case TYPE_ANY:
946 if (p->value)
948 len3 = -1;
949 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
950 fprintf (out, " value:");
951 if (len2 > 0)
952 for (k = 0; k < len2; k++)
953 fprintf (out, "%02x", (p->value)[k + len3]);
955 break;
956 case TYPE_SET:
957 case TYPE_SET_OF:
958 case TYPE_CHOICE:
959 case TYPE_DEFINITIONS:
960 case TYPE_SEQUENCE_OF:
961 case TYPE_SEQUENCE:
962 case TYPE_NULL:
963 break;
964 default:
965 break;
969 if (mode == ASN1_PRINT_ALL)
971 if (p->type & 0x1FFFFF00)
973 fprintf (out, " attr:");
974 if (p->type & CONST_UNIVERSAL)
975 fprintf (out, "UNIVERSAL,");
976 if (p->type & CONST_PRIVATE)
977 fprintf (out, "PRIVATE,");
978 if (p->type & CONST_APPLICATION)
979 fprintf (out, "APPLICATION,");
980 if (p->type & CONST_EXPLICIT)
981 fprintf (out, "EXPLICIT,");
982 if (p->type & CONST_IMPLICIT)
983 fprintf (out, "IMPLICIT,");
984 if (p->type & CONST_TAG)
985 fprintf (out, "TAG,");
986 if (p->type & CONST_DEFAULT)
987 fprintf (out, "DEFAULT,");
988 if (p->type & CONST_TRUE)
989 fprintf (out, "TRUE,");
990 if (p->type & CONST_FALSE)
991 fprintf (out, "FALSE,");
992 if (p->type & CONST_LIST)
993 fprintf (out, "LIST,");
994 if (p->type & CONST_MIN_MAX)
995 fprintf (out, "MIN_MAX,");
996 if (p->type & CONST_OPTION)
997 fprintf (out, "OPTION,");
998 if (p->type & CONST_1_PARAM)
999 fprintf (out, "1_PARAM,");
1000 if (p->type & CONST_SIZE)
1001 fprintf (out, "SIZE,");
1002 if (p->type & CONST_DEFINED_BY)
1003 fprintf (out, "DEF_BY,");
1004 if (p->type & CONST_GENERALIZED)
1005 fprintf (out, "GENERALIZED,");
1006 if (p->type & CONST_UTC)
1007 fprintf (out, "UTC,");
1008 if (p->type & CONST_SET)
1009 fprintf (out, "SET,");
1010 if (p->type & CONST_NOT_USED)
1011 fprintf (out, "NOT_USED,");
1012 if (p->type & CONST_ASSIGN)
1013 fprintf (out, "ASSIGNMENT,");
1017 if (mode == ASN1_PRINT_ALL)
1019 fprintf (out, "\n");
1021 else
1023 switch (type_field (p->type))
1025 case TYPE_CONSTANT:
1026 case TYPE_TAG:
1027 case TYPE_SIZE:
1028 break;
1029 default:
1030 fprintf (out, "\n");
1034 if (p->down)
1036 p = p->down;
1037 indent += 2;
1039 else if (p == root)
1041 p = NULL;
1042 break;
1044 else if (p->right)
1045 p = p->right;
1046 else
1048 while (1)
1050 p = _asn1_find_up (p);
1051 if (p == root)
1053 p = NULL;
1054 break;
1056 indent -= 2;
1057 if (p->right)
1059 p = p->right;
1060 break;
1070 * asn1_number_of_elements - Counts the number of elements of a structure.
1071 * @element: pointer to the root of an ASN1 structure.
1072 * @name: the name of a sub-structure of ROOT.
1073 * @num: pointer to an integer where the result will be stored
1075 * Counts the number of elements of a sub-structure called NAME with
1076 * names equal to "?1","?2", ...
1078 * Returns:
1080 * ASN1_SUCCESS: Creation OK.
1082 * ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
1084 * ASN1_GENERIC_ERROR: Pointer num equal to NULL.
1087 asn1_retCode
1088 asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1090 ASN1_TYPE node, p;
1092 if (num == NULL)
1093 return ASN1_GENERIC_ERROR;
1095 *num = 0;
1097 node = asn1_find_node (element, name);
1098 if (node == NULL)
1099 return ASN1_ELEMENT_NOT_FOUND;
1101 p = node->down;
1103 while (p)
1105 if ((p->name) && (p->name[0] == '?'))
1106 (*num)++;
1107 p = p->right;
1110 return ASN1_SUCCESS;
1115 * asn1_find_structure_from_oid - Locate structure defined by a specific OID.
1116 * @definitions: ASN1 definitions
1117 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1119 * Search the structure that is defined just after an OID definition.
1121 * Returns: NULL when OIDVALUE not found, otherwise the pointer to a
1122 * constant string that contains the element name defined just
1123 * after the OID.
1126 const char *
1127 asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1129 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1];
1130 char value[ASN1_MAX_NAME_SIZE];
1131 ASN1_TYPE p;
1132 int len;
1133 asn1_retCode result;
1135 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1136 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1139 strcpy (definitionsName, definitions->name);
1140 strcat (definitionsName, ".");
1142 /* search the OBJECT_ID into definitions */
1143 p = definitions->down;
1144 while (p)
1146 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1147 (p->type & CONST_ASSIGN))
1149 strcpy (name, definitionsName);
1150 strcat (name, p->name);
1152 len = ASN1_MAX_NAME_SIZE;
1153 result = asn1_read_value (definitions, name, value, &len);
1155 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1157 p = p->right;
1158 if (p == NULL) /* reach the end of ASN1 definitions */
1159 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1161 return p->name;
1164 p = p->right;
1167 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1171 * asn1_copy_node:
1172 * @dst: Destination ASN1_TYPE node.
1173 * @dst_name: Field name in destination node.
1174 * @src: Source ASN1_TYPE node.
1175 * @src_name: Field name in source node.
1177 * Create a deep copy of a ASN1_TYPE variable.
1179 * Return value: Return ASN1_SUCCESS on success.
1181 asn1_retCode
1182 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1183 ASN1_TYPE src, const char *src_name)
1185 /* FIXME: rewrite using copy_structure().
1186 * It seems quite hard to do.
1188 int result;
1189 ASN1_TYPE dst_node;
1190 void *data = NULL;
1191 int size = 0;
1193 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1194 if (result != ASN1_MEM_ERROR)
1195 return result;
1197 data = _asn1_malloc (size);
1198 if (data == NULL)
1199 return ASN1_MEM_ERROR;
1201 result = asn1_der_coding (src, src_name, data, &size, NULL);
1202 if (result != ASN1_SUCCESS)
1204 _asn1_free (data);
1205 return result;
1208 dst_node = asn1_find_node (dst, dst_name);
1209 if (dst_node == NULL)
1211 _asn1_free (data);
1212 return ASN1_ELEMENT_NOT_FOUND;
1215 result = asn1_der_decoding (&dst_node, data, size, NULL);
1217 _asn1_free (data);
1219 return result;