corrected copyright notices
[gnutls.git] / lib / minitasn1 / parser_aux.c
blob50238d2c92f3b7b47cfa29088d2d061628287300
1 /*
2 * Copyright (C) 2000-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
22 #include <int.h>
23 #include <hash-pjw-bare.h>
24 #include "parser_aux.h"
25 #include "gstr.h"
26 #include "structure.h"
27 #include "element.h"
29 char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
31 /***********************************************/
32 /* Type: list_type */
33 /* Description: type used in the list during */
34 /* the structure creation. */
35 /***********************************************/
36 typedef struct list_struct
38 asn1_node node;
39 struct list_struct *next;
40 } list_type;
43 /* Pointer to the first element of the list */
44 list_type *firstElement = NULL;
46 /******************************************************/
47 /* Function : _asn1_add_static_node */
48 /* Description: creates a new NODE_ASN element and */
49 /* puts it in the list pointed by firstElement. */
50 /* Parameters: */
51 /* type: type of the new element (see ASN1_ETYPE_ */
52 /* and CONST_ constants). */
53 /* Return: pointer to the new element. */
54 /******************************************************/
55 asn1_node
56 _asn1_add_static_node (unsigned int type)
58 list_type *listElement;
59 asn1_node punt;
61 punt = calloc (1, sizeof (struct asn1_node_st));
62 if (punt == NULL)
63 return NULL;
65 listElement = malloc (sizeof (list_type));
66 if (listElement == NULL)
68 free (punt);
69 return NULL;
72 listElement->node = punt;
73 listElement->next = firstElement;
74 firstElement = listElement;
76 punt->type = type;
78 return punt;
81 /**
82 * asn1_find_node:
83 * @pointer: NODE_ASN element pointer.
84 * @name: null terminated string with the element's name to find.
86 * Searches for an element called @name starting from @pointer. The
87 * name is composed by differents identifiers separated by dots. When
88 * *@pointer has a name, the first identifier must be the name of
89 * *@pointer, otherwise it must be the name of one child of *@pointer.
91 * Returns: the search result, or %NULL if not found.
92 **/
93 asn1_node
94 asn1_find_node (asn1_node pointer, const char *name)
96 asn1_node p;
97 char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
98 const char *n_start;
99 unsigned int nsize;
100 unsigned int nhash;
102 if (pointer == NULL)
103 return NULL;
105 if (name == NULL)
106 return NULL;
108 p = pointer;
109 n_start = name;
111 if (p->name[0] != 0)
112 { /* has *pointer got a name ? */
113 n_end = strchr (n_start, '.'); /* search the first dot */
114 if (n_end)
116 nsize = n_end - n_start;
117 memcpy (n, n_start, nsize);
118 n[nsize] = 0;
119 n_start = n_end;
120 n_start++;
122 nhash = hash_pjw_bare(n, nsize);
124 else
126 nsize = _asn1_str_cpy (n, sizeof (n), n_start);
127 nhash = hash_pjw_bare(n, nsize);
129 n_start = NULL;
132 while (p)
134 if ((p->name) && nhash == p->name_hash && (!strcmp (p->name, n)))
135 break;
136 else
137 p = p->right;
138 } /* while */
140 if (p == NULL)
141 return NULL;
143 else
144 { /* *pointer doesn't have a name */
145 if (n_start[0] == 0)
146 return p;
149 while (n_start)
150 { /* Has the end of NAME been reached? */
151 n_end = strchr (n_start, '.'); /* search the next dot */
152 if (n_end)
154 nsize = n_end - n_start;
155 memcpy (n, n_start, nsize);
156 n[nsize] = 0;
157 n_start = n_end;
158 n_start++;
160 nhash = hash_pjw_bare(n, nsize);
162 else
164 nsize = _asn1_str_cpy (n, sizeof (n), n_start);
165 nhash = hash_pjw_bare(n, nsize);
166 n_start = NULL;
169 if (p->down == NULL)
170 return NULL;
172 p = p->down;
174 /* The identifier "?LAST" indicates the last element
175 in the right chain. */
176 if (!strcmp (n, "?LAST"))
178 if (p == NULL)
179 return NULL;
180 while (p->right)
181 p = p->right;
183 else
184 { /* no "?LAST" */
185 while (p)
187 if (p->name_hash == nhash && !strcmp (p->name, n))
188 break;
189 else
190 p = p->right;
192 if (p == NULL)
193 return NULL;
195 } /* while */
197 return p;
201 /******************************************************************/
202 /* Function : _asn1_set_value */
203 /* Description: sets the field VALUE in a NODE_ASN element. The */
204 /* previous value (if exist) will be lost */
205 /* Parameters: */
206 /* node: element pointer. */
207 /* value: pointer to the value that you want to set. */
208 /* len: character number of value. */
209 /* Return: pointer to the NODE_ASN element. */
210 /******************************************************************/
211 asn1_node
212 _asn1_set_value (asn1_node node, const void *value, unsigned int len)
214 if (node == NULL)
215 return node;
216 if (node->value)
218 if (node->value != node->small_value)
219 free (node->value);
220 node->value = NULL;
221 node->value_len = 0;
224 if (!len)
225 return node;
227 if (len < sizeof (node->small_value))
229 node->value = node->small_value;
231 else
233 node->value = malloc (len);
234 if (node->value == NULL)
235 return NULL;
237 node->value_len = len;
239 memcpy (node->value, value, len);
240 return node;
243 /******************************************************************/
244 /* Function : _asn1_set_value_lv */
245 /* Description: sets the field VALUE in a NODE_ASN element. The */
246 /* previous value (if exist) will be lost. The value */
247 /* given is stored as an length-value format (LV */
248 /* Parameters: */
249 /* node: element pointer. */
250 /* value: pointer to the value that you want to set. */
251 /* len: character number of value. */
252 /* Return: pointer to the NODE_ASN element. */
253 /******************************************************************/
254 asn1_node
255 _asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
257 int len2;
258 void *temp;
260 if (node == NULL)
261 return node;
263 asn1_length_der (len, NULL, &len2);
264 temp = malloc (len + len2);
265 if (temp == NULL)
266 return NULL;
268 asn1_octet_der (value, len, temp, &len2);
269 return _asn1_set_value_m (node, temp, len2);
272 /* the same as _asn1_set_value except that it sets an already malloc'ed
273 * value.
275 asn1_node
276 _asn1_set_value_m (asn1_node node, void *value, unsigned int len)
278 if (node == NULL)
279 return node;
281 if (node->value)
283 if (node->value != node->small_value)
284 free (node->value);
285 node->value = NULL;
286 node->value_len = 0;
289 if (!len)
290 return node;
292 node->value = value;
293 node->value_len = len;
295 return node;
298 /******************************************************************/
299 /* Function : _asn1_append_value */
300 /* Description: appends to the field VALUE in a NODE_ASN element. */
301 /* */
302 /* Parameters: */
303 /* node: element pointer. */
304 /* value: pointer to the value that you want to be appended. */
305 /* len: character number of value. */
306 /* Return: pointer to the NODE_ASN element. */
307 /******************************************************************/
308 asn1_node
309 _asn1_append_value (asn1_node node, const void *value, unsigned int len)
311 if (node == NULL)
312 return node;
313 if (node->value != NULL && node->value != node->small_value)
315 /* value is allocated */
316 int prev_len = node->value_len;
317 node->value_len += len;
318 node->value = realloc (node->value, node->value_len);
319 if (node->value == NULL)
321 node->value_len = 0;
322 return NULL;
324 memcpy (&node->value[prev_len], value, len);
326 return node;
328 else if (node->value == node->small_value)
330 /* value is in node */
331 int prev_len = node->value_len;
332 node->value_len += len;
333 node->value = malloc (node->value_len);
334 if (node->value == NULL)
336 node->value_len = 0;
337 return NULL;
339 memcpy (node->value, node->small_value, prev_len);
340 memcpy (&node->value[prev_len], value, len);
342 return node;
344 else /* node->value == NULL */
345 return _asn1_set_value (node, value, len);
348 /******************************************************************/
349 /* Function : _asn1_set_name */
350 /* Description: sets the field NAME in a NODE_ASN element. The */
351 /* previous value (if exist) will be lost */
352 /* Parameters: */
353 /* node: element pointer. */
354 /* name: a null terminated string with the name that you want */
355 /* to set. */
356 /* Return: pointer to the NODE_ASN element. */
357 /******************************************************************/
358 asn1_node
359 _asn1_set_name (asn1_node node, const char *name)
361 unsigned int nsize;
363 if (node == NULL)
364 return node;
366 if (name == NULL)
368 node->name[0] = 0;
369 node->name_hash = hash_pjw_bare(node->name, 0);
370 return node;
373 nsize = _asn1_str_cpy (node->name, sizeof (node->name), name);
374 node->name_hash = hash_pjw_bare(node->name, nsize);
376 return node;
379 /******************************************************************/
380 /* Function : _asn1_cpy_name */
381 /* Description: copies the field NAME in a NODE_ASN element. */
382 /* Parameters: */
383 /* dst: a dest element pointer. */
384 /* src: a source element pointer. */
385 /* Return: pointer to the NODE_ASN element. */
386 /******************************************************************/
387 asn1_node
388 _asn1_cpy_name (asn1_node dst, asn1_node src)
390 if (dst == NULL)
391 return dst;
393 if (src == NULL)
395 dst->name[0] = 0;
396 dst->name_hash = hash_pjw_bare(dst->name, 0);
397 return dst;
400 _asn1_str_cpy (dst->name, sizeof (dst->name), src->name);
401 dst->name_hash = src->name_hash;
403 return dst;
406 /******************************************************************/
407 /* Function : _asn1_set_right */
408 /* Description: sets the field RIGHT in a NODE_ASN element. */
409 /* Parameters: */
410 /* node: element pointer. */
411 /* right: pointer to a NODE_ASN element that you want be pointed*/
412 /* by NODE. */
413 /* Return: pointer to *NODE. */
414 /******************************************************************/
415 asn1_node
416 _asn1_set_right (asn1_node node, asn1_node right)
418 if (node == NULL)
419 return node;
420 node->right = right;
421 if (right)
422 right->left = node;
423 return node;
427 /******************************************************************/
428 /* Function : _asn1_get_last_right */
429 /* Description: return the last element along the right chain. */
430 /* Parameters: */
431 /* node: starting element pointer. */
432 /* Return: pointer to the last element along the right chain. */
433 /******************************************************************/
434 asn1_node
435 _asn1_get_last_right (asn1_node node)
437 asn1_node p;
439 if (node == NULL)
440 return NULL;
441 p = node;
442 while (p->right)
443 p = p->right;
444 return p;
447 /******************************************************************/
448 /* Function : _asn1_remove_node */
449 /* Description: gets free the memory allocated for an NODE_ASN */
450 /* element (not the elements pointed by it). */
451 /* Parameters: */
452 /* node: NODE_ASN element pointer. */
453 /******************************************************************/
454 void
455 _asn1_remove_node (asn1_node node)
457 if (node == NULL)
458 return;
460 if (node->value != NULL && node->value != node->small_value)
461 free (node->value);
462 free (node);
465 /******************************************************************/
466 /* Function : _asn1_find_up */
467 /* Description: return the father of the NODE_ASN element. */
468 /* Parameters: */
469 /* node: NODE_ASN element pointer. */
470 /* Return: Null if not found. */
471 /******************************************************************/
472 asn1_node
473 _asn1_find_up (asn1_node node)
475 asn1_node p;
477 if (node == NULL)
478 return NULL;
480 p = node;
482 while ((p->left != NULL) && (p->left->right == p))
483 p = p->left;
485 return p->left;
488 /******************************************************************/
489 /* Function : _asn1_delete_list */
490 /* Description: deletes the list elements (not the elements */
491 /* pointed by them). */
492 /******************************************************************/
493 void
494 _asn1_delete_list (void)
496 list_type *listElement;
498 while (firstElement)
500 listElement = firstElement;
501 firstElement = firstElement->next;
502 free (listElement);
506 /******************************************************************/
507 /* Function : _asn1_delete_list_and nodes */
508 /* Description: deletes the list elements and the elements */
509 /* pointed by them. */
510 /******************************************************************/
511 void
512 _asn1_delete_list_and_nodes (void)
514 list_type *listElement;
516 while (firstElement)
518 listElement = firstElement;
519 firstElement = firstElement->next;
520 _asn1_remove_node (listElement->node);
521 free (listElement);
526 char *
527 _asn1_ltostr (long v, char *str)
529 long d, r;
530 char temp[20];
531 int count, k, start;
533 if (v < 0)
535 str[0] = '-';
536 start = 1;
537 v = -v;
539 else
540 start = 0;
542 count = 0;
545 d = v / 10;
546 r = v - d * 10;
547 temp[start + count] = '0' + (char) r;
548 count++;
549 v = d;
551 while (v);
553 for (k = 0; k < count; k++)
554 str[k + start] = temp[start + count - k - 1];
555 str[count + start] = 0;
556 return str;
560 /******************************************************************/
561 /* Function : _asn1_change_integer_value */
562 /* Description: converts into DER coding the value assign to an */
563 /* INTEGER constant. */
564 /* Parameters: */
565 /* node: root of an ASN1element. */
566 /* Return: */
567 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
568 /* otherwise ASN1_SUCCESS */
569 /******************************************************************/
571 _asn1_change_integer_value (asn1_node node)
573 asn1_node p;
574 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
575 unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
576 int len;
578 if (node == NULL)
579 return ASN1_ELEMENT_NOT_FOUND;
581 p = node;
582 while (p)
584 if ((type_field (p->type) == ASN1_ETYPE_INTEGER) && (p->type & CONST_ASSIGN))
586 if (p->value)
588 _asn1_convert_integer (p->value, val, sizeof (val), &len);
589 asn1_octet_der (val, len, val2, &len);
590 _asn1_set_value (p, val2, len);
594 if (p->down)
596 p = p->down;
598 else
600 if (p == node)
601 p = NULL;
602 else if (p->right)
603 p = p->right;
604 else
606 while (1)
608 p = _asn1_find_up (p);
609 if (p == node)
611 p = NULL;
612 break;
614 if (p->right)
616 p = p->right;
617 break;
624 return ASN1_SUCCESS;
628 /******************************************************************/
629 /* Function : _asn1_expand_object_id */
630 /* Description: expand the IDs of an OBJECT IDENTIFIER constant. */
631 /* Parameters: */
632 /* node: root of an ASN1 element. */
633 /* Return: */
634 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
635 /* otherwise ASN1_SUCCESS */
636 /******************************************************************/
638 _asn1_expand_object_id (asn1_node node)
640 asn1_node p, p2, p3, p4, p5;
641 char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
642 int move, tlen;
644 if (node == NULL)
645 return ASN1_ELEMENT_NOT_FOUND;
647 _asn1_str_cpy (name_root, sizeof (name_root), node->name);
649 p = node;
650 move = DOWN;
652 while (!((p == node) && (move == UP)))
654 if (move != UP)
656 if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
657 && (p->type & CONST_ASSIGN))
659 p2 = p->down;
660 if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
662 if (p2->value && !isdigit (p2->value[0]))
664 _asn1_str_cpy (name2, sizeof (name2), name_root);
665 _asn1_str_cat (name2, sizeof (name2), ".");
666 _asn1_str_cat (name2, sizeof (name2),
667 (char *) p2->value);
668 p3 = asn1_find_node (node, name2);
669 if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
670 !(p3->type & CONST_ASSIGN))
671 return ASN1_ELEMENT_NOT_FOUND;
672 _asn1_set_down (p, p2->right);
673 _asn1_remove_node (p2);
674 p2 = p;
675 p4 = p3->down;
676 while (p4)
678 if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
680 p5 = _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
681 _asn1_set_name (p5, p4->name);
682 tlen = _asn1_strlen (p4->value);
683 if (tlen > 0)
684 _asn1_set_value (p5, p4->value, tlen + 1);
685 if (p2 == p)
687 _asn1_set_right (p5, p->down);
688 _asn1_set_down (p, p5);
690 else
692 _asn1_set_right (p5, p2->right);
693 _asn1_set_right (p2, p5);
695 p2 = p5;
697 p4 = p4->right;
699 move = DOWN;
700 continue;
704 move = DOWN;
706 else
707 move = RIGHT;
709 if (move == DOWN)
711 if (p->down)
712 p = p->down;
713 else
714 move = RIGHT;
717 if (p == node)
719 move = UP;
720 continue;
723 if (move == RIGHT)
725 if (p->right)
726 p = p->right;
727 else
728 move = UP;
730 if (move == UP)
731 p = _asn1_find_up (p);
735 /*******************************/
736 /* expand DEFAULT */
737 /*******************************/
738 p = node;
739 move = DOWN;
741 while (!((p == node) && (move == UP)))
743 if (move != UP)
745 if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
746 (p->type & CONST_DEFAULT))
748 p2 = p->down;
749 if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
751 _asn1_str_cpy (name2, sizeof (name2), name_root);
752 _asn1_str_cat (name2, sizeof (name2), ".");
753 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
754 p3 = asn1_find_node (node, name2);
755 if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
756 !(p3->type & CONST_ASSIGN))
757 return ASN1_ELEMENT_NOT_FOUND;
758 p4 = p3->down;
759 name2[0] = 0;
760 while (p4)
762 if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
764 if (name2[0])
765 _asn1_str_cat (name2, sizeof (name2), ".");
766 _asn1_str_cat (name2, sizeof (name2),
767 (char *) p4->value);
769 p4 = p4->right;
771 tlen = strlen (name2);
772 if (tlen > 0)
773 _asn1_set_value (p2, name2, tlen + 1);
776 move = DOWN;
778 else
779 move = RIGHT;
781 if (move == DOWN)
783 if (p->down)
784 p = p->down;
785 else
786 move = RIGHT;
789 if (p == node)
791 move = UP;
792 continue;
795 if (move == RIGHT)
797 if (p->right)
798 p = p->right;
799 else
800 move = UP;
802 if (move == UP)
803 p = _asn1_find_up (p);
806 return ASN1_SUCCESS;
810 /******************************************************************/
811 /* Function : _asn1_type_set_config */
812 /* Description: sets the CONST_SET and CONST_NOT_USED properties */
813 /* in the fields of the SET elements. */
814 /* Parameters: */
815 /* node: root of an ASN1 element. */
816 /* Return: */
817 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
818 /* otherwise ASN1_SUCCESS */
819 /******************************************************************/
821 _asn1_type_set_config (asn1_node node)
823 asn1_node p, p2;
824 int move;
826 if (node == NULL)
827 return ASN1_ELEMENT_NOT_FOUND;
829 p = node;
830 move = DOWN;
832 while (!((p == node) && (move == UP)))
834 if (move != UP)
836 if (type_field (p->type) == ASN1_ETYPE_SET)
838 p2 = p->down;
839 while (p2)
841 if (type_field (p2->type) != ASN1_ETYPE_TAG)
842 p2->type |= CONST_SET | CONST_NOT_USED;
843 p2 = p2->right;
846 move = DOWN;
848 else
849 move = RIGHT;
851 if (move == DOWN)
853 if (p->down)
854 p = p->down;
855 else
856 move = RIGHT;
859 if (p == node)
861 move = UP;
862 continue;
865 if (move == RIGHT)
867 if (p->right)
868 p = p->right;
869 else
870 move = UP;
872 if (move == UP)
873 p = _asn1_find_up (p);
876 return ASN1_SUCCESS;
880 /******************************************************************/
881 /* Function : _asn1_check_identifier */
882 /* Description: checks the definitions of all the identifiers */
883 /* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */
884 /* The _asn1_identifierMissing global variable is filled if */
885 /* necessary. */
886 /* Parameters: */
887 /* node: root of an ASN1 element. */
888 /* Return: */
889 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
890 /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
891 /* otherwise ASN1_SUCCESS */
892 /******************************************************************/
894 _asn1_check_identifier (asn1_node node)
896 asn1_node p, p2;
897 char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
899 if (node == NULL)
900 return ASN1_ELEMENT_NOT_FOUND;
902 p = node;
903 while (p)
905 if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
907 _asn1_str_cpy (name2, sizeof (name2), node->name);
908 _asn1_str_cat (name2, sizeof (name2), ".");
909 _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
910 p2 = asn1_find_node (node, name2);
911 if (p2 == NULL)
913 if (p->value)
914 _asn1_strcpy (_asn1_identifierMissing, p->value);
915 else
916 _asn1_strcpy (_asn1_identifierMissing, "(null)");
917 return ASN1_IDENTIFIER_NOT_FOUND;
920 else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
921 (p->type & CONST_DEFAULT))
923 p2 = p->down;
924 if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
926 _asn1_str_cpy (name2, sizeof (name2), node->name);
927 _asn1_str_cat (name2, sizeof (name2), ".");
928 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
929 _asn1_strcpy (_asn1_identifierMissing, p2->value);
930 p2 = asn1_find_node (node, name2);
931 if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
932 !(p2->type & CONST_ASSIGN))
933 return ASN1_IDENTIFIER_NOT_FOUND;
934 else
935 _asn1_identifierMissing[0] = 0;
938 else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
939 (p->type & CONST_ASSIGN))
941 p2 = p->down;
942 if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
944 if (p2->value && !isdigit (p2->value[0]))
946 _asn1_str_cpy (name2, sizeof (name2), node->name);
947 _asn1_str_cat (name2, sizeof (name2), ".");
948 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
949 _asn1_strcpy (_asn1_identifierMissing, p2->value);
950 p2 = asn1_find_node (node, name2);
951 if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
952 !(p2->type & CONST_ASSIGN))
953 return ASN1_IDENTIFIER_NOT_FOUND;
954 else
955 _asn1_identifierMissing[0] = 0;
960 if (p->down)
962 p = p->down;
964 else if (p->right)
965 p = p->right;
966 else
968 while (1)
970 p = _asn1_find_up (p);
971 if (p == node)
973 p = NULL;
974 break;
976 if (p->right)
978 p = p->right;
979 break;
985 return ASN1_SUCCESS;
989 /******************************************************************/
990 /* Function : _asn1_set_default_tag */
991 /* Description: sets the default IMPLICIT or EXPLICIT property in */
992 /* the tagged elements that don't have this declaration. */
993 /* Parameters: */
994 /* node: pointer to a DEFINITIONS element. */
995 /* Return: */
996 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */
997 /* a DEFINITIONS element, */
998 /* otherwise ASN1_SUCCESS */
999 /******************************************************************/
1001 _asn1_set_default_tag (asn1_node node)
1003 asn1_node p;
1005 if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
1006 return ASN1_ELEMENT_NOT_FOUND;
1008 p = node;
1009 while (p)
1011 if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
1012 !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1014 if (node->type & CONST_EXPLICIT)
1015 p->type |= CONST_EXPLICIT;
1016 else
1017 p->type |= CONST_IMPLICIT;
1020 if (p->down)
1022 p = p->down;
1024 else if (p->right)
1025 p = p->right;
1026 else
1028 while (1)
1030 p = _asn1_find_up (p);
1031 if (p == node)
1033 p = NULL;
1034 break;
1036 if (p->right)
1038 p = p->right;
1039 break;
1045 return ASN1_SUCCESS;